Properties now have serialization references to Types.
This setup allows properties to recur deserializing into types as necessary, and sets the groundwork for successfully handling all kinds of JSON-LD input.
このコミットが含まれているのは:
コミット
b5d927c49f
|
@ -262,7 +262,12 @@ func (c Converter) convertType(t rdf.VocabularyType,
|
|||
if e != nil {
|
||||
return
|
||||
}
|
||||
// Apply disjoint if both sides are available.
|
||||
// Apply disjoint if both sides are available because the TypeGenerator
|
||||
// does not know the entire vocabulary, so cannot do this lookup and
|
||||
// create this connection for us.
|
||||
//
|
||||
// TODO: Pass in the disjoint and have the TypeGenerator complete the
|
||||
// doubly-linked connection for us.
|
||||
for _, disj := range t.DisjointWith {
|
||||
if len(disj.Vocab) != 0 {
|
||||
// TODO: This should be fixed to handle references
|
||||
|
@ -273,6 +278,33 @@ func (c Converter) convertType(t rdf.VocabularyType,
|
|||
tg.AddDisjoint(disjointType)
|
||||
}
|
||||
}
|
||||
// Apply the type's KindSerializationFuncs to the property because there
|
||||
// is no way for the TypeGenerator to know all properties who have a
|
||||
// range of this type.
|
||||
//
|
||||
// TODO: Pass in these properties to the TypeGenerator constructor so it
|
||||
// can build these double-links properly. Note this would also need to
|
||||
// apply to referenced properties, possibly.
|
||||
for _, prop := range existingFProps {
|
||||
for _, kind := range prop.Kinds {
|
||||
if kind.Name.LowerName == tg.TypeName() {
|
||||
ser, deser, less := tg.KindSerializationFuncs()
|
||||
if e = prop.SetKindFns(tg.TypeName(), ser, deser, less); e != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, prop := range existingNFProps {
|
||||
for _, kind := range prop.Kinds {
|
||||
if kind.Name.LowerName == tg.TypeName() {
|
||||
ser, deser, less := tg.KindSerializationFuncs()
|
||||
if e = prop.SetKindFns(tg.TypeName(), ser, deser, less); e != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
}
|
||||
methods := []*codegen.Method{
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
kindIndexMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -129,7 +129,7 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// IsLanguageMap Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
isLanguageMapMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -154,7 +154,7 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// HasLanguage Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
hasLanguageMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("bcp47").String()},
|
||||
|
@ -182,7 +182,7 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// GetLanguage Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
getLanguageMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("bcp47").String()},
|
||||
|
@ -214,7 +214,7 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// SetLanguage Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
setLanguageMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{
|
||||
|
@ -273,7 +273,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*codegen.Method, [
|
|||
}
|
||||
serialize := []*codegen.Method{
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.serializeFnName(),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -319,7 +319,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*codegen.Method, [
|
|||
if p.asIterator {
|
||||
deserialize = append(deserialize,
|
||||
codegen.NewCommentedFunction(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.DeserializeFnName(),
|
||||
[]jen.Code{jen.Id("i").Interface()},
|
||||
[]jen.Code{jen.Op("*").Id(p.StructName()), jen.Error()},
|
||||
|
@ -335,7 +335,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*codegen.Method, [
|
|||
} else {
|
||||
deserialize = append(deserialize,
|
||||
codegen.NewCommentedFunction(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.DeserializeFnName(),
|
||||
[]jen.Code{jen.Id("m").Map(jen.String()).Interface()},
|
||||
[]jen.Code{jen.Op("*").Id(p.StructName()), jen.Error()},
|
||||
|
@ -421,7 +421,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
}
|
||||
if p.Kinds[0].Nilable {
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
hasMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -431,7 +431,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
))
|
||||
} else {
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
hasMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -443,7 +443,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
// Get Method
|
||||
getComment := jen.Commentf("%s returns the value of this property. When %s returns false, %s will return any arbitrary value.", getMethod, hasMethod, getMethod)
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.getFnName(0),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -465,7 +465,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
}
|
||||
if p.Kinds[0].Nilable {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.setFnName(0),
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(p.Kinds[0].ConcreteKind)},
|
||||
|
@ -478,7 +478,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
))
|
||||
} else {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.setFnName(0),
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(p.Kinds[0].ConcreteKind)},
|
||||
|
@ -507,7 +507,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
}
|
||||
if p.Kinds[0].Nilable {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.clearMethodName(),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -517,7 +517,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method {
|
|||
))
|
||||
} else {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.clearMethodName(),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -602,7 +602,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
)
|
||||
}
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
hasAnyMethodName,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -626,7 +626,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
clearLine = append(clearLine, jen.Id(codegen.This()).Dot(langMapMember).Op("=").Nil())
|
||||
}
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.clearMethodName(),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -649,7 +649,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
}
|
||||
if kind.Nilable {
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.isMethodName(i),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -659,7 +659,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
))
|
||||
} else {
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.isMethodName(i),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -684,7 +684,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
}
|
||||
if kind.Nilable {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.setFnName(i),
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(kind.ConcreteKind)},
|
||||
|
@ -697,7 +697,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
))
|
||||
} else {
|
||||
methods = append(methods, codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.setFnName(i),
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(kind.ConcreteKind)},
|
||||
|
@ -715,7 +715,7 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method {
|
|||
for i, kind := range p.Kinds {
|
||||
getComment := jen.Commentf("%s returns the value of this property. When %s returns false, %s will return an arbitrary value.", p.getFnName(i), p.isMethodName(i), p.getFnName(i))
|
||||
methods = append(methods, codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.getFnName(i),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
|
|
@ -90,7 +90,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
prependMethodName := fmt.Sprintf("%s%s", prependMethod, p.kindCamelName(i))
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
prependMethodName,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(kind.ConcreteKind)},
|
||||
|
@ -108,7 +108,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
appendMethodName := fmt.Sprintf("%s%s", appendMethod, p.kindCamelName(i))
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
appendMethodName,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("v").Id(kind.ConcreteKind)},
|
||||
|
@ -140,7 +140,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// Remove Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedPointerMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
removeMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("idx").Int()},
|
||||
|
@ -176,7 +176,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// Len Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
lenMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -192,7 +192,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// Swap Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
swapMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{
|
||||
|
@ -213,7 +213,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// Less Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
lessMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{
|
||||
|
@ -235,7 +235,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
// Kind Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
kindIndexMethod,
|
||||
p.StructName(),
|
||||
[]jen.Code{jen.Id("idx").Int()},
|
||||
|
@ -255,7 +255,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
func (p *NonFunctionalPropertyGenerator) serializationFuncs() ([]*codegen.Method, []*codegen.Function) {
|
||||
serialize := []*codegen.Method{
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.serializeFnName(),
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
@ -323,7 +323,7 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() ([]*codegen.Method
|
|||
}
|
||||
deserialize := []*codegen.Function{
|
||||
codegen.NewCommentedFunction(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
p.DeserializeFnName(),
|
||||
[]jen.Code{jen.Id("m").Map(jen.String()).Interface()},
|
||||
[]jen.Code{jen.Id(p.StructName()), jen.Error()},
|
||||
|
|
|
@ -84,8 +84,8 @@ type PropertyGenerator struct {
|
|||
asIterator bool
|
||||
}
|
||||
|
||||
// packageName returns the name of the package for the property to be generated.
|
||||
func (p *PropertyGenerator) packageName() string {
|
||||
// PackageName returns the name of the package for the property to be generated.
|
||||
func (p *PropertyGenerator) PackageName() string {
|
||||
return p.Package
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ func (p *PropertyGenerator) packageName() string {
|
|||
//
|
||||
// This feels very hacky.
|
||||
func (p *PropertyGenerator) SetKindFns(name string, ser, deser, less *codegen.Function) error {
|
||||
for _, kind := range p.Kinds {
|
||||
for i, kind := range p.Kinds {
|
||||
if kind.Name.LowerName == name {
|
||||
if kind.SerializeFn != nil || kind.DeserializeFn != nil || kind.LessFn != nil {
|
||||
return fmt.Errorf("property kind already has serialization functions set for %q", name)
|
||||
|
@ -104,6 +104,7 @@ func (p *PropertyGenerator) SetKindFns(name string, ser, deser, less *codegen.Fu
|
|||
kind.SerializeFn = ser
|
||||
kind.DeserializeFn = deser
|
||||
kind.LessFn = less
|
||||
p.Kinds[i] = kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +201,7 @@ func (p *PropertyGenerator) clearMethodName() string {
|
|||
func (p *PropertyGenerator) commonMethods() []*codegen.Method {
|
||||
return []*codegen.Method{
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.packageName(),
|
||||
p.PackageName(),
|
||||
nameMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
|
|
|
@ -37,6 +37,7 @@ func TypeInterface(pkg string) *codegen.Interface {
|
|||
|
||||
// Property represents a property of an ActivityStreams type.
|
||||
type Property interface {
|
||||
PackageName() string
|
||||
PropertyName() string
|
||||
StructName() string
|
||||
SetKindFns(name string, ser, deser, less *codegen.Function) error
|
||||
|
@ -65,6 +66,9 @@ type TypeGenerator struct {
|
|||
//
|
||||
// All TypeGenerators must be created before the Definition method is called, to
|
||||
// ensure that type extension, in the inheritence sense, is properly set up.
|
||||
// Additionally, all properties whose range is this type should have their
|
||||
// SetKindFns method called with this TypeGenerator's KindSerializationFuncs for
|
||||
// all code generation to correctly reference each other.
|
||||
func NewTypeGenerator(packageName, typeName, comment string,
|
||||
properties, withoutProperties []Property,
|
||||
extends, disjoint []*TypeGenerator) (*TypeGenerator, error) {
|
||||
|
@ -93,14 +97,6 @@ func NewTypeGenerator(packageName, typeName, comment string,
|
|||
for _, ext := range extends {
|
||||
ext.extendedBy = append(ext.extendedBy, t)
|
||||
}
|
||||
// TODO: Fix: Only notify properties whose Range is this type, not the
|
||||
// properties this type has (which is wrong and currently borken)
|
||||
for _, property := range t.properties {
|
||||
ser, deser, less := t.kindSerializationFuncs()
|
||||
if err := property.SetKindFns(t.TypeName(), ser, deser, less); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
@ -172,7 +168,7 @@ func (t *TypeGenerator) Definition() *codegen.Struct {
|
|||
t.cacheOnce.Do(func() {
|
||||
members := t.members()
|
||||
m := t.serializationMethod()
|
||||
ser, deser, less := t.kindSerializationFuncs()
|
||||
ser, deser, less := t.KindSerializationFuncs()
|
||||
t.cachedStruct = codegen.NewStruct(
|
||||
jen.Commentf(t.Comment()),
|
||||
t.TypeName(),
|
||||
|
@ -387,9 +383,9 @@ func (t *TypeGenerator) serializationMethod() (ser *codegen.Method) {
|
|||
return
|
||||
}
|
||||
|
||||
// kindSerializationFuncs returns free function references that can be used to
|
||||
// KindSerializationFuncs returns free function references that can be used to
|
||||
// treat a TypeGenerator as another property's Kind.
|
||||
func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Function) {
|
||||
func (t *TypeGenerator) KindSerializationFuncs() (ser, deser, less *codegen.Function) {
|
||||
serName := fmt.Sprintf("%s%s", serializeMethodName, t.TypeName())
|
||||
ser = codegen.NewCommentedFunction(
|
||||
t.packageName,
|
||||
|
@ -404,20 +400,19 @@ func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Func
|
|||
jen.Commentf("%s calls %s on the %s type.", serName, serializeMethodName, t.TypeName()))
|
||||
deserName := fmt.Sprintf("%s%s", deserializeFnName, t.TypeName())
|
||||
deserCode := jen.Empty()
|
||||
for name := range t.allProperties() {
|
||||
for name, prop := range t.allProperties() {
|
||||
deserCode = deserCode.Add(
|
||||
jen.If(
|
||||
jen.List(
|
||||
jen.Id("p"),
|
||||
jen.Err(),
|
||||
// TODO: Qual
|
||||
).Op(":=").Qual("", deserializeFnName).Call(jen.Id("m")),
|
||||
).Op(":=").Qual(prop.PackageName(), deserializeMethod).Call(jen.Id("m")),
|
||||
jen.Err().Op("!=").Nil(),
|
||||
).Block(
|
||||
jen.Return(jen.Nil(), jen.Err()),
|
||||
).Else().Block(
|
||||
jen.Id(codegen.This()).Dot(strings.Title(name)).Op(":=").Op("*").Id("p"),
|
||||
))
|
||||
jen.Id(codegen.This()).Dot(strings.Title(name)).Op("=").Op("*").Id("p"),
|
||||
).Line())
|
||||
}
|
||||
deser = codegen.NewCommentedFunction(
|
||||
t.packageName,
|
||||
|
|
読み込み中…
新しいイシューから参照