diff --git a/tools/exp/convert/convert.go b/tools/exp/convert/convert.go index de18cb5..380a2fa 100644 --- a/tools/exp/convert/convert.go +++ b/tools/exp/convert/convert.go @@ -2,6 +2,7 @@ package convert import ( "fmt" + "github.com/cjslep/activity/tools/exp/codegen" "github.com/cjslep/activity/tools/exp/props" "github.com/cjslep/activity/tools/exp/rdf" "github.com/dave/jennifer/jen" @@ -204,7 +205,7 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) { Directory: pub.WriteDir(), }) var files []*File - files, e = c.rootFiles(pub, v.Manager, v.Types) + files, e = c.rootFiles(pub, c.VocabularyName, v.Manager, v.Types) if e != nil { return } @@ -560,23 +561,24 @@ func (c Converter) packageManager(s string) (pkg *props.PackageManager, e error) return } -func (c Converter) rootFiles(pkg props.Package, m *props.ManagerGenerator, t map[string]*props.TypeGenerator) (f []*File, e error) { +func (c Converter) rootFiles(pkg props.Package, vocabName string, m *props.ManagerGenerator, 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, globalVar, initFn := pg.RootDefinitions(m, tgs) - file := jen.NewFilePath(pkg.Path()) - file.Add(globalVar).Line().Add(initFn.Definition()).Line() - for _, c := range ctors { - file.Add(c.Definition()).Line() - } + ctors, ext, disj, extBy, globalVar, initFn := pg.RootDefinitions(vocabName, m, tgs) + initFile := jen.NewFilePath(pkg.Path()) + initFile.Add(globalVar).Line().Add(initFn.Definition()).Line() f = append(f, &File{ - F: file, - FileName: "gen_ctors.go", + F: initFile, + FileName: "gen_init.go", Directory: pkg.WriteDir(), }) + f = append(f, funcsToFile(pkg, ctors, fmt.Sprintf("gen_pkg_%s_constructors.go", vocabName))) + f = append(f, funcsToFile(pkg, ext, fmt.Sprintf("gen_pkg_%s_extends.go", vocabName))) + f = append(f, funcsToFile(pkg, disj, fmt.Sprintf("gen_pkg_%s_disjoint.go", vocabName))) + f = append(f, funcsToFile(pkg, extBy, fmt.Sprintf("gen_pkg_%s_extendedby.go", vocabName))) return } @@ -772,3 +774,15 @@ func convertValue(pkg props.Package, v *props.Kind) *File { Directory: pkg.WriteDir(), } } + +func funcsToFile(pkg props.Package, fns []*codegen.Function, filename string) *File { + file := jen.NewFilePath(pkg.Path()) + for _, fn := range fns { + file.Add(fn.Definition()).Line() + } + return &File{ + F: file, + FileName: filename, + Directory: pkg.WriteDir(), + } +} diff --git a/tools/exp/props/pkg.go b/tools/exp/props/pkg.go index 4244bc3..cdfcb6c 100644 --- a/tools/exp/props/pkg.go +++ b/tools/exp/props/pkg.go @@ -114,8 +114,8 @@ func NewTypePackageGenerator() *TypePackageGenerator { } // RootDefinitions creates functions needed at the root level of the package declarations. -func (t *TypePackageGenerator) RootDefinitions(m *ManagerGenerator, tgs []*TypeGenerator) (ctors []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { - return rootDefinitions(m, tgs) +func (t *TypePackageGenerator) RootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator) (ctors, ext, disj, extBy []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { + return rootDefinitions(vocabName, m, tgs) } // PublicDefinitions creates the public-facing code generated definitions needed @@ -214,8 +214,8 @@ func NewPackageGenerator() *PackageGenerator { } // RootDefinitions creates functions needed at the root level of the package declarations. -func (t *PackageGenerator) RootDefinitions(m *ManagerGenerator, tgs []*TypeGenerator) (ctors []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { - return rootDefinitions(m, tgs) +func (t *PackageGenerator) RootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator) (ctors, ext, disj, extBy []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { + return rootDefinitions(vocabName, m, tgs) } // PublicDefinitions creates the public-facing code generated definitions needed @@ -269,11 +269,11 @@ func (t *PackageGenerator) PrivateDefinitions(tgs []*TypeGenerator, pgs []*Prope // rootDefinitions creates common functions needed at the root level of the // package declarations. -func rootDefinitions(m *ManagerGenerator, tgs []*TypeGenerator) (ctors []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { +func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator) (ctors, ext, disj, extBy []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) { // Type constructors for _, tg := range tgs { ctors = append(ctors, codegen.NewCommentedFunction( - tg.PublicPackage().Path(), + m.pkg.Path(), fmt.Sprintf("New%s%s", tg.PublicPackage().Name(), tg.TypeName()), /*params=*/ nil, []jen.Code{jen.Qual(tg.PublicPackage().Path(), tg.InterfaceName())}, @@ -284,6 +284,55 @@ func rootDefinitions(m *ManagerGenerator, tgs []*TypeGenerator) (ctors []*codege }, fmt.Sprintf("New%s%s creates a new %s", tg.PublicPackage().Name(), tg.TypeName(), tg.InterfaceName()))) } + // Extends + for _, tg := range tgs { + f, _ := tg.extendsDefinition() + name := fmt.Sprintf("%s%s", vocabName, f.Name()) + ext = append(ext, codegen.NewCommentedFunction( + m.pkg.Path(), + name, + []jen.Code{jen.Id("other").Qual(tg.PublicPackage().Path(), typeInterfaceName)}, + []jen.Code{jen.Bool()}, + []jen.Code{ + jen.Return( + f.Call(jen.Id("other")), + ), + }, + fmt.Sprintf("%s returns true if %s extends from the other's type.", name, tg.TypeName()))) + } + // DisjointWith + for _, tg := range tgs { + f := tg.disjointWithDefinition() + name := fmt.Sprintf("%s%s", vocabName, f.Name()) + disj = append(disj, codegen.NewCommentedFunction( + m.pkg.Path(), + name, + []jen.Code{jen.Id("other").Qual(tg.PublicPackage().Path(), typeInterfaceName)}, + []jen.Code{jen.Bool()}, + []jen.Code{ + jen.Return( + f.Call(jen.Id("other")), + ), + }, + fmt.Sprintf("%s returns true if %s is disjoint with the other's type.", name, tg.TypeName()))) + } + // ExtendedBy + for _, tg := range tgs { + f := tg.extendedByDefinition() + name := fmt.Sprintf("%s%s", vocabName, f.Name()) + extBy = append(extBy, codegen.NewCommentedFunction( + m.pkg.Path(), + name, + []jen.Code{jen.Id("other").Qual(tg.PublicPackage().Path(), typeInterfaceName)}, + []jen.Code{jen.Bool()}, + []jen.Code{ + jen.Return( + f.Call(jen.Id("other")), + ), + }, + fmt.Sprintf("%s returns true if the other's type extends from %s.", name, tg.TypeName()))) + } + // init globalManager = jen.Var().Id(managerInitName()).Op("*").Qual(m.pkg.Path(), managerName) callInitsMap := make(map[string]jen.Code, len(tgs)) for _, tg := range tgs {