astool can handle colliding type and property names.

このコミットが含まれているのは:
Cory Slep 2019-02-09 21:23:17 +01:00
コミット f769e201b2
7個のファイルの変更239行の追加89行の削除

ファイルの表示

@ -399,7 +399,7 @@ func (c *Converter) convertVocabulary(p *rdf.ParsedVocabulary, refs map[string]*
v.Name = p.Vocab.Name
v.URI = p.Vocab.URI
for k, val := range p.Vocab.Values {
v.Values[k] = c.convertValue(val)
v.Values[k] = c.convertValue(p.Vocab.Name, val)
}
for k, prop := range p.Vocab.Properties {
if prop.Functional {
@ -735,7 +735,7 @@ func (c *Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty,
}
// convertValue turns a rdf.VocabularyValue into a Kind.
func (c *Converter) convertValue(v rdf.VocabularyValue) *gen.Kind {
func (c *Converter) convertValue(vocabName string, v rdf.VocabularyValue) *gen.Kind {
s := v.SerializeFn.CloneToPackage(c.vocabValuePackage(v).Path())
d := v.DeserializeFn.CloneToPackage(c.vocabValuePackage(v).Path())
l := v.LessFn.CloneToPackage(c.vocabValuePackage(v).Path())
@ -744,6 +744,7 @@ func (c *Converter) convertValue(v rdf.VocabularyValue) *gen.Kind {
id := toIdentifier(v)
return gen.NewKindForValue(id.LowerName,
id.CamelName,
vocabName,
v.DefinitionType,
v.IsNilable,
v.IsURI,
@ -773,7 +774,7 @@ func (c *Converter) propertyKinds(v rdf.VocabularyProperty,
return
} else {
id := toIdentifier(t)
kt := gen.NewKindForType(id.LowerName, id.CamelName)
kt := gen.NewKindForType(id.LowerName, id.CamelName, vocab.Name)
k = append(k, *kt)
}
} else {
@ -799,12 +800,12 @@ func (c *Converter) propertyKinds(v rdf.VocabularyProperty,
return
} else {
id := toIdentifier(t)
kt := gen.NewKindForType(id.LowerName, id.CamelName)
kt := gen.NewKindForType(id.LowerName, id.CamelName, refVocab.Name)
k = append(k, *kt)
}
} else {
// It is a Value of the vocabulary
k = append(k, *c.convertValue(val))
k = append(k, *c.convertValue(refVocab.Name, val))
}
}
}
@ -1160,6 +1161,7 @@ func (c *Converter) allExtendsAreIn(registry *rdf.RDFRegistry, t rdf.VocabularyT
// toFiles converts a vocabulary's types and properties to files.
func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
vName := strings.ToLower(v.Name)
for _, i := range v.FProps {
var pm *gen.PackageManager
pm, e = c.propertyPackageManager(i, v.Name)
@ -1172,7 +1174,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
file.Add(i.Definition().Definition())
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_property_%s.go", i.PropertyName()),
FileName: fmt.Sprintf("gen_property_%s_%s.go", vName, i.PropertyName()),
Directory: priv.WriteDir(),
})
// Interface
@ -1181,7 +1183,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
file.Add(i.InterfaceDefinition(pm.PublicPackage()).Definition())
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_property_%s_interface.go", i.PropertyName()),
FileName: fmt.Sprintf("gen_property_%s_%s_interface.go", vName, i.PropertyName()),
Directory: pub.WriteDir(),
})
}
@ -1199,7 +1201,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
file.Add(s.Definition()).Line().Add(t.Definition())
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_property_%s.go", i.PropertyName()),
FileName: fmt.Sprintf("gen_property_%s_%s.go", vName, i.PropertyName()),
Directory: priv.WriteDir(),
})
// Interface
@ -1210,7 +1212,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
}
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_property_%s_interface.go", i.PropertyName()),
FileName: fmt.Sprintf("gen_property_%s_%s_interface.go", vName, i.PropertyName()),
Directory: pub.WriteDir(),
})
}
@ -1227,7 +1229,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
file.Add(i.Definition().Definition())
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_type_%s.go", strings.ToLower(i.TypeName())),
FileName: fmt.Sprintf("gen_type_%s_%s.go", vName, strings.ToLower(i.TypeName())),
Directory: priv.WriteDir(),
})
// Interface
@ -1236,7 +1238,7 @@ func (c *Converter) toFiles(v vocabulary) (f []*File, e error) {
file.Add(i.InterfaceDefinition(pm.PublicPackage()).Definition())
f = append(f, &File{
F: file,
FileName: fmt.Sprintf("gen_type_%s_interface.go", strings.ToLower(i.TypeName())),
FileName: fmt.Sprintf("gen_type_%s_%s_interface.go", vName, strings.ToLower(i.TypeName())),
Directory: pub.WriteDir(),
})
}

