diff --git a/tools/exp/codegen/method.go b/tools/exp/codegen/method.go index 4f6df1b..1bdc20a 100644 --- a/tools/exp/codegen/method.go +++ b/tools/exp/codegen/method.go @@ -199,7 +199,7 @@ func (m Method) Definition() jen.Code { // Call generates the Go code required to call this method, with qualifier if // required. func (m Method) Call(on string, params ...jen.Code) jen.Code { - return jen.Id(on).Call(params...) + return jen.Id(on).Dot(m.function.name).Call(params...) } // Name returns the identifier of this function. diff --git a/tools/exp/convert/convert.go b/tools/exp/convert/convert.go index 67d59e5..82929b9 100644 --- a/tools/exp/convert/convert.go +++ b/tools/exp/convert/convert.go @@ -259,7 +259,6 @@ func (c Converter) convertType(t rdf.VocabularyType, if e != nil { return } - pkg := pm.PrivatePackage() // Determine the properties for this type var p []props.Property for _, prop := range t.Properties { @@ -345,7 +344,7 @@ func (c Converter) convertType(t rdf.VocabularyType, } } tg, e = props.NewTypeGenerator( - pkg, + pm, name, t.Notes, p, @@ -405,10 +404,11 @@ func (c Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty, func (c Converter) convertValue(v rdf.VocabularyValue) (k *props.Kind) { k = &props.Kind{ - Name: c.toIdentifier(v), - ConcreteKind: v.DefinitionType, + Name: c.toIdentifier(v), + // TODO: Add Qualifier + ConcreteKind: jen.Id(v.DefinitionType), Nilable: c.isNilable(v.DefinitionType), - // TODO + // TODO: Fix Qualifying calls? SerializeFn: jen.Empty().Add(v.SerializeFn.Call()), DeserializeFn: jen.Empty().Add(v.DeserializeFn.Call()), LessFn: jen.Empty().Add(v.LessFn.Call()), @@ -418,10 +418,10 @@ func (c Converter) convertValue(v rdf.VocabularyValue) (k *props.Kind) { func (c Converter) convertTypeToKind(v rdf.VocabularyType) (k *props.Kind, e error) { k = &props.Kind{ - Name: c.toIdentifier(v), - ConcreteKind: c.convertTypeToConcreteKind(v), - Nilable: true, + Name: c.toIdentifier(v), + Nilable: true, // Instead of populating: + // - ConcreteKind // - SerializeFn // - DeserializeFn // - LessFn @@ -437,10 +437,6 @@ func (c Converter) convertTypeToName(v rdf.VocabularyType) string { return strings.Title(v.Name) } -func (c Converter) convertTypeToConcreteKind(v rdf.VocabularyType) string { - return "*" + c.convertTypeToName(v) -} - func (c Converter) propertyKinds(v rdf.VocabularyProperty, kinds map[string]*props.Kind, vocab rdf.Vocabulary, diff --git a/tools/exp/props/funcprop.go b/tools/exp/props/funcprop.go index 12e02d0..1a3f4a6 100644 --- a/tools/exp/props/funcprop.go +++ b/tools/exp/props/funcprop.go @@ -284,7 +284,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co } serializeFns = serializeFns.Block( jen.Return( - kind.SerializeFn.Call( + kind.SerializeFn.Clone().Call( jen.Id(codegen.This()).Dot(p.getFnName(i)).Call(), ), ), @@ -317,7 +317,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co jen.Id("v"), jen.Id("handled"), jen.Err(), - ).Op(":=").Add(kind.DeserializeFn.Call( + ).Op(":=").Add(kind.DeserializeFn.Clone().Call( jen.Id("i"), )), jen.Id("handled"), @@ -385,7 +385,7 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *codegen.Struct { comment = jen.Commentf("%s is an iterator for a property. It is permitted to be a single nilable value type.", p.StructName()) } kindMembers = []jen.Code{ - jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind), + jen.Id(p.memberName(0)).Add(p.Kinds[0].ConcreteKind), } } else { comment = jen.Commentf("%s is the functional property %q. It is permitted to be a single default-valued value type.", p.StructName(), p.PropertyName()) @@ -393,7 +393,7 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *codegen.Struct { comment = jen.Commentf("%s is an iterator for a property. It is permitted to be a single default-valued value type.", p.StructName()) } kindMembers = []jen.Code{ - jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind), + jen.Id(p.memberName(0)).Add(p.Kinds[0].ConcreteKind), jen.Id(p.hasMemberName(0)).Bool(), } } @@ -463,7 +463,8 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method { p.getFnName(0), p.StructName(), /*params=*/ nil, - []jen.Code{jen.Id(p.Kinds[0].ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{p.Kinds[0].ConcreteKind}, []jen.Code{jen.Return(jen.Id(codegen.This()).Dot(p.memberName(0)))}, getComment, )) @@ -484,7 +485,8 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method { p.Package.Path(), p.setFnName(0), p.StructName(), - []jen.Code{jen.Id("v").Id(p.Kinds[0].ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Id("v").Add(p.Kinds[0].ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Id(codegen.This()).Dot(p.clearMethodName()).Call(), @@ -497,7 +499,7 @@ func (p *FunctionalPropertyGenerator) singleTypeFuncs() []*codegen.Method { p.Package.Path(), p.setFnName(0), p.StructName(), - []jen.Code{jen.Id("v").Id(p.Kinds[0].ConcreteKind)}, + []jen.Code{jen.Id("v").Add(p.Kinds[0].ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Id(codegen.This()).Dot(p.clearMethodName()).Call(), @@ -551,9 +553,9 @@ func (p *FunctionalPropertyGenerator) multiTypeDef() *codegen.Struct { kindMembers := make([]jen.Code, 0, len(p.Kinds)) for i, kind := range p.Kinds { if kind.Nilable { - kindMembers = append(kindMembers, jen.Id(p.memberName(i)).Id(p.Kinds[i].ConcreteKind)) + kindMembers = append(kindMembers, jen.Id(p.memberName(i)).Add(p.Kinds[i].ConcreteKind)) } else { - kindMembers = append(kindMembers, jen.Id(p.memberName(i)).Id(p.Kinds[i].ConcreteKind)) + kindMembers = append(kindMembers, jen.Id(p.memberName(i)).Add(p.Kinds[i].ConcreteKind)) kindMembers = append(kindMembers, jen.Id(p.hasMemberName(i)).Bool()) } } @@ -707,7 +709,8 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method { p.Package.Path(), p.setFnName(i), p.StructName(), - []jen.Code{jen.Id("v").Id(kind.ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Id("v").Add(kind.ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Id(codegen.This()).Dot(p.clearMethodName()).Call(), @@ -720,7 +723,8 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method { p.Package.Path(), p.setFnName(i), p.StructName(), - []jen.Code{jen.Id("v").Id(kind.ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Id("v").Add(kind.ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Id(codegen.This()).Dot(p.clearMethodName()).Call(), @@ -739,7 +743,8 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*codegen.Method { p.getFnName(i), p.StructName(), /*params=*/ nil, - []jen.Code{jen.Id(kind.ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Add(kind.ConcreteKind)}, []jen.Code{jen.Return(jen.Id(codegen.This()).Dot(p.memberName(i)))}, getComment, )) diff --git a/tools/exp/props/manager.go b/tools/exp/props/manager.go index 0346345..4111b13 100644 --- a/tools/exp/props/manager.go +++ b/tools/exp/props/manager.go @@ -116,7 +116,7 @@ func NewManagerGenerator(pm PackageManager, // Pass 3: Populate interfaces of the types and properties, which relies // on the first pass's data population. for _, t := range tg { - publicPkg := t.Package().Parent().PublicPackage() + publicPkg := t.PublicPackage() mg.tgManagedMethods[t].ifaces = []*codegen.Interface{t.toInterface(publicPkg)} } // TODO: Move these back to pass 1 @@ -187,14 +187,12 @@ func (m *ManagerGenerator) PrivateManager() *codegen.Struct { for _, nfp := range m.nfpManagedMethods { methods = append(methods, nfp.deserializor) } - var functions []*codegen.Function - var members []jen.Code s := codegen.NewStruct( jen.Commentf(fmt.Sprintf("%s privately manages concrete types and deserializations for internal use by generated code. Application code should use the public version instead, which uses interfaces to abstract away the generated code and allow apps to not entirely rely on go-fed should they choose not to.", managerName)), managerName, methods, - functions, - members) + /*functions=*/ nil, + /*members=*/ nil) return s } @@ -205,7 +203,7 @@ func (m *ManagerGenerator) PrivateManager() *codegen.Struct { func (m *ManagerGenerator) createPrivateDeserializationMethodForType(tg *TypeGenerator) *codegen.Method { dn := tg.deserializationFnName() pkg := m.pm.PrivatePackage() - name := fmt.Sprintf("%s%s%s", dn, tg.Package().Name(), strings.Title(pkg.Name())) + name := fmt.Sprintf("%s%s%s", dn, tg.PrivatePackage().Name(), strings.Title(pkg.Name())) return codegen.NewCommentedValueMethod( pkg.Path(), name, @@ -222,10 +220,10 @@ func (m *ManagerGenerator) createPrivateDeserializationMethodForType(tg *TypeGen }, []jen.Code{ jen.Return( - jen.Qual(tg.Package().Path(), dn), + jen.Qual(tg.PrivatePackage().Path(), dn), ), }, - jen.Commentf("%s returns the deserialization method for the %q type in package %q", name, tg.TypeName(), tg.Package().Name())) + jen.Commentf("%s returns the deserialization method for the %q type in package %q", name, tg.TypeName(), tg.PrivatePackage().Name())) } // createPrivateDeserializationMethodForFuncProperty creates a new method for the diff --git a/tools/exp/props/nonfuncprop.go b/tools/exp/props/nonfuncprop.go index 465ffe9..ed89519 100644 --- a/tools/exp/props/nonfuncprop.go +++ b/tools/exp/props/nonfuncprop.go @@ -121,7 +121,8 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method { p.Package.Path(), prependMethodName, p.StructName(), - []jen.Code{jen.Id("v").Id(kind.ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Id("v").Add(kind.ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Op("*").Id(codegen.This()).Op("=").Append( @@ -139,7 +140,8 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method { p.Package.Path(), appendMethodName, p.StructName(), - []jen.Code{jen.Id("v").Id(kind.ConcreteKind)}, + // TODO: Interface Kind + []jen.Code{jen.Id("v").Add(kind.ConcreteKind)}, /*ret=*/ nil, []jen.Code{ jen.Op("*").Id(codegen.This()).Op("=").Append( @@ -159,7 +161,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method { ).Block( jen.Id("lhs").Op(":=").Id(codegen.This()).Index(jen.Id("i")).Dot(p.getFnName(i)).Call(), jen.Id("rhs").Op(":=").Id(codegen.This()).Index(jen.Id("j")).Dot(p.getFnName(i)).Call(), - jen.Return(kind.LessFn.Call( + jen.Return(kind.LessFn.Clone().Call( jen.Id("lhs"), jen.Id("rhs"), )), diff --git a/tools/exp/props/property.go b/tools/exp/props/property.go index c07fd8c..d3e41e1 100644 --- a/tools/exp/props/property.go +++ b/tools/exp/props/property.go @@ -58,11 +58,14 @@ type Identifier struct { // Kind is data that describes a concrete Go type, how to serialize and // deserialize such types, compare the types, and other meta-information to use // during Go code generation. +// +// Only represents values and other types. type Kind struct { - Name Identifier - ConcreteKind string + Name Identifier + // ConcreteKind is expected to be a jen.Qual + ConcreteKind *jen.Statement Nilable bool - // Expected to be a jen.Qual + // These functions are expected to be a jen.Qual SerializeFn *jen.Statement DeserializeFn *jen.Statement LessFn *jen.Statement @@ -97,12 +100,13 @@ func (p *PropertyGenerator) GetPackage() Package { // The name parameter must match the LowerName of an Identifier. // // This feels very hacky. -func (p *PropertyGenerator) SetKindFns(name string, ser, deser, less *jen.Statement) error { +func (p *PropertyGenerator) SetKindFns(name string, qualKind, ser, deser, less *jen.Statement) error { 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) } + kind.ConcreteKind = qualKind kind.SerializeFn = ser kind.DeserializeFn = deser kind.LessFn = less diff --git a/tools/exp/props/type.go b/tools/exp/props/type.go index c1dedfb..af252be 100644 --- a/tools/exp/props/type.go +++ b/tools/exp/props/type.go @@ -45,13 +45,13 @@ type Property interface { GetPackage() Package PropertyName() string StructName() string - SetKindFns(name string, ser, deser, less *jen.Statement) error + SetKindFns(name string, kind, ser, deser, less *jen.Statement) error DeserializeFnName() string } // TypeGenerator represents an ActivityStream type definition to generate in Go. type TypeGenerator struct { - pkg Package + pm *PackageManager typeName string comment string properties map[string]Property @@ -85,11 +85,11 @@ type TypeGenerator struct { // // A ManagerGenerator must be created with this type before Definition is // called, to ensure that the serialization functions are properly set up. -func NewTypeGenerator(pkg Package, typeName, comment string, +func NewTypeGenerator(pm *PackageManager, typeName, comment string, properties, withoutProperties, rangeProperties []Property, extends, disjoint []*TypeGenerator) (*TypeGenerator, error) { t := &TypeGenerator{ - pkg: pkg, + pm: pm, typeName: typeName, comment: comment, properties: make(map[string]Property, len(properties)), @@ -128,20 +128,27 @@ func NewTypeGenerator(pkg Package, typeName, comment string, func (t *TypeGenerator) apply(m *ManagerGenerator) error { t.m = m // Set up Kind functions - ser := jen.Qual(t.Package().Path(), t.serializationFnName()) + // TODO: Call serialize on an object instead of using a function. + ser := jen.Qual(t.PrivatePackage().Path(), t.serializationFnName()) deser := jen.Qual(m.privatePackage().Path(), m.getPrivateDeserializationMethodForType(t).Name()) - less := jen.Qual(t.Package().Path(), t.lessFnName()) + less := jen.Qual(t.PrivatePackage().Path(), t.lessFnName()) + kind := jen.Qual(t.PublicPackage().Path(), t.InterfaceName()) for _, p := range t.rangeProperties { - if e := p.SetKindFns(t.TypeName(), ser, deser, less); e != nil { + if e := p.SetKindFns(t.TypeName(), kind, ser, deser, less); e != nil { return e } } return nil } -// Package gets this TypeGenerator's Package. -func (t *TypeGenerator) Package() Package { - return t.pkg +// Package gets this TypeGenerator's Private Package. +func (t *TypeGenerator) PrivatePackage() Package { + return t.pm.PrivatePackage() +} + +// Package gets this TypeGenerator's Public Package. +func (t *TypeGenerator) PublicPackage() Package { + return t.pm.PublicPackage() } // Comment returns the comment for this type. @@ -324,7 +331,7 @@ func (t *TypeGenerator) members() (members []jen.Code) { // type name. func (t *TypeGenerator) nameDefinition() *codegen.Method { return codegen.NewCommentedValueMethod( - t.pkg.Path(), + t.PrivatePackage().Path(), typeNameMethod, t.TypeName(), /*params=*/ nil, @@ -374,14 +381,14 @@ func (t *TypeGenerator) extendsDefinition() (*codegen.Function, *codegen.Method) jen.Return(jen.False())} } f := codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.extendsFnName(), []jen.Code{jen.Id("other").Id(typeInterfaceName)}, []jen.Code{jen.Bool()}, impl, jen.Commentf("%s returns true if the %s type extends from the other type.", t.extendsFnName(), t.TypeName())) m := codegen.NewCommentedValueMethod( - t.pkg.Path(), + t.PrivatePackage().Path(), extendingMethod, t.TypeName(), []jen.Code{jen.Id("other").Id(typeInterfaceName)}, @@ -430,7 +437,7 @@ func (t *TypeGenerator) extendedByDefinition() *codegen.Function { jen.Return(jen.False())} } return codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.extendedByFnName(), []jen.Code{jen.Id("other").Id(typeInterfaceName)}, []jen.Code{jen.Bool()}, @@ -476,7 +483,7 @@ func (t *TypeGenerator) disjointWithDefinition() *codegen.Function { jen.Return(jen.False())} } return codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.disjointWithFnName(), []jen.Code{jen.Id("other").Id(typeInterfaceName)}, []jen.Code{jen.Bool()}, @@ -488,7 +495,7 @@ func (t *TypeGenerator) disjointWithDefinition() *codegen.Function { // a property. func (t *TypeGenerator) serializationMethod() (ser *codegen.Method) { ser = codegen.NewCommentedValueMethod( - t.pkg.Path(), + t.PrivatePackage().Path(), serializeMethodName, t.TypeName(), /*params=*/ nil, @@ -505,7 +512,7 @@ func (t *TypeGenerator) serializationMethod() (ser *codegen.Method) { // treat a TypeGenerator as another property's Kind. func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Function) { ser = codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.serializationFnName(), []jen.Code{jen.Id("s").Id(t.TypeName())}, []jen.Code{jen.Interface(), jen.Error()}, @@ -523,7 +530,8 @@ func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Func jen.List( jen.Id("p"), jen.Err(), - ).Op(":=").Add(deserMethod.Call(managerInitName())).Call(jen.Id("m")), + // TODO: Ensure this variable is called correctly + ).Op(":=").Add(deserMethod.Call(managerInitName(), jen.Id("m"))), jen.Err().Op("!=").Nil(), ).Block( jen.Return(jen.Nil(), jen.Err()), @@ -532,7 +540,7 @@ func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Func ).Line()) } deser = codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.deserializationFnName(), []jen.Code{jen.Id("m").Map(jen.String()).Interface()}, []jen.Code{jen.Op("*").Id(t.TypeName()), jen.Error()}, @@ -543,7 +551,7 @@ func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Func }, jen.Commentf("%s creates a %s from a map representation that has been unmarshalled from a text or binary format.", t.deserializationFnName(), t.TypeName())) less = codegen.NewCommentedFunction( - t.pkg.Path(), + t.PrivatePackage().Path(), t.lessFnName(), []jen.Code{ jen.Id("i"),