Add per-package files for property-based packages.
このコミットが含まれているのは:
コミット
be110cf688
|
@ -173,6 +173,12 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
|
||||||
Directory: pub.WriteDir(),
|
Directory: pub.WriteDir(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
propPkgFiles, err := c.propertyPackageFiles(v.FProps, v.NFProps)
|
||||||
|
if err != nil {
|
||||||
|
e = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = append(f, propPkgFiles...)
|
||||||
// Types
|
// Types
|
||||||
for _, i := range v.Types {
|
for _, i := range v.Types {
|
||||||
var pm *props.PackageManager
|
var pm *props.PackageManager
|
||||||
|
@ -617,6 +623,45 @@ func (c Converter) typePackageFiles(t map[string]*props.TypeGenerator) (f []*Fil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Converter) propertyPackageFiles(fp map[string]*props.FunctionalPropertyGenerator, nfp map[string]*props.NonFunctionalPropertyGenerator) (f []*File, e error) {
|
||||||
|
switch c.PropertyPackagePolicy {
|
||||||
|
case PropertyFlatUnderRoot:
|
||||||
|
fallthrough
|
||||||
|
case PropertyFlatUnderVocabularyRoot:
|
||||||
|
// Only need one for all types.
|
||||||
|
pgs := make([]*props.PropertyGenerator, 0, len(fp)+len(nfp))
|
||||||
|
for _, v := range fp {
|
||||||
|
pgs = append(pgs, &v.PropertyGenerator)
|
||||||
|
}
|
||||||
|
for _, v := range nfp {
|
||||||
|
pgs = append(pgs, &v.PropertyGenerator)
|
||||||
|
}
|
||||||
|
ppg := props.NewPropertyPackageGenerator()
|
||||||
|
// Private
|
||||||
|
s, i, fn := ppg.PrivateDefinitions(pgs)
|
||||||
|
priv := pgs[0].GetPrivatePackage()
|
||||||
|
file := jen.NewFilePath(priv.Path())
|
||||||
|
file.Add(
|
||||||
|
s,
|
||||||
|
).Line().Add(
|
||||||
|
i.Definition(),
|
||||||
|
).Line().Add(
|
||||||
|
fn.Definition(),
|
||||||
|
).Line()
|
||||||
|
f = append(f, &File{
|
||||||
|
F: file,
|
||||||
|
FileName: "gen_pkg.go",
|
||||||
|
Directory: priv.WriteDir(),
|
||||||
|
})
|
||||||
|
case PropertyIndividualUnderRoot:
|
||||||
|
// Need individual files per type.
|
||||||
|
// TODO
|
||||||
|
default:
|
||||||
|
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type typeNamer interface {
|
type typeNamer interface {
|
||||||
TypeName() string
|
TypeName() string
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
||||||
jen.List(
|
jen.List(
|
||||||
jen.Id("v"),
|
jen.Id("v"),
|
||||||
jen.Err(),
|
jen.Err(),
|
||||||
).Op(":=").Add(kind.DeserializeFn.Clone().Call(
|
).Op(":=").Add(kind.DeserializeFn.Clone().Call().Call(
|
||||||
jen.Id("i"),
|
jen.Id("i"),
|
||||||
)),
|
)),
|
||||||
jen.Err().Op("!=").Nil(),
|
jen.Err().Op("!=").Nil(),
|
||||||
|
|
|
@ -148,3 +148,42 @@ func (t *TypePackageGenerator) PrivateDefinitions(tgs []*TypeGenerator) (*jen.St
|
||||||
// PropertyPackageGenerator manages generating one-time files needed for
|
// PropertyPackageGenerator manages generating one-time files needed for
|
||||||
// properties.
|
// properties.
|
||||||
type PropertyPackageGenerator struct{}
|
type PropertyPackageGenerator struct{}
|
||||||
|
|
||||||
|
// NewPropertyPackageGenerator creates a new TypePackageGenerator.
|
||||||
|
func NewPropertyPackageGenerator() *PropertyPackageGenerator {
|
||||||
|
return &PropertyPackageGenerator{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateDefinitions creates the private code generated definitions needed once
|
||||||
|
// per package.
|
||||||
|
//
|
||||||
|
// Precondition: The passed-in generators are the complete set of type
|
||||||
|
// generators within a package.
|
||||||
|
func (p *PropertyPackageGenerator) PrivateDefinitions(pgs []*PropertyGenerator) (*jen.Statement, *codegen.Interface, *codegen.Function) {
|
||||||
|
fnsMap := make(map[string]codegen.FunctionSignature)
|
||||||
|
for _, pg := range pgs {
|
||||||
|
for _, m := range pg.getAllManagerMethods() {
|
||||||
|
v := m.ToFunctionSignature()
|
||||||
|
fnsMap[v.Name] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var fns []codegen.FunctionSignature
|
||||||
|
for _, v := range fnsMap {
|
||||||
|
fns = append(fns, v)
|
||||||
|
}
|
||||||
|
return jen.Var().Id(managerInitName()).Id(managerInterfaceName),
|
||||||
|
codegen.NewInterface(pgs[0].GetPrivatePackage().Path(),
|
||||||
|
managerInterfaceName,
|
||||||
|
fns,
|
||||||
|
fmt.Sprintf("%s abstracts the code-generated manager that provides access to concrete implementations.", managerInterfaceName)),
|
||||||
|
codegen.NewCommentedFunction(pgs[0].GetPrivatePackage().Path(),
|
||||||
|
setManagerFunctionName,
|
||||||
|
[]jen.Code{
|
||||||
|
jen.Id("m").Id(managerInterfaceName),
|
||||||
|
},
|
||||||
|
/*ret=*/ nil,
|
||||||
|
[]jen.Code{
|
||||||
|
jen.Id(managerInitName()).Op("=").Id("m"),
|
||||||
|
},
|
||||||
|
jen.Commentf("%s sets the manager package-global variable. For internal use only, do not use as part of Application behavior. Must be called at golang init time.", setManagerFunctionName))
|
||||||
|
}
|
||||||
|
|
|
@ -105,7 +105,8 @@ func (k Kind) lessFnCode(this, other *jen.Statement) *jen.Statement {
|
||||||
//
|
//
|
||||||
// TODO: Make this type private
|
// TODO: Make this type private
|
||||||
type PropertyGenerator struct {
|
type PropertyGenerator struct {
|
||||||
vocabName string
|
vocabName string
|
||||||
|
managerMethods []*codegen.Method
|
||||||
// TODO: Make these private
|
// TODO: Make these private
|
||||||
PackageManager *PackageManager
|
PackageManager *PackageManager
|
||||||
Name Identifier
|
Name Identifier
|
||||||
|
@ -136,14 +137,15 @@ func (p *PropertyGenerator) GetPublicPackage() Package {
|
||||||
// The name parameter must match the LowerName of an Identifier.
|
// The name parameter must match the LowerName of an Identifier.
|
||||||
//
|
//
|
||||||
// This feels very hacky.
|
// This feels very hacky.
|
||||||
func (p *PropertyGenerator) SetKindFns(name string, qualKind, deser *jen.Statement) error {
|
func (p *PropertyGenerator) SetKindFns(name string, qualKind *jen.Statement, deser *codegen.Method) error {
|
||||||
for i, kind := range p.Kinds {
|
for i, kind := range p.Kinds {
|
||||||
if kind.Name.LowerName == name {
|
if kind.Name.LowerName == name {
|
||||||
if kind.SerializeFn != nil || kind.DeserializeFn != nil || kind.LessFn != nil {
|
if kind.SerializeFn != nil || kind.DeserializeFn != nil || kind.LessFn != nil {
|
||||||
return fmt.Errorf("property kind already has serialization functions set for %q", name)
|
return fmt.Errorf("property kind already has serialization functions set for %q", name)
|
||||||
}
|
}
|
||||||
kind.ConcreteKind = qualKind
|
kind.ConcreteKind = qualKind
|
||||||
kind.DeserializeFn = deser
|
kind.DeserializeFn = deser.On(managerInitName())
|
||||||
|
p.managerMethods = append(p.managerMethods, deser)
|
||||||
p.Kinds[i] = kind
|
p.Kinds[i] = kind
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -151,6 +153,12 @@ func (p *PropertyGenerator) SetKindFns(name string, qualKind, deser *jen.Stateme
|
||||||
return fmt.Errorf("cannot find property kind %q", name)
|
return fmt.Errorf("cannot find property kind %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getAllManagerMethods returns the list of manager methods used by this
|
||||||
|
// property.
|
||||||
|
func (p *PropertyGenerator) getAllManagerMethods() []*codegen.Method {
|
||||||
|
return p.managerMethods
|
||||||
|
}
|
||||||
|
|
||||||
// StructName returns the name of the type, which may or may not be a struct,
|
// StructName returns the name of the type, which may or may not be a struct,
|
||||||
// to generate.
|
// to generate.
|
||||||
func (p *PropertyGenerator) StructName() string {
|
func (p *PropertyGenerator) StructName() string {
|
||||||
|
|
|
@ -44,7 +44,7 @@ type Property interface {
|
||||||
GetPublicPackage() Package
|
GetPublicPackage() Package
|
||||||
PropertyName() string
|
PropertyName() string
|
||||||
InterfaceName() string
|
InterfaceName() string
|
||||||
SetKindFns(name string, kind, deser *jen.Statement) error
|
SetKindFns(name string, kind *jen.Statement, deser *codegen.Method) error
|
||||||
DeserializeFnName() string
|
DeserializeFnName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +130,8 @@ func (t *TypeGenerator) apply(m *ManagerGenerator) error {
|
||||||
t.m = m
|
t.m = m
|
||||||
// Set up Kind functions
|
// Set up Kind functions
|
||||||
// Note: this "i" must be the same as the "i" in the deserialization definition.
|
// Note: this "i" must be the same as the "i" in the deserialization definition.
|
||||||
// TODO: Remove this kluge.
|
// TODO: Remove this kluge. (2nd todo: figure out wtf this todo means)
|
||||||
deser := m.getDeserializationMethodForType(t).On(managerInitName())
|
deser := m.getDeserializationMethodForType(t)
|
||||||
kind := jen.Qual(t.PublicPackage().Path(), t.InterfaceName())
|
kind := jen.Qual(t.PublicPackage().Path(), t.InterfaceName())
|
||||||
for _, p := range t.rangeProperties {
|
for _, p := range t.rangeProperties {
|
||||||
if e := p.SetKindFns(t.TypeName(), kind, deser); e != nil {
|
if e := p.SetKindFns(t.TypeName(), kind, deser); e != nil {
|
||||||
|
|
読み込み中…
新しいイシューから参照