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.
|
||||
func (v vocabulary) typeArray() []*gen.TypeGenerator {
|
||||
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
|
||||
// file structure.
|
||||
func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
||||
// Values -- include all referenced values too.
|
||||
for _, v := range v.Values {
|
||||
pkg := c.valuePackage(v)
|
||||
f = append(f, convertValue(pkg, v))
|
||||
}
|
||||
pub := c.GenRoot.PublicPackage()
|
||||
// References
|
||||
for _, ref := range v.References {
|
||||
for _, v := range ref.Values {
|
||||
pkg := c.valuePackage(v)
|
||||
|
@ -218,6 +258,22 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
|||
return
|
||||
}
|
||||
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
|
||||
files, e = c.toFiles(v)
|
||||
|
@ -225,26 +281,32 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
|||
return
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
e = err
|
||||
return
|
||||
}
|
||||
f = append(f, pkgFiles...)
|
||||
// Manager
|
||||
pub := c.GenRoot.PublicPackage()
|
||||
file := jen.NewFilePath(pub.Path())
|
||||
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)
|
||||
// Init file
|
||||
var file *File
|
||||
file, e = c.initFile(pub, v)
|
||||
if e != nil {
|
||||
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
|
||||
rootDocFile := jen.NewFilePath(pub.Path())
|
||||
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.
|
||||
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(
|
||||
c.GenRoot.PublicPackage(),
|
||||
typeArray,
|
||||
funcPropArray,
|
||||
nonFuncPropArray)
|
||||
v.allTypeArray(),
|
||||
v.allFuncPropArray(),
|
||||
v.allNonFuncPropArray())
|
||||
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
|
||||
// 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()
|
||||
ctors, ext, disj, extBy, globalVar, initFn := pg.RootDefinitions(vocabName, v.Manager, 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(),
|
||||
})
|
||||
ctors, ext, disj, extBy := pg.RootDefinitions(vocabName, m, v.typeArray(), v.propArray())
|
||||
lowerVocabName := strings.ToLower(vocabName)
|
||||
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)))
|
||||
|
@ -780,6 +824,21 @@ func (c Converter) rootFiles(pkg gen.Package, vocabName string, v vocabulary) (f
|
|||
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
|
||||
// within a single vocabulary.
|
||||
//
|
||||
|
|
|
@ -171,8 +171,12 @@ func NewPackageGenerator() *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.
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -245,7 +249,7 @@ func publicTypeDefinitions(tgs []*TypeGenerator) (typeI *codegen.Interface) {
|
|||
|
||||
// rootDefinitions creates common functions needed at the root level of the
|
||||
// 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
|
||||
for _, tg := range tgs {
|
||||
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())))
|
||||
}
|
||||
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
|
||||
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))
|
||||
for _, tg := range tgs {
|
||||
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 {
|
||||
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))
|
||||
|
@ -326,12 +336,12 @@ func rootDefinitions(vocabName string, m *ManagerGenerator, tgs []*TypeGenerator
|
|||
callInits = append(callInits, c)
|
||||
}
|
||||
init = codegen.NewCommentedFunction(
|
||||
m.pkg.Path(),
|
||||
pkg.Path(),
|
||||
"init",
|
||||
/*params=*/ nil,
|
||||
/*ret=*/ nil,
|
||||
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...),
|
||||
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
|
||||
|
|
読み込み中…
新しいイシューから参照