Fix init generation for multiple vocabularies.
このコミットが含まれているのは:
コミット
c3b9686d1f
|
@ -44,6 +44,49 @@ func newVocabulary() vocabulary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allTypeArray converts all Types, including referenced Types, to an array.
|
||||||
|
func (v vocabulary) allTypeArray() []*gen.TypeGenerator {
|
||||||
|
var typeArray []*gen.TypeGenerator
|
||||||
|
for _, ref := range v.References {
|
||||||
|
typeArray = append(typeArray, ref.typeArray()...)
|
||||||
|
}
|
||||||
|
typeArray = append(typeArray, v.typeArray()...)
|
||||||
|
return typeArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// allPropArray converts all Properties, including referenced Properties, to an
|
||||||
|
// array.
|
||||||
|
func (v vocabulary) allPropArray() []*gen.PropertyGenerator {
|
||||||
|
var propArray []*gen.PropertyGenerator
|
||||||
|
for _, ref := range v.References {
|
||||||
|
propArray = append(propArray, ref.propArray()...)
|
||||||
|
}
|
||||||
|
propArray = append(propArray, v.propArray()...)
|
||||||
|
return propArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// allFuncPropArray converts all FProps, including referenced Properties, to an
|
||||||
|
// array.
|
||||||
|
func (v vocabulary) allFuncPropArray() []*gen.FunctionalPropertyGenerator {
|
||||||
|
var funcPropArray []*gen.FunctionalPropertyGenerator
|
||||||
|
for _, ref := range v.References {
|
||||||
|
funcPropArray = append(funcPropArray, ref.funcPropArray()...)
|
||||||
|
}
|
||||||
|
funcPropArray = append(funcPropArray, v.funcPropArray()...)
|
||||||
|
return funcPropArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// allNonFuncPropArray converts all NFProps, including referenced Properties, to
|
||||||
|
// an array.
|
||||||
|
func (v vocabulary) allNonFuncPropArray() []*gen.NonFunctionalPropertyGenerator {
|
||||||
|
var nonFuncPropArray []*gen.NonFunctionalPropertyGenerator
|
||||||
|
for _, ref := range v.References {
|
||||||
|
nonFuncPropArray = append(nonFuncPropArray, ref.nonFuncPropArray()...)
|
||||||
|
}
|
||||||
|
nonFuncPropArray = append(nonFuncPropArray, v.nonFuncPropArray()...)
|
||||||
|
return nonFuncPropArray
|
||||||
|
}
|
||||||
|
|
||||||
// typeArray converts Types to an array.
|
// typeArray converts Types to an array.
|
||||||
func (v vocabulary) typeArray() []*gen.TypeGenerator {
|
func (v vocabulary) typeArray() []*gen.TypeGenerator {
|
||||||
tg := make([]*gen.TypeGenerator, 0, len(v.Types))
|
tg := make([]*gen.TypeGenerator, 0, len(v.Types))
|
||||||
|
@ -202,11 +245,8 @@ func (c Converter) Convert(p *rdf.ParsedVocabulary) (f []*File, e error) {
|
||||||
// convertToFiles takes the generators for a vocabulary and maps them into a
|
// convertToFiles takes the generators for a vocabulary and maps them into a
|
||||||
// file structure.
|
// file structure.
|
||||||
func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
||||||
// Values -- include all referenced values too.
|
pub := c.GenRoot.PublicPackage()
|
||||||
for _, v := range v.Values {
|
// References
|
||||||
pkg := c.valuePackage(v)
|
|
||||||
f = append(f, convertValue(pkg, v))
|
|
||||||
}
|
|
||||||
for _, ref := range v.References {
|
for _, ref := range v.References {
|
||||||
for _, v := range ref.Values {
|
for _, v := range ref.Values {
|
||||||
pkg := c.valuePackage(v)
|
pkg := c.valuePackage(v)
|
||||||
|
@ -218,6 +258,22 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f = append(f, files...)
|
f = append(f, files...)
|
||||||
|
files, e = c.rootFiles(pub, ref.Name, *ref, v.Manager)
|
||||||
|
if e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = append(f, files...)
|
||||||
|
pkgFiles, err := c.packageFiles(*ref)
|
||||||
|
if err != nil {
|
||||||
|
e = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = append(f, pkgFiles...)
|
||||||
|
}
|
||||||
|
// This vocabulary
|
||||||
|
for _, v := range v.Values {
|
||||||
|
pkg := c.valuePackage(v)
|
||||||
|
f = append(f, convertValue(pkg, v))
|
||||||
}
|
}
|
||||||
var files []*File
|
var files []*File
|
||||||
files, e = c.toFiles(v)
|
files, e = c.toFiles(v)
|
||||||
|
@ -225,26 +281,32 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f = append(f, files...)
|
f = append(f, files...)
|
||||||
|
files, e = c.rootFiles(pub, v.Name, v, v.Manager)
|
||||||
|
if e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = append(f, files...)
|
||||||
pkgFiles, err := c.packageFiles(v)
|
pkgFiles, err := c.packageFiles(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e = err
|
e = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f = append(f, pkgFiles...)
|
f = append(f, pkgFiles...)
|
||||||
// Manager
|
// Init file
|
||||||
pub := c.GenRoot.PublicPackage()
|
var file *File
|
||||||
file := jen.NewFilePath(pub.Path())
|
file, e = c.initFile(pub, v)
|
||||||
file.Add(v.Manager.Definition().Definition())
|
|
||||||
f = append(f, &File{
|
|
||||||
F: file,
|
|
||||||
FileName: "gen_manager.go",
|
|
||||||
Directory: pub.WriteDir(),
|
|
||||||
})
|
|
||||||
files, e = c.rootFiles(pub, v.Name, v)
|
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f = append(f, files...)
|
f = append(f, file)
|
||||||
|
// Manager
|
||||||
|
jenFile := jen.NewFilePath(pub.Path())
|
||||||
|
jenFile.Add(v.Manager.Definition().Definition())
|
||||||
|
f = append(f, &File{
|
||||||
|
F: jenFile,
|
||||||
|
FileName: "gen_manager.go",
|
||||||
|
Directory: pub.WriteDir(),
|
||||||
|
})
|
||||||
// Root Package Documentation
|
// Root Package Documentation
|
||||||
rootDocFile := jen.NewFilePath(pub.Path())
|
rootDocFile := jen.NewFilePath(pub.Path())
|
||||||
rootDocFile.PackageComment(gen.GenRootPackageComment(pub.Name()))
|
rootDocFile.PackageComment(gen.GenRootPackageComment(pub.Name()))
|
||||||
|
@ -319,22 +381,11 @@ func (c Converter) convertVocabulary(p *rdf.ParsedVocabulary, refs map[string]*v
|
||||||
|
|
||||||
// convertGenRoot creates code-wide code generators.
|
// convertGenRoot creates code-wide code generators.
|
||||||
func (c Converter) convertGenRoot(v *vocabulary) (e error) {
|
func (c Converter) convertGenRoot(v *vocabulary) (e error) {
|
||||||
var typeArray []*gen.TypeGenerator
|
|
||||||
var funcPropArray []*gen.FunctionalPropertyGenerator
|
|
||||||
var nonFuncPropArray []*gen.NonFunctionalPropertyGenerator
|
|
||||||
for _, ref := range v.References {
|
|
||||||
typeArray = append(typeArray, ref.typeArray()...)
|
|
||||||
funcPropArray = append(funcPropArray, ref.funcPropArray()...)
|
|
||||||
nonFuncPropArray = append(nonFuncPropArray, ref.nonFuncPropArray()...)
|
|
||||||
}
|
|
||||||
typeArray = append(typeArray, v.typeArray()...)
|
|
||||||
funcPropArray = append(funcPropArray, v.funcPropArray()...)
|
|
||||||
nonFuncPropArray = append(nonFuncPropArray, v.nonFuncPropArray()...)
|
|
||||||
v.Manager, e = gen.NewManagerGenerator(
|
v.Manager, e = gen.NewManagerGenerator(
|
||||||
c.GenRoot.PublicPackage(),
|
c.GenRoot.PublicPackage(),
|
||||||
typeArray,
|
v.allTypeArray(),
|
||||||
funcPropArray,
|
v.allFuncPropArray(),
|
||||||
nonFuncPropArray)
|
v.allNonFuncPropArray())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,16 +813,9 @@ func (c Converter) packageManager(s, vocabName string) (pkg *gen.PackageManager,
|
||||||
|
|
||||||
// rootFiles creates files that are applied for all vocabularies. These files
|
// rootFiles creates files that are applied for all vocabularies. These files
|
||||||
// are the ones typically used by developers.
|
// are the ones typically used by developers.
|
||||||
func (c Converter) rootFiles(pkg gen.Package, vocabName string, v vocabulary) (f []*File, e error) {
|
func (c Converter) rootFiles(pkg gen.Package, vocabName string, v vocabulary, m *gen.ManagerGenerator) (f []*File, e error) {
|
||||||
pg := gen.NewPackageGenerator()
|
pg := gen.NewPackageGenerator()
|
||||||
ctors, ext, disj, extBy, globalVar, initFn := pg.RootDefinitions(vocabName, v.Manager, v.typeArray(), v.propArray())
|
ctors, ext, disj, extBy := pg.RootDefinitions(vocabName, m, v.typeArray(), v.propArray())
|
||||||
initFile := jen.NewFilePath(pkg.Path())
|
|
||||||
initFile.Add(globalVar).Line().Add(initFn.Definition()).Line()
|
|
||||||
f = append(f, &File{
|
|
||||||
F: initFile,
|
|
||||||
FileName: "gen_init.go",
|
|
||||||
Directory: pkg.WriteDir(),
|
|
||||||
})
|
|
||||||
lowerVocabName := strings.ToLower(vocabName)
|
lowerVocabName := strings.ToLower(vocabName)
|
||||||
f = append(f, funcsToFile(pkg, ctors, fmt.Sprintf("gen_pkg_%s_constructors.go", lowerVocabName)))
|
f = append(f, funcsToFile(pkg, ctors, fmt.Sprintf("gen_pkg_%s_constructors.go", lowerVocabName)))
|
||||||
f = append(f, funcsToFile(pkg, ext, fmt.Sprintf("gen_pkg_%s_extends.go", lowerVocabName)))
|
f = append(f, funcsToFile(pkg, ext, fmt.Sprintf("gen_pkg_%s_extends.go", lowerVocabName)))
|
||||||
|
@ -780,6 +824,21 @@ func (c Converter) rootFiles(pkg gen.Package, vocabName string, v vocabulary) (f
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initFile creates the file with the init function that hooks together the
|
||||||
|
// runtime Manager.
|
||||||
|
func (c Converter) initFile(pkg gen.Package, root vocabulary) (f *File, e error) {
|
||||||
|
pg := gen.NewPackageGenerator()
|
||||||
|
globalVar, initFn := pg.InitDefinitions(pkg, root.allTypeArray(), root.allPropArray())
|
||||||
|
initFile := jen.NewFilePath(pkg.Path())
|
||||||
|
initFile.Add(globalVar).Line().Add(initFn.Definition()).Line()
|
||||||
|
f = &File{
|
||||||
|
F: initFile,
|
||||||
|
FileName: "gen_init.go",
|
||||||
|
Directory: pkg.WriteDir(),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// packageFiles generates package-level files necessary for types and properties
|
// packageFiles generates package-level files necessary for types and properties
|
||||||
// within a single vocabulary.
|
// within a single vocabulary.
|
||||||
//
|
//
|
||||||
|
|
|
@ -171,8 +171,12 @@ func NewPackageGenerator() *PackageGenerator {
|
||||||
return &PackageGenerator{}
|
return &PackageGenerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *PackageGenerator) InitDefinitions(pkg Package, tgs []*TypeGenerator, pgs []*PropertyGenerator) (globalManager *jen.Statement, init *codegen.Function) {
|
||||||
|
return genInit(pkg, tgs, pgs)
|
||||||
|
}
|
||||||
|
|
||||||
// RootDefinitions creates functions needed at the root level of the package declarations.
|
// RootDefinitions creates functions needed at the root level of the package declarations.
|
||||||
func (t *PackageGenerator) RootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator, pgs []*PropertyGenerator) (ctors, ext, disj, extBy []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) {
|
func (t *PackageGenerator) RootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator, pgs []*PropertyGenerator) (ctors, ext, disj, extBy []*codegen.Function) {
|
||||||
return rootDefinitions(vocabName, m, tgs, pgs)
|
return rootDefinitions(vocabName, m, tgs, pgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +249,7 @@ func publicTypeDefinitions(tgs []*TypeGenerator) (typeI *codegen.Interface) {
|
||||||
|
|
||||||
// rootDefinitions creates common functions needed at the root level of the
|
// rootDefinitions creates common functions needed at the root level of the
|
||||||
// package declarations.
|
// package declarations.
|
||||||
func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator, pgs []*PropertyGenerator) (ctors, ext, disj, extBy []*codegen.Function, globalManager *jen.Statement, init *codegen.Function) {
|
func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator, pgs []*PropertyGenerator) (ctors, ext, disj, extBy []*codegen.Function) {
|
||||||
// Type constructors
|
// Type constructors
|
||||||
for _, tg := range tgs {
|
for _, tg := range tgs {
|
||||||
ctors = append(ctors, codegen.NewCommentedFunction(
|
ctors = append(ctors, codegen.NewCommentedFunction(
|
||||||
|
@ -308,17 +312,23 @@ func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator
|
||||||
},
|
},
|
||||||
fmt.Sprintf("%s returns true if the other's type extends from %s.", name, tg.TypeName())))
|
fmt.Sprintf("%s returns true if the other's type extends from %s.", name, tg.TypeName())))
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// init generates the code that implements the init calls per-type and
|
||||||
|
// per-property package, so that the Manager is injected at runtime.
|
||||||
|
func genInit(pkg Package, tgs []*TypeGenerator, pgs []*PropertyGenerator) (globalManager *jen.Statement, init *codegen.Function) {
|
||||||
// init
|
// init
|
||||||
globalManager = jen.Var().Id(managerInitName()).Op("*").Qual(m.pkg.Path(), managerName)
|
globalManager = jen.Var().Id(managerInitName()).Op("*").Qual(pkg.Path(), managerName)
|
||||||
callInitsMap := make(map[string]jen.Code, len(tgs))
|
callInitsMap := make(map[string]jen.Code, len(tgs))
|
||||||
for _, tg := range tgs {
|
for _, tg := range tgs {
|
||||||
callInitsMap[tg.PrivatePackage().Path()] = jen.Qual(tg.PrivatePackage().Path(), setManagerFunctionName).Call(
|
callInitsMap[tg.PrivatePackage().Path()] = jen.Qual(tg.PrivatePackage().Path(), setManagerFunctionName).Call(
|
||||||
jen.Qual(m.pkg.Path(), managerInitName()),
|
jen.Qual(pkg.Path(), managerInitName()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for _, pg := range pgs {
|
for _, pg := range pgs {
|
||||||
callInitsMap[pg.GetPrivatePackage().Path()] = jen.Qual(pg.GetPrivatePackage().Path(), setManagerFunctionName).Call(
|
callInitsMap[pg.GetPrivatePackage().Path()] = jen.Qual(pg.GetPrivatePackage().Path(), setManagerFunctionName).Call(
|
||||||
jen.Qual(m.pkg.Path(), managerInitName()),
|
jen.Qual(pkg.Path(), managerInitName()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
callInits := make([]jen.Code, 0, len(callInitsMap))
|
callInits := make([]jen.Code, 0, len(callInitsMap))
|
||||||
|
@ -326,12 +336,12 @@ func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator
|
||||||
callInits = append(callInits, c)
|
callInits = append(callInits, c)
|
||||||
}
|
}
|
||||||
init = codegen.NewCommentedFunction(
|
init = codegen.NewCommentedFunction(
|
||||||
m.pkg.Path(),
|
pkg.Path(),
|
||||||
"init",
|
"init",
|
||||||
/*params=*/ nil,
|
/*params=*/ nil,
|
||||||
/*ret=*/ nil,
|
/*ret=*/ nil,
|
||||||
append([]jen.Code{
|
append([]jen.Code{
|
||||||
jen.Qual(m.pkg.Path(), managerInitName()).Op("=").Op("&").Qual(m.pkg.Path(), managerName).Values(),
|
jen.Qual(pkg.Path(), managerInitName()).Op("=").Op("&").Qual(pkg.Path(), managerName).Values(),
|
||||||
}, callInits...),
|
}, callInits...),
|
||||||
fmt.Sprintf("init handles the 'magic' of creating a %s and dependency-injecting it into every other code-generated package. This gives the implementations access to create any type needed to deserialize, without relying on the other specific concrete implementations. In order to replace a go-fed created type with your own, be sure to have the manager call your own implementation's deserialize functions instead of the built-in type. Finally, each implementation views the %s as an interface with only a subset of funcitons available. This means this %s implements the union of those interfaces.", managerName, managerName, managerName))
|
fmt.Sprintf("init handles the 'magic' of creating a %s and dependency-injecting it into every other code-generated package. This gives the implementations access to create any type needed to deserialize, without relying on the other specific concrete implementations. In order to replace a go-fed created type with your own, be sure to have the manager call your own implementation's deserialize functions instead of the built-in type. Finally, each implementation views the %s as an interface with only a subset of funcitons available. This means this %s implements the union of those interfaces.", managerName, managerName, managerName))
|
||||||
return
|
return
|
||||||
|
|
読み込み中…
新しいイシューから参照