ファイルの表示

@ -112,6 +112,57 @@
},
"name": "customproperty",
"url": "https://example.com/fake-vocabulary#dfn-customproperty"
},
{
"id": "https://example.com/fake-vocabulary#Update",
"type": "owl:Class",
"notes": "Collides with the ActivityStreams Update type.",
"subClassOf": {
"type": "owl:Class",
"url": "https://www.w3.org/TR/activitystreams-vocabulary/#dfn-activity",
"name": "as:Activity"
},
"disjointWith": [],
"name": "Update",
"url": "https://example.com/fake-vocabulary#dfn-update"
},
{
"id": "https://example.com/fake-vocabulary#accuracy",
"type": "rdf:Property",
"notes": "Collides with the ActivityStreams accuracy property",
"domain": {
"type": "owl:Class",
"unionOf": [
{
"type": "owl:Class",
"url": "https://www.w3.org/TR/activitystreams-vocabulary/#dfn-update",
"name": "as:Update"
},
{
"type": "owl:Class",
"url": "https://example.com/fake-vocabulary#dfn-update",
"name": "Update"
}
]
},
"isDefinedBy": "https://example.com/fake-vocabulary#dfn-accuracy",
"range": {
"type": "owl:Class",
"unionOf": [
{
"type": "owl:Class",
"url": "https://www.w3.org/TR/activitystreams-vocabulary/#dfn-update",
"name": "as:Update"
},
{
"type": "owl:Class",
"url": "https://example.com/fake-vocabulary#dfn-update",
"name": "Update"
}
]
},
"name": "accuracy",
"url": "https://example.com/fake-vocabulary#dfn-accuracy"
}
]
}

ファイルの表示

