Clean up qualified names between implementations.
Implementations are relying more on each others' interfaces, which allows for better code isolation and a better chance at pruning down binaries when needed. Still plenty of TODO items left to tackle.
このコミットが含まれているのは:
コミット
aeda61d2f1
|
@ -202,6 +202,12 @@ func (m Method) Call(on string, params ...jen.Code) jen.Code {
|
|||
return jen.Id(on).Dot(m.function.name).Call(params...)
|
||||
}
|
||||
|
||||
// On generates the Go code that determines the qualified method name on a
|
||||
// specific variable.
|
||||
func (m Method) On(on string) *jen.Statement {
|
||||
return jen.Id(on).Dot(m.function.name)
|
||||
}
|
||||
|
||||
// Name returns the identifier of this function.
|
||||
func (m Method) Name() string {
|
||||
return m.function.name
|
||||
|
|
|
@ -282,13 +282,24 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
|||
jen.Id(codegen.This()).Dot(p.isMethodName(i)).Call(),
|
||||
)
|
||||
}
|
||||
serializeFns = serializeFns.Block(
|
||||
jen.Return(
|
||||
kind.SerializeFn.Clone().Call(
|
||||
jen.Id(codegen.This()).Dot(p.getFnName(i)).Call(),
|
||||
if kind.SerializeFn != nil {
|
||||
// This is a value that has a function that must be
|
||||
// called to serialize properly.
|
||||
serializeFns = serializeFns.Block(
|
||||
jen.Return(
|
||||
kind.SerializeFn.Clone().Call(
|
||||
jen.Id(codegen.This()).Dot(p.getFnName(i)).Call(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// This is a type with a Serialize method.
|
||||
serializeFns = serializeFns.Block(
|
||||
jen.Return(
|
||||
jen.Id(codegen.This()).Dot(p.getFnName(i)).Call().Dot(serializeMethodName).Call(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
serialize := codegen.NewCommentedValueMethod(
|
||||
p.Package.Path(),
|
||||
|
|
|
@ -57,7 +57,8 @@ type ManagerGenerator struct {
|
|||
// managedMethods caches the specific methods and interfaces mapped to specific
|
||||
// properties and types.
|
||||
type managedMethods struct {
|
||||
deserializor *codegen.Method
|
||||
deserializor *codegen.Method
|
||||
// TODO: Delete these?
|
||||
publicDeserializor *codegen.Method
|
||||
// Interface for a manager
|
||||
mIface *codegen.Interface
|
||||
|
@ -203,6 +204,7 @@ func (m *ManagerGenerator) PrivateManager() *codegen.Struct {
|
|||
func (m *ManagerGenerator) createPrivateDeserializationMethodForType(tg *TypeGenerator) *codegen.Method {
|
||||
dn := tg.deserializationFnName()
|
||||
pkg := m.pm.PrivatePackage()
|
||||
// TODO: Better naming scheme from package name
|
||||
name := fmt.Sprintf("%s%s%s", dn, tg.PrivatePackage().Name(), strings.Title(pkg.Name()))
|
||||
return codegen.NewCommentedValueMethod(
|
||||
pkg.Path(),
|
||||
|
@ -233,6 +235,7 @@ func (m *ManagerGenerator) createPrivateDeserializationMethodForType(tg *TypeGen
|
|||
func (m *ManagerGenerator) createPrivateDeserializationMethodForFuncProperty(fp *FunctionalPropertyGenerator) *codegen.Method {
|
||||
dn := fp.DeserializeFnName()
|
||||
pkg := m.pm.PrivatePackage()
|
||||
// TODO: Better naming scheme from package name
|
||||
name := fmt.Sprintf("%s%s%s", dn, fp.Package.Name(), strings.Title(pkg.Name()))
|
||||
return codegen.NewCommentedValueMethod(
|
||||
pkg.Path(),
|
||||
|
@ -263,6 +266,7 @@ func (m *ManagerGenerator) createPrivateDeserializationMethodForFuncProperty(fp
|
|||
func (m *ManagerGenerator) createPrivateDeserializationMethodForNonFuncProperty(nfp *NonFunctionalPropertyGenerator) *codegen.Method {
|
||||
dn := nfp.DeserializeFnName()
|
||||
pkg := m.pm.PrivatePackage()
|
||||
// TODO: Better naming scheme from package name
|
||||
name := fmt.Sprintf("%s%s%s", dn, nfp.Package.Name(), strings.Title(pkg.Name()))
|
||||
return codegen.NewCommentedValueMethod(
|
||||
pkg.Path(),
|
||||
|
|
|
@ -156,15 +156,21 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
|||
if i > 0 {
|
||||
less.Else()
|
||||
}
|
||||
// LessFn is nil case -- call Less method directly on the LHS.
|
||||
lessCall := jen.Id("lhs").Dot(lessMethod).Call(jen.Id("rhs"))
|
||||
if kind.LessFn != nil {
|
||||
// LessFn is indeed a function -- call this function
|
||||
lessCall = kind.LessFn.Clone().Call(
|
||||
jen.Id("lhs"),
|
||||
jen.Id("rhs"),
|
||||
)
|
||||
}
|
||||
less.If(
|
||||
jen.Id("idx1").Op("==").Lit(i),
|
||||
).Block(
|
||||
jen.Id("lhs").Op(":=").Id(codegen.This()).Index(jen.Id("i")).Dot(p.getFnName(i)).Call(),
|
||||
jen.Id("rhs").Op(":=").Id(codegen.This()).Index(jen.Id("j")).Dot(p.getFnName(i)).Call(),
|
||||
jen.Return(kind.LessFn.Clone().Call(
|
||||
jen.Id("lhs"),
|
||||
jen.Id("rhs"),
|
||||
)),
|
||||
jen.Return(lessCall),
|
||||
)
|
||||
}
|
||||
// Remove Method
|
||||
|
|
|
@ -62,13 +62,15 @@ type Identifier struct {
|
|||
// Only represents values and other types.
|
||||
type Kind struct {
|
||||
Name Identifier
|
||||
// ConcreteKind is expected to be a jen.Qual
|
||||
// ConcreteKind is expected to be properly qualified.
|
||||
ConcreteKind *jen.Statement
|
||||
Nilable bool
|
||||
// These functions are expected to be a jen.Qual
|
||||
SerializeFn *jen.Statement
|
||||
// Expected to always be non-nil: a function is needed to deserialize.
|
||||
DeserializeFn *jen.Statement
|
||||
LessFn *jen.Statement
|
||||
// If any of these are nil at generation time, assume to call the method
|
||||
// on the object directly (instead of a qualified function).
|
||||
SerializeFn *jen.Statement
|
||||
LessFn *jen.Statement
|
||||
}
|
||||
|
||||
// PropertyGenerator is a common base struct used in both Functional and
|
||||
|
@ -100,16 +102,14 @@ func (p *PropertyGenerator) GetPackage() Package {
|
|||
// The name parameter must match the LowerName of an Identifier.
|
||||
//
|
||||
// This feels very hacky.
|
||||
func (p *PropertyGenerator) SetKindFns(name string, qualKind, ser, deser, less *jen.Statement) error {
|
||||
func (p *PropertyGenerator) SetKindFns(name string, qualKind, deser *jen.Statement) error {
|
||||
for i, kind := range p.Kinds {
|
||||
if kind.Name.LowerName == name {
|
||||
if kind.SerializeFn != nil || kind.DeserializeFn != nil || kind.LessFn != nil {
|
||||
return fmt.Errorf("property kind already has serialization functions set for %q", name)
|
||||
}
|
||||
kind.ConcreteKind = qualKind
|
||||
kind.SerializeFn = ser
|
||||
kind.DeserializeFn = deser
|
||||
kind.LessFn = less
|
||||
p.Kinds[i] = kind
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,9 +9,6 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// TODO: Prevent circular dependency by somehow abstracting the requisite
|
||||
// functions between props and types.
|
||||
|
||||
const (
|
||||
typeInterfaceName = "Type"
|
||||
extendedByMethod = "IsExtendedBy"
|
||||
|
@ -21,7 +18,7 @@ const (
|
|||
typeNameMethod = "Name"
|
||||
serializeMethodName = "Serialize"
|
||||
deserializeFnName = "Deserialize"
|
||||
lessFnName = "Less"
|
||||
typeLessMethod = "LessThan"
|
||||
)
|
||||
|
||||
// TypeInterface returns the Type Interface that is needed for ActivityStream
|
||||
|
@ -45,7 +42,7 @@ type Property interface {
|
|||
GetPackage() Package
|
||||
PropertyName() string
|
||||
StructName() string
|
||||
SetKindFns(name string, kind, ser, deser, less *jen.Statement) error
|
||||
SetKindFns(name string, kind, deser *jen.Statement) error
|
||||
DeserializeFnName() string
|
||||
}
|
||||
|
||||
|
@ -128,13 +125,12 @@ func NewTypeGenerator(pm *PackageManager, typeName, comment string,
|
|||
func (t *TypeGenerator) apply(m *ManagerGenerator) error {
|
||||
t.m = m
|
||||
// Set up Kind functions
|
||||
// TODO: Call serialize on an object instead of using a function.
|
||||
ser := jen.Qual(t.PrivatePackage().Path(), t.serializationFnName())
|
||||
deser := jen.Qual(m.privatePackage().Path(), m.getPrivateDeserializationMethodForType(t).Name())
|
||||
less := jen.Qual(t.PrivatePackage().Path(), t.lessFnName())
|
||||
// Note: this "i" must be the same as the "i" in the deserialization definition.
|
||||
// TODO: Remove this kluge.
|
||||
deser := m.getPrivateDeserializationMethodForType(t).On(managerInitName())
|
||||
kind := jen.Qual(t.PublicPackage().Path(), t.InterfaceName())
|
||||
for _, p := range t.rangeProperties {
|
||||
if e := p.SetKindFns(t.TypeName(), kind, ser, deser, less); e != nil {
|
||||
if e := p.SetKindFns(t.TypeName(), kind, deser); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
@ -220,17 +216,6 @@ func (t *TypeGenerator) deserializationFnName() string {
|
|||
return fmt.Sprintf("%s%s", deserializeFnName, t.TypeName())
|
||||
}
|
||||
|
||||
// serializationFnName determines the name of the serialize function for this
|
||||
// type.
|
||||
func (t *TypeGenerator) serializationFnName() string {
|
||||
return fmt.Sprintf("%s%s", serializeMethodName, t.TypeName())
|
||||
}
|
||||
|
||||
// lessFnName determines the name of the less function for this type.
|
||||
func (t *TypeGenerator) lessFnName() string {
|
||||
return fmt.Sprintf("%s%s", lessFnName, t.TypeName())
|
||||
}
|
||||
|
||||
// toInterface creates the interface version of the definition generated.
|
||||
//
|
||||
// Requires apply to have already been called.
|
||||
|
@ -254,8 +239,9 @@ func (t *TypeGenerator) InterfaceDefinition(pkg Package) *codegen.Interface {
|
|||
func (t *TypeGenerator) Definition() *codegen.Struct {
|
||||
t.cacheOnce.Do(func() {
|
||||
members := t.members()
|
||||
m := t.serializationMethod()
|
||||
ser, deser, less := t.kindSerializationFuncs()
|
||||
ser := t.serializationMethod()
|
||||
less := t.lessMethod()
|
||||
deser := t.kindDeserializationFunc()
|
||||
extendsFn, extendsMethod := t.extendsDefinition()
|
||||
t.cachedStruct = codegen.NewStruct(
|
||||
jen.Commentf(t.Comments()),
|
||||
|
@ -263,15 +249,14 @@ func (t *TypeGenerator) Definition() *codegen.Struct {
|
|||
[]*codegen.Method{
|
||||
t.nameDefinition(),
|
||||
extendsMethod,
|
||||
m,
|
||||
ser,
|
||||
less,
|
||||
},
|
||||
[]*codegen.Function{
|
||||
t.extendedByDefinition(),
|
||||
extendsFn,
|
||||
t.disjointWithDefinition(),
|
||||
ser,
|
||||
deser,
|
||||
less,
|
||||
},
|
||||
members)
|
||||
})
|
||||
|
@ -322,6 +307,7 @@ func (t *TypeGenerator) members() (members []jen.Code) {
|
|||
// Convert to jen.Code
|
||||
members = make([]jen.Code, 0, len(p))
|
||||
for _, property := range sortedMembers {
|
||||
// TODO: Use interface instead
|
||||
members = append(members, jen.Id(strings.Title(property.PropertyName())).Qual(property.GetPackage().Path(), property.StructName()))
|
||||
}
|
||||
return
|
||||
|
@ -508,20 +494,27 @@ func (t *TypeGenerator) serializationMethod() (ser *codegen.Method) {
|
|||
return
|
||||
}
|
||||
|
||||
// kindSerializationFuncs returns free function references that can be used to
|
||||
// treat a TypeGenerator as another property's Kind.
|
||||
func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Function) {
|
||||
ser = codegen.NewCommentedFunction(
|
||||
// lessMethod returns the method needed to compare a type with another type.
|
||||
func (t *TypeGenerator) lessMethod() (less *codegen.Method) {
|
||||
less = codegen.NewCommentedValueMethod(
|
||||
t.PrivatePackage().Path(),
|
||||
t.serializationFnName(),
|
||||
[]jen.Code{jen.Id("s").Id(t.TypeName())},
|
||||
[]jen.Code{jen.Interface(), jen.Error()},
|
||||
typeLessMethod,
|
||||
t.TypeName(),
|
||||
[]jen.Code{
|
||||
jen.Return(
|
||||
jen.Id("s").Dot(serializeMethodName).Call(),
|
||||
),
|
||||
jen.Id("o").Op("*").Id(t.TypeName()),
|
||||
},
|
||||
jen.Commentf("%s calls %s on the %s type.", t.serializationFnName(), serializeMethodName, t.TypeName()))
|
||||
[]jen.Code{jen.Bool()},
|
||||
[]jen.Code{
|
||||
// TODO
|
||||
jen.Commentf("TODO: Less code for %s", t.TypeName()),
|
||||
},
|
||||
jen.Commentf("%s computes if this %s is lesser, with an arbitrary but stable determination", typeLessMethod, t.TypeName()))
|
||||
return
|
||||
}
|
||||
|
||||
// kindDeserializationFunc returns free function reference that can be used to
|
||||
// treat a TypeGenerator as another property's Kind.
|
||||
func (t *TypeGenerator) kindDeserializationFunc() (deser *codegen.Function) {
|
||||
deserCode := jen.Empty()
|
||||
for name, prop := range t.allProperties() {
|
||||
deserMethod := t.m.getPrivateDeserializationMethodForProperty(prop)
|
||||
|
@ -550,18 +543,5 @@ func (t *TypeGenerator) kindSerializationFuncs() (ser, deser, less *codegen.Func
|
|||
jen.Return(jen.Id(codegen.This()), jen.Nil()),
|
||||
},
|
||||
jen.Commentf("%s creates a %s from a map representation that has been unmarshalled from a text or binary format.", t.deserializationFnName(), t.TypeName()))
|
||||
less = codegen.NewCommentedFunction(
|
||||
t.PrivatePackage().Path(),
|
||||
t.lessFnName(),
|
||||
[]jen.Code{
|
||||
jen.Id("i"),
|
||||
jen.Id("j").Op("*").Id(t.TypeName()),
|
||||
},
|
||||
[]jen.Code{jen.Bool()},
|
||||
[]jen.Code{
|
||||
// TODO
|
||||
jen.Commentf("TODO: Less code for %s", t.TypeName()),
|
||||
},
|
||||
jen.Commentf("%s computes which %s is lesser, with an arbitrary but stable determination", t.lessFnName(), t.TypeName()))
|
||||
return
|
||||
}
|
||||
|
|
読み込み中…
新しいイシューから参照