From a93c6aa67866f4491e838344096cc8c6a33abfab Mon Sep 17 00:00:00 2001 From: Cory Slep Date: Sat, 12 Jan 2019 12:30:08 +0100 Subject: [PATCH] Add constructors in pkg and for types. --- tools/exp/convert/convert.go | 25 ++++++++++++++++++++ tools/exp/props/pkg.go | 46 ++++++++++++++++++++++++++++++++++-- tools/exp/props/property.go | 4 ++-- tools/exp/props/type.go | 24 +++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/tools/exp/convert/convert.go b/tools/exp/convert/convert.go index 12870b0..6f9316f 100644 --- a/tools/exp/convert/convert.go +++ b/tools/exp/convert/convert.go @@ -203,6 +203,12 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) { FileName: "gen_manager.go", Directory: pub.WriteDir(), }) + var files []*File + files, e = c.rootFiles(pub, v.Types) + if e != nil { + return + } + f = append(f, files...) return } @@ -554,6 +560,25 @@ func (c Converter) packageManager(s string) (pkg *props.PackageManager, e error) return } +func (c Converter) rootFiles(pkg props.Package, t map[string]*props.TypeGenerator) (f []*File, e error) { + tgs := make([]*props.TypeGenerator, 0, len(t)) + for _, v := range t { + tgs = append(tgs, v) + } + pg := props.NewPackageGenerator() + ctors := pg.RootDefinitions(tgs) + file := jen.NewFilePath(pkg.Path()) + for _, c := range ctors { + file.Add(c.Definition()).Line() + } + f = append(f, &File{ + F: file, + FileName: "gen_ctors.go", + Directory: pkg.WriteDir(), + }) + return +} + func (c Converter) packageFiles(t map[string]*props.TypeGenerator, fp map[string]*props.FunctionalPropertyGenerator, nfp map[string]*props.NonFunctionalPropertyGenerator) (f []*File, e error) { diff --git a/tools/exp/props/pkg.go b/tools/exp/props/pkg.go index 032cf3c..28f21c2 100644 --- a/tools/exp/props/pkg.go +++ b/tools/exp/props/pkg.go @@ -113,12 +113,35 @@ func NewTypePackageGenerator() *TypePackageGenerator { return &TypePackageGenerator{} } +// RootDefinitions creates functions needed at the root level of the package declarations. +func (t *TypePackageGenerator) RootDefinitions(tgs []*TypeGenerator) (ctors []*codegen.Function) { + // Type constructors + for _, tg := range tgs { + ctors = append(ctors, codegen.NewCommentedFunction( + tg.PublicPackage().Path(), + fmt.Sprintf("New%s%s", tg.PublicPackage().Name(), tg.TypeName()), + /*params=*/ nil, + []jen.Code{jen.Qual(tg.PublicPackage().Path(), tg.InterfaceName())}, + []jen.Code{ + jen.Return( + jen.Op("&").Qual(tg.PrivatePackage().Path(), tg.TypeName()).Values( + jen.Dict{ + jen.Id(unknownMember): jen.Make(jen.Map(jen.String()).Interface(), jen.Lit(0)), + }, + ), + ), + }, + fmt.Sprintf("New%s%s creates a new %s", tg.PublicPackage().Name(), tg.TypeName(), tg.InterfaceName()))) + } + return +} + // PublicDefinitions creates the public-facing code generated definitions needed // once per package. // // Precondition: The passed-in generators are the complete set of type // generators within a package. -func (t *TypePackageGenerator) PublicDefinitions(tgs []*TypeGenerator) *codegen.Interface { +func (t *TypePackageGenerator) PublicDefinitions(tgs []*TypeGenerator) (typeI *codegen.Interface) { return TypeInterface(tgs[0].PublicPackage()) } @@ -127,7 +150,7 @@ func (t *TypePackageGenerator) PublicDefinitions(tgs []*TypeGenerator) *codegen. // // Precondition: The passed-in generators are the complete set of type // generators within a package. -func (t *TypePackageGenerator) PrivateDefinitions(tgs []*TypeGenerator) (*jen.Statement, *codegen.Interface, *codegen.Function) { +func (t *TypePackageGenerator) PrivateDefinitions(tgs []*TypeGenerator) (mgrVar *jen.Statement, mgrI *codegen.Interface, setMgrFn *codegen.Function) { fnsMap := make(map[string]codegen.FunctionSignature) for _, tg := range tgs { for _, m := range tg.getAllManagerMethods() { @@ -208,6 +231,25 @@ func NewPackageGenerator() *PackageGenerator { return &PackageGenerator{} } +// RootDefinitions creates functions needed at the root level of the package declarations. +func (t *PackageGenerator) RootDefinitions(tgs []*TypeGenerator) (ctors []*codegen.Function) { + // Type constructors + for _, tg := range tgs { + ctors = append(ctors, codegen.NewCommentedFunction( + tg.PublicPackage().Path(), + fmt.Sprintf("New%s%s", tg.PublicPackage().Name(), tg.TypeName()), + /*params=*/ nil, + []jen.Code{jen.Qual(tg.PublicPackage().Path(), tg.InterfaceName())}, + []jen.Code{ + jen.Return( + tg.constructorFn().Call(), + ), + }, + fmt.Sprintf("New%s%s creates a new %s", tg.PublicPackage().Name(), tg.TypeName(), tg.InterfaceName()))) + } + return +} + // PublicDefinitions creates the public-facing code generated definitions needed // once per package. // diff --git a/tools/exp/props/property.go b/tools/exp/props/property.go index 4a72979..21b4b4f 100644 --- a/tools/exp/props/property.go +++ b/tools/exp/props/property.go @@ -127,8 +127,8 @@ func (k Kind) isValue() bool { // It also properly handles the concept of generating Go code for property // iterators, which are needed for NonFunctional properties. type PropertyGenerator struct { - vocabName string - managerMethods []*codegen.Method + vocabName string + managerMethods []*codegen.Method packageManager *PackageManager name Identifier comment string diff --git a/tools/exp/props/type.go b/tools/exp/props/type.go index 8522a1d..51ab83b 100644 --- a/tools/exp/props/type.go +++ b/tools/exp/props/type.go @@ -22,6 +22,7 @@ const ( getUnknownMethod = "GetUnknownProperties" unknownMember = "unknown" getMethodFormat = "Get%s" + constructorName = "New" ) // TypeInterface returns the Type Interface that is needed for ActivityStream @@ -244,6 +245,7 @@ func (t *TypeGenerator) Definition() *codegen.Struct { extendsFn, extendsMethod := t.extendsDefinition() getters := t.allGetters() setters := t.allSetters() + constructor := t.constructorFn() t.cachedStruct = codegen.NewStruct( t.Comments(), t.TypeName(), @@ -259,6 +261,7 @@ func (t *TypeGenerator) Definition() *codegen.Struct { setters..., ), []*codegen.Function{ + constructor, t.extendedByDefinition(), extendsFn, t.disjointWithDefinition(), @@ -732,3 +735,24 @@ func (t *TypeGenerator) getAllManagerMethods() (m []*codegen.Method) { } return m } + +// constructorFn creates a constructor for this type. +func (t *TypeGenerator) constructorFn() *codegen.Function { + return codegen.NewCommentedFunction( + t.PrivatePackage().Path(), + fmt.Sprintf("%s%s", constructorName, t.TypeName()), + /*params=*/ nil, + []jen.Code{ + jen.Op("*").Qual(t.PrivatePackage().Path(), t.TypeName()), + }, + []jen.Code{ + jen.Return( + jen.Op("&").Qual(t.PrivatePackage().Path(), t.TypeName()).Values( + jen.Dict{ + jen.Id(unknownMember): jen.Make(jen.Map(jen.String()).Interface(), jen.Lit(0)), + }, + ), + ), + }, + fmt.Sprintf("%s%s creates a new %s type", constructorName, t.TypeName(), t.TypeName())) +}