@ -5,6 +5,7 @@ import (
"github.com/dave/jennifer/jen"
"github.com/go-fed/activity/astool/codegen"
"net/url"
"strings"
"sync"
)
@ -104,7 +105,7 @@ func (p *NonFunctionalPropertyGenerator) Definitions() (*codegen.Struct, *codege
// iteratorInterfaceName gets the interface name for the iterator.
func (p *NonFunctionalPropertyGenerator) iteratorInterfaceName() string {
return fmt.Sprintf("%sInterface", p.iteratorTypeName().CamelName)
return fmt.Sprintf("%s", strings.Title(p.iteratorTypeName().CamelName))
}
// elementTypeGenerator produces a FunctionalPropertyGenerator for the iterator
@ -143,7 +144,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
prependDict[k] = v
}
prependDict[jen.Id(myIndexMemberName)] = jen.Lit(0)
prependMethodName := fmt.Sprintf("%s%s", prependMethod, p.kindCamelName(i))
prependMethodName := fmt.Sprintf("%s%s%s", prependMethod, kind.Vocab, p.kindCamelName(i))
methods = append(methods,
codegen.NewCommentedPointerMethod(
p.GetPrivatePackage().Path(),
@ -175,7 +176,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
appendDict[k] = v
}
appendDict[jen.Id(myIndexMemberName)] = jen.Id(codegen.This()).Dot(lenMethod).Call()
appendMethodName := fmt.Sprintf("%s%s", appendMethod, p.kindCamelName(i))
appendMethodName := fmt.Sprintf("%s%s%s", appendMethod, kind.Vocab, p.kindCamelName(i))
methods = append(methods,
codegen.NewCommentedPointerMethod(
p.GetPrivatePackage().Path(),

ファイルの表示

@ -469,7 +469,7 @@ func genInit(pkg Package,
func toPublicConstructor(vocabName string, m *ManagerGenerator, pg *PropertyGenerator) *codegen.Function {
return codegen.NewCommentedFunction(
m.pkg.Path(),
fmt.Sprintf("New%s%s", vocabName, pg.StructName()),
fmt.Sprintf("New%s%sProperty", vocabName, strings.Title(pg.PropertyName())),
/*params=*/ nil,
[]jen.Code{jen.Qual(pg.GetPublicPackage().Path(), pg.InterfaceName())},
[]jen.Code{

ファイルの表示

@ -46,8 +46,8 @@ const (
unknownMemberName = "unknown"
// Reference to the rdf:langString member! Kludge: both of these must be
// kept in sync with the generated code.
langMapMember = "langStringMember"
isLanguageMapMethod = "IsLangString"
langMapMember = "rdfLangStringMember"
isLanguageMapMethod = "IsRDFLangString"
// Kind Index constants
iriKindIndex = -2
noneOrUnknownKindIndex = -1
@ -82,7 +82,8 @@ type Identifier struct {
//
// Only represents values and other types.
type Kind struct {
Name Identifier
Name Identifier
Vocab string
// ConcreteKind is expected to be properly qualified.
ConcreteKind *jen.Statement
Nilable bool
@ -106,7 +107,7 @@ type Kind struct {
}
// NewKindForValue creates a Kind for a value type.
func NewKindForValue(docName, idName string,
func NewKindForValue(docName, idName, vocab string,
defType *jen.Statement,
isNilable, isURI bool,
serializeFn, deserializeFn, lessFn *codegen.Function) *Kind {
@ -115,6 +116,7 @@ func NewKindForValue(docName, idName string,
LowerName: docName,
CamelName: idName,
},
Vocab: vocab,
ConcreteKind: defType,
Nilable: isNilable,
IsURI: isURI,
@ -128,7 +130,7 @@ func NewKindForValue(docName, idName string,
}
// NewKindForType creates a Kind for an ActivitySteams type.
func NewKindForType(docName, idName string) *Kind {
func NewKindForType(docName, idName, vocab string) *Kind {
return &Kind{
// Name must use toIdentifier for vocabValuePackage and
// valuePackage to be the same.
@ -136,6 +138,7 @@ func NewKindForType(docName, idName string) *Kind {
LowerName: docName,
CamelName: idName,
},
Vocab: vocab,
Nilable: true,
IsURI: false,
// Instead of populating:
@ -236,9 +239,9 @@ func (p *PropertyGenerator) GetPublicPackage() Package {
// The name parameter must match the LowerName of an Identifier.
//
// This feels very hacky.
func (p *PropertyGenerator) SetKindFns(docName, idName string, qualKind *jen.Statement, deser *codegen.Method) error {
func (p *PropertyGenerator) SetKindFns(docName, idName, vocab string, qualKind *jen.Statement, deser *codegen.Method) error {
for i, kind := range p.kinds {
if kind.Name.LowerName == docName {
if kind.Name.LowerName == docName && kind.Vocab == vocab {
if kind.SerializeFn != nil || kind.DeserializeFn != nil || kind.LessFn != nil {
return fmt.Errorf("property kind already has serialization functions set for %q: %s", docName, p.PropertyName())
}
@ -252,7 +255,7 @@ func (p *PropertyGenerator) SetKindFns(docName, idName string, qualKind *jen.Sta
// In the case of extended types applying themselves to their parents'
// range, they will be missing from the property's kinds list. Append a
// new kind to handle this use case.
k := NewKindForType(docName, idName)
k := NewKindForType(docName, idName, vocab)
k.ConcreteKind = qualKind
k.DeserializeFn = deser.On(managerInitName())
p.managerMethods = append(p.managerMethods, deser)
@ -272,26 +275,27 @@ func (p *PropertyGenerator) StructName() string {
if p.asIterator {
return p.name.CamelName
}
return fmt.Sprintf("%sProperty", p.name.CamelName)
return fmt.Sprintf("%s%sProperty", p.VocabName(), p.name.CamelName)
}
// iteratorTypeName determines the identifier to use for the iterator type.
func (p *PropertyGenerator) iteratorTypeName() Identifier {
s := fmt.Sprintf("%s%s", p.VocabName(), p.name.CamelName)
return Identifier{
LowerName: p.name.LowerName,
CamelName: fmt.Sprintf("%sPropertyIterator", p.name.CamelName),
LowerName: s,
CamelName: fmt.Sprintf("%sPropertyIterator", s),
}
}
// InterfaceName returns the interface name of the property type.
func (p *PropertyGenerator) InterfaceName() string {
return fmt.Sprintf("%sInterface", p.StructName())
return fmt.Sprintf("%s", p.StructName())
}
// parentTypeInterfaceName is useful for iterators that need the base property
// type's interface name.
func (p *PropertyGenerator) parentTypeInterfaceName() string {
return fmt.Sprintf("%sInterface", strings.TrimSuffix(p.StructName(), "Iterator"))
return fmt.Sprintf("%s", strings.TrimSuffix(p.StructName(), "Iterator"))
}
// PropertyName returns the name of this property, as defined in
@ -321,7 +325,7 @@ func (p *PropertyGenerator) getFnName(i int) string {
if len(p.kinds) == 1 {
return getMethod
}
return fmt.Sprintf("%s%s", getMethod, p.kindCamelName(i))
return fmt.Sprintf("%s%s%s", getMethod, p.kinds[i].Vocab, p.kindCamelName(i))
}
// setFnName returns the identifier of the function that sets concrete types
@ -330,7 +334,7 @@ func (p *PropertyGenerator) setFnName(i int) string {
if len(p.kinds) == 1 {
return setMethod
}
return fmt.Sprintf("%s%s", setMethod, p.kindCamelName(i))
return fmt.Sprintf("%s%s%s", setMethod, p.kinds[i].Vocab, p.kindCamelName(i))
}
// serializeFnName returns the identifier of the function that serializes the
@ -354,7 +358,9 @@ func (p *PropertyGenerator) kindCamelName(i int) string {
//
// It will panic if 'i' is out of range.
func (p *PropertyGenerator) memberName(i int) string {
return fmt.Sprintf("%sMember", p.kinds[i].Name.LowerName)
k := p.kinds[i]
v := strings.ToLower(k.Vocab)
return fmt.Sprintf("%s%sMember", v, k.Name.CamelName)
}
// hasMemberName returns the identifier to use for struct members that determine
@ -423,7 +429,7 @@ func (p *PropertyGenerator) commonMethods() (m []*codegen.Method) {
// isMethodName returns the identifier to use for methods that determine if a
// property holds a specific Kind of value.
func (p *PropertyGenerator) isMethodName(i int) string {
return fmt.Sprintf("%s%s", isMethod, p.kindCamelName(i))
return fmt.Sprintf("%s%s%s", isMethod, p.kinds[i].Vocab, p.kindCamelName(i))
}
// ConstructorFn creates a constructor function with a default vocabulary

ファイルの表示

@ -231,10 +231,55 @@ func (r *ResolverGenerator) isUnFn() *codegen.Function {
// jsonResolverMethods returns the methods for the TypeResolver.
func (r *ResolverGenerator) jsonResolverMethods() (m []*codegen.Method) {
aliasToId := make(map[string]string)
aliasFetching := jen.Empty()
impl := jen.Empty()
for _, t := range r.types {
impl = impl.Case(
jen.Lit(t.TypeName()),
for i, t := range r.types {
if i > 0 {
impl = impl.Else()
}
// Get the vocab URI in http and https forms
vocabHttps := *t.vocabURI
vocabHttps.Scheme = "https"
vocabHttp := vocabHttps
vocabHttp.Scheme = "http"
// Determine if we've already generated the code for fetching
// the alias for this vocabulary.
if _, ok := aliasToId[vocabHttps.String()]; !ok {
// If not, generate the code.
vocabId := t.vocabName + "Alias"
aliasToId[vocabHttps.String()] = vocabId
aliasFetching = aliasFetching.Add(
jen.List(
jen.Id(vocabId),
jen.Id("ok"),
).Op(":=").Id("aliasMap").Index(
jen.Lit(vocabHttps.String()),
),
).Line().Add(
jen.If(
jen.Op("!").Id("ok"),
).Block(
jen.List(
jen.Id(vocabId),
jen.Id("_"),
).Op("=").Id("aliasMap").Index(
jen.Lit(vocabHttp.String()),
),
),
).Line().Add(
// If it is not empty post-pend with a ":".
jen.If(
jen.Len(jen.Id(vocabId)).Op(">").Lit(0),
).Block(
jen.Id(vocabId).Op("+=").Lit(":"),
),
).Line()
}
// Fetch the identifier holding the alias for this vocabulary,
aliasId := aliasToId[vocabHttps.String()]
impl = impl.If(
jen.Id("typeString").Op("==").Id(aliasId).Op("+").Lit(t.TypeName()),
).Block(
jen.List(
jen.Id("v"),
@ -276,7 +321,7 @@ func (r *ResolverGenerator) jsonResolverMethods() (m []*codegen.Method) {
jen.Return(
jen.Id(errorNoMatch),
),
).Line()
)
}
m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(),
@ -321,11 +366,10 @@ func (r *ResolverGenerator) jsonResolverMethods() (m []*codegen.Method) {
jen.Id("handleFn").Op(":=").Func().Parens(
jen.Id("typeString").String(),
).Error().Block(
jen.Switch(jen.Id("typeString")).Block(
impl.Default().Block(
jen.Return(
jen.Id(errorUnhandled),
),
aliasFetching,
impl.Else().Block(
jen.Return(
jen.Id(errorUnhandled),
),
),
),
@ -393,9 +437,14 @@ func (r *ResolverGenerator) jsonResolverMethods() (m []*codegen.Method) {
// typeResolverMethods returns the methods for the TypeResolver.
func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) {
impl := jen.Empty()
for _, t := range r.types {
impl = impl.Case(
jen.Lit(t.TypeName()),
for i, t := range r.types {
if i > 0 {
impl = impl.Else()
}
impl = impl.If(
jen.Id("o").Dot(vocabURIMethod).Call().Op("==").Lit(t.vocabURI.String()).Op(
"&&",
).Id("o").Dot(typeNameMethod).Call().Op("==").Lit(t.TypeName()),
).Block(
jen.If(
jen.List(
@ -430,7 +479,7 @@ func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) {
),
),
),
).Line()
)
}
m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(),
@ -450,11 +499,9 @@ func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) {
jen.Id("i"),
).Op(":=").Range().Id(codegen.This()).Dot(callbackMember),
).Block(
jen.Switch(jen.Id("o").Dot(typeNameMethod).Call()).Block(
impl.Default().Block(
jen.Return(
jen.Id(errorUnhandled),
),
impl.Else().Block(
jen.Return(
jen.Id(errorUnhandled),
),
),
),
@ -469,9 +516,14 @@ func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) {
// typePredicatedResolverMethods returns the methods for the TypePredicatedResolver.
func (r *ResolverGenerator) typePredicatedResolverMethods() (m []*codegen.Method) {
impl := jen.Empty()
for _, t := range r.types {
impl = impl.Case(
jen.Lit(t.TypeName()),
for i, t := range r.types {
if i > 0 {
impl = impl.Else()
}
impl = impl.If(
jen.Id("o").Dot(vocabURIMethod).Call().Op("==").Lit(t.vocabURI.String()).Op(
"&&",
).Id("o").Dot(typeNameMethod).Call().Op("==").Lit(t.TypeName()),
).Block(
jen.If(
jen.List(
@ -518,7 +570,7 @@ func (r *ResolverGenerator) typePredicatedResolverMethods() (m []*codegen.Method
jen.Id(errorPredicateUnmatched),
),
),
).Line()
)
}
m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(),
@ -535,12 +587,10 @@ func (r *ResolverGenerator) typePredicatedResolverMethods() (m []*codegen.Method
[]jen.Code{
jen.Var().Id("predicatePasses").Bool(),
jen.Var().Err().Error(),
jen.Switch(jen.Id("o").Dot(typeNameMethod).Call()).Block(
impl.Default().Block(
jen.Return(
jen.False(),
jen.Id(errorUnhandled),
),
impl.Else().Block(
jen.Return(
jen.False(),
jen.Id(errorUnhandled),
),
),
jen.If(
@ -726,6 +776,12 @@ func (r *ResolverGenerator) asInterface() *codegen.Interface {
Ret: []jen.Code{jen.String()},
Comment: fmt.Sprintf("%s returns the ActiivtyStreams value's type.", typeNameMethod),
},
{
Name: vocabURIMethod,
Params: nil,
Ret: []jen.Code{jen.String()},
Comment: fmt.Sprintf("%s returns the vocabulary's URI as a string.", vocabURIMethod),
},
},
fmt.Sprintf("%s represents any ActivityStream value code-generated by go-fed or compatible with the generated interfaces.", activityStreamInterface))
}

ファイルの表示

@ -12,7 +12,7 @@ import (
const (
typeInterfaceName = "Type"
typeMember = "Type" // This specifically must match the "type" property member generated! Kludge that this happens to just work.
typeMember = "ActivityStreamsType" // This specifically must match the "type" property member generated! Kludge that this happens to just work.
typePropertyConstructor = "typePropertyConstructor"
jsonLDContextInterfaceName = "jsonldContexter"
extendedByMethod = "IsExtendedBy"
@ -20,6 +20,7 @@ const (
extendsMethod = "Extends"
disjointWithMethod = "IsDisjointWith"
typeNameMethod = "GetName"
vocabURIMethod = "VocabularyURI"
serializeMethodName = "Serialize"
deserializeFnName = "Deserialize"
compareLessMethod = "LessThan"
@ -48,6 +49,12 @@ func TypeInterface(pkg Package) *codegen.Interface {
Ret: []jen.Code{jen.String()},
Comment: fmt.Sprintf("%s returns the ActivityStreams type name.", typeNameMethod),
},
{
Name: vocabURIMethod,
Params: nil,
Ret: []jen.Code{jen.String()},
Comment: fmt.Sprintf("%s returns the vocabulary's URI as a string.", vocabURIMethod),
},
}
return codegen.NewInterface(pkg.Path(), typeInterfaceName, funcs, comment)
}
@ -77,10 +84,12 @@ func ContextInterface(pkg Package) *codegen.Interface {
// Property represents a property of an ActivityStreams type.
type Property interface {
VocabName() string
GetPublicPackage() Package
PropertyName() string
StructName() string
InterfaceName() string
SetKindFns(docName, idName string, kind *jen.Statement, deser *codegen.Method) error
SetKindFns(docName, idName, vocab string, kind *jen.Statement, deser *codegen.Method) error
DeserializeFnName() string
HasNaturalLanguageMap() bool
}
@ -150,10 +159,10 @@ func NewTypeGenerator(vocabName string,
}
}
for _, wop := range withoutProperties {
if _, has := t.withoutProperties[wop.PropertyName()]; has {
return nil, fmt.Errorf("type already has withoutproperty with name %q", wop.PropertyName())
if _, has := t.withoutProperties[wop.StructName()]; has {
return nil, fmt.Errorf("type already has withoutproperty with name %q", wop.StructName())
}
t.withoutProperties[wop.PropertyName()] = wop
t.withoutProperties[wop.StructName()] = wop
}
// Complete doubly-linked extends/extendedBy lists.
for _, ext := range extends {
@ -169,10 +178,10 @@ func NewTypeGenerator(vocabName string,
// AddPropertyGenerator adds a property generator to this type. It must be
// called before Definition is called.
func (t *TypeGenerator) AddPropertyGenerator(property Property) error {
if _, has := t.properties[property.PropertyName()]; has {
return fmt.Errorf("type already has property with name %q", property.PropertyName())
if _, has := t.properties[property.StructName()]; has {
return fmt.Errorf("type already has property with name %q", property.StructName())
}
t.properties[property.PropertyName()] = property
t.properties[property.StructName()] = property
return nil
}
@ -206,7 +215,7 @@ func (t *TypeGenerator) apply(m *ManagerGenerator) error {
continue
}
// Kluge: convert.toIdentifier must match this!
if e := p.SetKindFns(t.TypeName(), strings.Title(t.TypeName()), kind, deser); e != nil {
if e := p.SetKindFns(t.TypeName(), strings.Title(t.TypeName()), t.vocabName, kind, deser); e != nil {
return e
}
propsSet[p] = true
@ -249,9 +258,14 @@ func (t *TypeGenerator) TypeName() string {
return t.typeName
}
// StructName returns the Go name for this type.
func (t *TypeGenerator) StructName() string {
return fmt.Sprintf("%s%s", t.VocabName(), t.typeName)
}
// InterfaceName returns the interface name for this type.
func (t *TypeGenerator) InterfaceName() string {
return fmt.Sprintf("%sInterface", t.TypeName())
return fmt.Sprintf("%s", t.StructName())
}
// Extends returns the generators of types that this ActivityStreams type
@ -287,7 +301,7 @@ func (t *TypeGenerator) WithoutProperties() map[string]Property {
// extendsFnName determines the name of the Extends function, which
// determines if this ActivityStreams type extends another one.
func (t *TypeGenerator) extendsFnName() string {
return fmt.Sprintf("%s%s", t.TypeName(), extendsMethod)
return fmt.Sprintf("%s%s", t.StructName(), extendsMethod)
}
// extendedByFnName determines the name of the ExtendedBy function, which
@ -332,10 +346,11 @@ func (t *TypeGenerator) Definition() *codegen.Struct {
ctxMethods := t.contextMethods()
t.cachedStruct = codegen.NewStruct(
t.Comments(),
t.TypeName(),
t.StructName(),
append(append(append(
[]*codegen.Method{
t.nameDefinition(),
t.vocabURIDefinition(),
extendsMethod,
ser,
less,
@ -410,7 +425,10 @@ func (t *TypeGenerator) allProperties() []Property {
// memberName returns the member name for this property.
func (*TypeGenerator) memberName(p Property) string {
return strings.Title(p.PropertyName())
return fmt.Sprintf(
"%s%s",
p.VocabName(),
strings.Title(p.PropertyName()))
}
// members returns all the properties this type has as its members.
@ -433,7 +451,7 @@ func (t *TypeGenerator) nameDefinition() *codegen.Method {
return codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
typeNameMethod,
t.TypeName(),
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.String()},
[]jen.Code{
@ -442,6 +460,22 @@ func (t *TypeGenerator) nameDefinition() *codegen.Method {
fmt.Sprintf("%s returns the name of this type.", typeNameMethod))
}
// vocabURIDefinition generates the golang method for returning this type's
// vocabulary URI as a string.
func (t *TypeGenerator) vocabURIDefinition() *codegen.Method {
return codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
vocabURIMethod,
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.String()},
[]jen.Code{
jen.Return(jen.Lit(t.vocabURI.String())),
},
fmt.Sprintf("%s returns the vocabulary's URI as a string.", vocabURIMethod))
}
// getAllParentExtends recursively determines all the parent types that this
// type extends from.
func (t *TypeGenerator) getAllParentExtends(s map[*TypeGenerator]string, tg *TypeGenerator) map[*TypeGenerator]string {
@ -495,7 +529,7 @@ func (t *TypeGenerator) extendsDefinition() (*codegen.Function, *codegen.Method)
m := codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
extendingMethod,
t.TypeName(),
t.StructName(),
[]jen.Code{jen.Id("other").Qual(t.PublicPackage().Path(), typeInterfaceName)},
[]jen.Code{jen.Bool()},
[]jen.Code{
@ -646,7 +680,7 @@ func (t *TypeGenerator) serializationMethod() (ser *codegen.Method) {
ser = codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
serializeMethodName,
t.TypeName(),
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.Map(jen.String()).Interface(), jen.Error()},
[]jen.Code{
@ -734,7 +768,7 @@ func (t *TypeGenerator) lessMethod() (less *codegen.Method) {
less = codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
compareLessMethod,
t.TypeName(),
t.StructName(),
[]jen.Code{
jen.Id("o").Qual(t.PublicPackage().Path(), t.InterfaceName()),
},
@ -803,7 +837,7 @@ func (t *TypeGenerator) deserializationFn() (deser *codegen.Function) {
t.PrivatePackage().Path(),
t.deserializationFnName(),
[]jen.Code{jen.Id("m").Map(jen.String()).Interface(), jen.Id("aliasMap").Map(jen.String()).String()},
[]jen.Code{jen.Op("*").Id(t.TypeName()), jen.Error()},
[]jen.Code{jen.Op("*").Id(t.StructName()), jen.Error()},
[]jen.Code{
jen.Id("alias").Op(":=").Lit(""),
jen.Id("aliasPrefix").Op(":=").Lit(""),
@ -817,7 +851,7 @@ func (t *TypeGenerator) deserializationFn() (deser *codegen.Function) {
jen.Id("alias").Op("=").Id("a"),
jen.Id("aliasPrefix").Op("=").Id("a").Op("+").Lit(":"),
),
jen.Id(codegen.This()).Op(":=").Op("&").Id(t.TypeName()).Values(jen.Dict{
jen.Id(codegen.This()).Op(":=").Op("&").Id(t.StructName()).Values(jen.Dict{
jen.Id(aliasMember): jen.Id("alias"),
jen.Id(unknownMember): jen.Make(jen.Map(jen.String()).Interface()),
}),
@ -910,7 +944,7 @@ func (t *TypeGenerator) getUnknownMethod() (get *codegen.Method) {
get = codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
getUnknownMethod,
t.TypeName(),
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.Map(jen.String()).Interface()},
[]jen.Code{
@ -929,7 +963,7 @@ func (t *TypeGenerator) allGetters() (m []*codegen.Method) {
m = append(m, codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
fmt.Sprintf(getMethodFormat, t.memberName(property)),
t.TypeName(),
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.Qual(property.GetPublicPackage().Path(), property.InterfaceName())},
[]jen.Code{
@ -948,7 +982,7 @@ func (t *TypeGenerator) allSetters() (m []*codegen.Method) {
m = append(m, codegen.NewCommentedPointerMethod(
t.PrivatePackage().Path(),
fmt.Sprintf("Set%s", t.memberName(property)),
t.TypeName(),
t.StructName(),
[]jen.Code{jen.Id("i").Qual(property.GetPublicPackage().Path(), property.InterfaceName())},
/*ret=*/ nil,
[]jen.Code{
@ -972,16 +1006,16 @@ func (t *TypeGenerator) getAllManagerMethods() (m []*codegen.Method) {
func (t *TypeGenerator) constructorFn() *codegen.Function {
return codegen.NewCommentedFunction(
t.PrivatePackage().Path(),
fmt.Sprintf("%s%s", constructorName, t.TypeName()),
fmt.Sprintf("%s%s", constructorName, t.StructName()),
/*params=*/ nil,
[]jen.Code{
jen.Op("*").Qual(t.PrivatePackage().Path(), t.TypeName()),
jen.Op("*").Qual(t.PrivatePackage().Path(), t.StructName()),
},
[]jen.Code{
jen.Id("typeProp").Op(":=").Id(typePropertyConstructorName()).Call(),
jen.Id("typeProp").Dot("AppendString").Call(jen.Lit(t.TypeName())),
jen.Id("typeProp").Dot("AppendXMLSchemaString").Call(jen.Lit(t.TypeName())),
jen.Return(
jen.Op("&").Qual(t.PrivatePackage().Path(), t.TypeName()).Values(
jen.Op("&").Qual(t.PrivatePackage().Path(), t.StructName()).Values(
jen.Dict{
jen.Id(aliasMember): jen.Lit(t.vocabAlias),
jen.Id(unknownMember): jen.Make(jen.Map(jen.String()).Interface(), jen.Lit(0)),
@ -990,7 +1024,7 @@ func (t *TypeGenerator) constructorFn() *codegen.Function {
),
),
},
fmt.Sprintf("%s%s creates a new %s type", constructorName, t.TypeName(), t.TypeName()))
fmt.Sprintf("%s%s creates a new %s type", constructorName, t.StructName(), t.TypeName()))
}
// contextMethod returns a map of the context's vocabulary
@ -999,7 +1033,7 @@ func (t *TypeGenerator) contextMethods() []*codegen.Method {
helper := codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
helperName,
t.TypeName(),
t.StructName(),
[]jen.Code{jen.Id("i").Id(jsonLDContextInterfaceName), jen.Id("toMerge").Map(jen.String()).String()},
[]jen.Code{jen.Map(jen.String()).String()},
[]jen.Code{
@ -1034,7 +1068,7 @@ func (t *TypeGenerator) contextMethods() []*codegen.Method {
ctxMethod := codegen.NewCommentedValueMethod(
t.PrivatePackage().Path(),
contextMethod,
t.TypeName(),
t.StructName(),
/*params=*/ nil,
[]jen.Code{jen.Map(jen.String()).String()},
[]jen.Code{