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.
このコミットが含まれているのは:
Cory Slep 2018-12-19 09:44:57 +01:00
コミット b5d927c49f
5個のファイルの変更80行の追加52行の削除

ファイルの表示

@ -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,