Properly handle natural language map.
- Deserialization now happens correctly into the rdf:langString property. - Kluges to make sure the member is being set and referred to in the generation code. - No longer generate special member for natural language map nor a special Is method. Use the rdf:langString generated proeprties. - Keep the Set/Get special language members for handling individual languages.
このコミットが含まれているのは:
コミット
8a7ec8c3a9
@ -670,7 +670,7 @@ func (c *Converter) convertFunctionalProperty(p rdf.VocabularyProperty,
|
||||
if len(examples) > 0 {
|
||||
comment = fmt.Sprintf("%s\n\n%s", comment, strings.Join(examples, "\n\n"))
|
||||
}
|
||||
fp = gen.NewFunctionalPropertyGenerator(
|
||||
fp, e = gen.NewFunctionalPropertyGenerator(
|
||||
v.GetName(),
|
||||
v.URI,
|
||||
vocabNameToAlias(v.GetName()),
|
||||
@ -679,6 +679,9 @@ func (c *Converter) convertFunctionalProperty(p rdf.VocabularyProperty,
|
||||
comment,
|
||||
k,
|
||||
p.NaturalLanguageMap)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
e = backPopulateProperty(v.Registry, p, genRefs, fp)
|
||||
if e != nil {
|
||||
return
|
||||
@ -712,7 +715,7 @@ func (c *Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty,
|
||||
if len(examples) > 0 {
|
||||
comment = fmt.Sprintf("%s\n\n%s", comment, strings.Join(examples, "\n\n"))
|
||||
}
|
||||
nfp = gen.NewNonFunctionalPropertyGenerator(
|
||||
nfp, e = gen.NewNonFunctionalPropertyGenerator(
|
||||
v.GetName(),
|
||||
v.URI,
|
||||
vocabNameToAlias(v.GetName()),
|
||||
@ -721,6 +724,9 @@ func (c *Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty,
|
||||
comment,
|
||||
k,
|
||||
p.NaturalLanguageMap)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
e = backPopulateProperty(v.Registry, p, genRefs, nfp)
|
||||
if e != nil {
|
||||
return
|
||||
|
@ -34,7 +34,20 @@ func NewFunctionalPropertyGenerator(vocabName string,
|
||||
name Identifier,
|
||||
comment string,
|
||||
kinds []Kind,
|
||||
hasNaturalLanguageMap bool) *FunctionalPropertyGenerator {
|
||||
hasNaturalLanguageMap bool) (*FunctionalPropertyGenerator, error) {
|
||||
// Ensure that the natural language map has the langString kind.
|
||||
if hasNaturalLanguageMap {
|
||||
found := false
|
||||
for _, k := range kinds {
|
||||
if k.Name.LowerName == "langString" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, fmt.Errorf("Property has natural language map, but not an rdf:langString kind")
|
||||
}
|
||||
}
|
||||
return &FunctionalPropertyGenerator{
|
||||
PropertyGenerator: PropertyGenerator{
|
||||
vocabName: vocabName,
|
||||
@ -46,7 +59,7 @@ func NewFunctionalPropertyGenerator(vocabName string,
|
||||
comment: comment,
|
||||
kinds: kinds,
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InterfaceDefinition creates an interface definition in the provided package.
|
||||
@ -156,25 +169,6 @@ func (p *FunctionalPropertyGenerator) funcs() []*codegen.Method {
|
||||
),
|
||||
}
|
||||
if p.hasNaturalLanguageMap {
|
||||
// IsLanguageMap Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.GetPrivatePackage().Path(),
|
||||
isLanguageMapMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
[]jen.Code{jen.Bool()},
|
||||
[]jen.Code{
|
||||
jen.Return(jen.Id(codegen.This()).Dot(langMapMember).Op("!=").Nil()),
|
||||
},
|
||||
fmt.Sprintf(
|
||||
"%s determines if this property is represented by a natural language map. When true, use %s, %s, and %s methods to access and mutate the natural language map. The %s method can be used to clear the natural language map. Note that this method is only used for natural language representations, and does not determine the presence nor absence of other values for this property.",
|
||||
isLanguageMapMethod,
|
||||
hasLanguageMethod,
|
||||
getLanguageMethod,
|
||||
setLanguageMethod,
|
||||
p.clearMethodName(),
|
||||
)))
|
||||
// HasLanguage Method
|
||||
methods = append(methods,
|
||||
codegen.NewCommentedValueMethod(
|
||||
@ -366,6 +360,20 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
||||
typeDeserializeFns = typeDeserializeFns.Add(tmp)
|
||||
}
|
||||
}
|
||||
mapProperty := jen.Empty()
|
||||
if p.hasNaturalLanguageMap {
|
||||
mapProperty = jen.If(
|
||||
jen.Id("!ok"),
|
||||
).Block(
|
||||
jen.Commentf("Attempt to find the map instead."),
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Op("=").Id("m").Index(
|
||||
jen.Id("propName").Op("+").Lit("Map"),
|
||||
),
|
||||
)
|
||||
}
|
||||
var deserialize *codegen.Function
|
||||
if p.asIterator {
|
||||
deserialize = codegen.NewCommentedFunction(
|
||||
@ -384,13 +392,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
||||
).Block(
|
||||
jen.Id("alias").Op("=").Id("a"),
|
||||
),
|
||||
p.wrapDeserializeCode(valueDeserializeFns, typeDeserializeFns).Line().Return(
|
||||
jen.Nil(),
|
||||
jen.Qual("fmt", "Errorf").Call(
|
||||
jen.Lit("could not deserialize %q property"),
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
),
|
||||
p.wrapDeserializeCode(valueDeserializeFns, typeDeserializeFns),
|
||||
},
|
||||
fmt.Sprintf("%s creates an iterator from an element that has been unmarshalled from a text or binary format.", p.DeserializeFnName()))
|
||||
} else {
|
||||
@ -421,15 +423,14 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
),
|
||||
jen.If(
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Op(":=").Id("m").Index(
|
||||
jen.Id("propName"),
|
||||
),
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Block(
|
||||
).Op(":=").Id("m").Index(
|
||||
jen.Id("propName"),
|
||||
),
|
||||
mapProperty,
|
||||
jen.If(jen.Id("ok")).Block(
|
||||
p.wrapDeserializeCode(valueDeserializeFns, typeDeserializeFns),
|
||||
),
|
||||
jen.Return(
|
||||
@ -471,9 +472,6 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *codegen.Struct {
|
||||
}
|
||||
// TODO: Normalize alias of values when setting on this property.
|
||||
kindMembers = append(kindMembers, jen.Id(aliasMember).String())
|
||||
if p.hasNaturalLanguageMap {
|
||||
kindMembers = append(kindMembers, jen.Id(langMapMember).Map(jen.String()).String())
|
||||
}
|
||||
if p.asIterator {
|
||||
kindMembers = append(kindMembers, jen.Id(myIndexMemberName).Int())
|
||||
kindMembers = append(kindMembers, jen.Id(parentMemberName).Qual(p.GetPublicPackage().Path(), p.parentTypeInterfaceName()))
|
||||
@ -487,6 +485,7 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *codegen.Struct {
|
||||
methods = append(methods, p.singleTypeFuncs()...)
|
||||
methods = append(methods, p.funcs()...)
|
||||
methods = append(methods, p.commonMethods()...)
|
||||
methods = append(methods, p.nameMethod())
|
||||
return codegen.NewStruct(comment,
|
||||
p.StructName(),
|
||||
methods,
|
||||
@ -719,9 +718,6 @@ func (p *FunctionalPropertyGenerator) multiTypeDef() *codegen.Struct {
|
||||
kindMembers = append(kindMembers, p.iriMemberDef())
|
||||
}
|
||||
kindMembers = append(kindMembers, jen.Id(aliasMember).String())
|
||||
if p.hasNaturalLanguageMap {
|
||||
kindMembers = append(kindMembers, jen.Id(langMapMember).Map(jen.String()).String())
|
||||
}
|
||||
explanation := "At most, one type of value can be present, or none at all. Setting a value will clear the other types of values so that only one of the 'Is' methods will return true. It is possible to clear all values, so that this property is empty."
|
||||
comment := fmt.Sprintf(
|
||||
"%s is the functional property %q. It is permitted to be one of multiple value types. %s",
|
||||
@ -747,6 +743,7 @@ func (p *FunctionalPropertyGenerator) multiTypeDef() *codegen.Struct {
|
||||
methods = append(methods, p.multiTypeFuncs()...)
|
||||
methods = append(methods, p.funcs()...)
|
||||
methods = append(methods, p.commonMethods()...)
|
||||
methods = append(methods, p.nameMethod())
|
||||
return codegen.NewStruct(comment,
|
||||
p.StructName(),
|
||||
methods,
|
||||
@ -1150,3 +1147,34 @@ func (p *FunctionalPropertyGenerator) hasValueKind() bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// nameMethod returns the Name method for this functional property.
|
||||
func (p *FunctionalPropertyGenerator) nameMethod() *codegen.Method{
|
||||
nameImpl := jen.Return(
|
||||
jen.Lit(p.PropertyName()),
|
||||
)
|
||||
if p.hasNaturalLanguageMap {
|
||||
nameImpl = jen.If(
|
||||
jen.Id(codegen.This()).Dot(isLanguageMapMethod).Call(),
|
||||
).Block(
|
||||
jen.Return(
|
||||
jen.Lit(p.PropertyName() + "Map"),
|
||||
),
|
||||
).Else().Block(
|
||||
jen.Return(
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
)
|
||||
}
|
||||
return codegen.NewCommentedValueMethod(
|
||||
p.GetPrivatePackage().Path(),
|
||||
nameMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
[]jen.Code{jen.String()},
|
||||
[]jen.Code{
|
||||
nameImpl,
|
||||
},
|
||||
fmt.Sprintf("%s returns the name of this property: %q.", nameMethod, p.PropertyName()),
|
||||
)
|
||||
}
|
||||
|
@ -35,7 +35,20 @@ func NewNonFunctionalPropertyGenerator(vocabName string,
|
||||
name Identifier,
|
||||
comment string,
|
||||
kinds []Kind,
|
||||
hasNaturalLanguageMap bool) *NonFunctionalPropertyGenerator {
|
||||
hasNaturalLanguageMap bool) (*NonFunctionalPropertyGenerator, error) {
|
||||
// Ensure that the natural language map has the langString kind.
|
||||
if hasNaturalLanguageMap {
|
||||
found := false
|
||||
for _, k := range kinds {
|
||||
if k.Name.LowerName == "langString" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, fmt.Errorf("Property has natural language map, but not an rdf:langString kind")
|
||||
}
|
||||
}
|
||||
return &NonFunctionalPropertyGenerator{
|
||||
PropertyGenerator: PropertyGenerator{
|
||||
vocabName: vocabName,
|
||||
@ -47,7 +60,7 @@ func NewNonFunctionalPropertyGenerator(vocabName string,
|
||||
comment: comment,
|
||||
kinds: kinds,
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InterfaceDefinitions creates interface definitions in the provided package.
|
||||
@ -539,6 +552,7 @@ func (p *NonFunctionalPropertyGenerator) funcs() []*codegen.Method {
|
||||
},
|
||||
fmt.Sprintf("%s returns the JSONLD URIs required in the context string for this property and the specific values that are set. The value in the map is the alias used to import the property's value or values.", contextMethod)))
|
||||
methods = append(methods, p.commonMethods()...)
|
||||
methods = append(methods, p.nameMethod())
|
||||
return methods
|
||||
}
|
||||
|
||||
@ -621,6 +635,20 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() (*codegen.Method,
|
||||
),
|
||||
)
|
||||
}
|
||||
mapProperty := jen.Empty()
|
||||
if p.hasNaturalLanguageMap {
|
||||
mapProperty = jen.If(
|
||||
jen.Id("!ok"),
|
||||
).Block(
|
||||
jen.Commentf("Attempt to find the map instead."),
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Op("=").Id("m").Index(
|
||||
jen.Id("propName").Op("+").Lit("Map"),
|
||||
),
|
||||
)
|
||||
}
|
||||
deserialize := codegen.NewCommentedFunction(
|
||||
p.GetPrivatePackage().Path(),
|
||||
p.DeserializeFnName(),
|
||||
@ -647,13 +675,14 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() (*codegen.Method,
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
),
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Op(":=").Id("m").Index(
|
||||
jen.Id("propName"),
|
||||
),
|
||||
mapProperty,
|
||||
jen.If(
|
||||
jen.List(
|
||||
jen.Id("i"),
|
||||
jen.Id("ok"),
|
||||
).Op(":=").Id("m").Index(
|
||||
jen.Id("propName"),
|
||||
),
|
||||
jen.Id("ok"),
|
||||
).Block(
|
||||
jen.Id(codegen.This()).Op(":=").Op("&").Id(p.StructName()).Values(
|
||||
@ -717,3 +746,36 @@ func (p *NonFunctionalPropertyGenerator) thisIRI() *jen.Statement {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// nameMethod returns the Name method for this non-functional property.
|
||||
func (p *NonFunctionalPropertyGenerator) nameMethod() *codegen.Method{
|
||||
nameImpl := jen.Return(
|
||||
jen.Lit(p.PropertyName()),
|
||||
)
|
||||
if p.hasNaturalLanguageMap {
|
||||
nameImpl = jen.If(
|
||||
jen.Id(codegen.This()).Dot(lenMethod).Call().Op("==").Lit(1).Op(
|
||||
"&&",
|
||||
).Id(codegen.This()).Dot(atMethodName).Call(jen.Lit(0)).Dot(isLanguageMapMethod).Call(),
|
||||
).Block(
|
||||
jen.Return(
|
||||
jen.Lit(p.PropertyName() + "Map"),
|
||||
),
|
||||
).Else().Block(
|
||||
jen.Return(
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
)
|
||||
}
|
||||
return codegen.NewCommentedValueMethod(
|
||||
p.GetPrivatePackage().Path(),
|
||||
nameMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
[]jen.Code{jen.String()},
|
||||
[]jen.Code{
|
||||
nameImpl,
|
||||
},
|
||||
fmt.Sprintf("%s returns the name of this property: %q.", nameMethod, p.PropertyName()),
|
||||
)
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ const (
|
||||
nameMethod = "Name"
|
||||
serializeIteratorMethod = "serialize"
|
||||
deserializeIteratorMethod = "deserialize"
|
||||
isLanguageMapMethod = "IsLanguageMap"
|
||||
hasLanguageMethod = "HasLanguage"
|
||||
getLanguageMethod = "GetLanguage"
|
||||
setLanguageMethod = "SetLanguage"
|
||||
@ -45,7 +44,10 @@ const (
|
||||
contextMethod = "JSONLDContext"
|
||||
// Member names for generated code
|
||||
unknownMemberName = "unknown"
|
||||
langMapMember = "langMap"
|
||||
// Reference to the rdf:langString member! Kludge: both of these must be
|
||||
// kept in sync with the generated code.
|
||||
langMapMember = "langStringMember"
|
||||
isLanguageMapMethod = "IsLangString"
|
||||
// Kind Index constants
|
||||
iriKindIndex = -2
|
||||
noneOrUnknownKindIndex = -1
|
||||
@ -202,6 +204,12 @@ type PropertyGenerator struct {
|
||||
asIterator bool
|
||||
}
|
||||
|
||||
// HasNaturalLanguageMap returns whether this property has a natural language
|
||||
// map.
|
||||
func (p *PropertyGenerator) HasNaturalLanguageMap() bool {
|
||||
return p.hasNaturalLanguageMap
|
||||
}
|
||||
|
||||
// VocabName returns this property's vocabulary name.
|
||||
func (p *PropertyGenerator) VocabName() string {
|
||||
return p.vocabName
|
||||
@ -369,23 +377,7 @@ func (p *PropertyGenerator) clearMethodName() string {
|
||||
}
|
||||
|
||||
// commonMethods returns methods common to every property.
|
||||
func (p *PropertyGenerator) commonMethods() []*codegen.Method {
|
||||
// Name method
|
||||
m := []*codegen.Method{
|
||||
codegen.NewCommentedValueMethod(
|
||||
p.GetPrivatePackage().Path(),
|
||||
nameMethod,
|
||||
p.StructName(),
|
||||
/*params=*/ nil,
|
||||
[]jen.Code{jen.String()},
|
||||
[]jen.Code{
|
||||
jen.Return(
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
},
|
||||
fmt.Sprintf("%s returns the name of this property: %q.", nameMethod, p.PropertyName()),
|
||||
),
|
||||
}
|
||||
func (p *PropertyGenerator) commonMethods() (m []*codegen.Method) {
|
||||
if p.asIterator {
|
||||
// Next & Prev methods
|
||||
m = append(m, codegen.NewCommentedValueMethod(
|
||||
|
@ -82,6 +82,7 @@ type Property interface {
|
||||
InterfaceName() string
|
||||
SetKindFns(docName, idName string, kind *jen.Statement, deser *codegen.Method) error
|
||||
DeserializeFnName() string
|
||||
HasNaturalLanguageMap() bool
|
||||
}
|
||||
|
||||
// TypeGenerator represents an ActivityStream type definition to generate in Go.
|
||||
@ -780,6 +781,13 @@ func (t *TypeGenerator) deserializationFn() (deser *codegen.Function) {
|
||||
).Block(
|
||||
jen.Continue(),
|
||||
)
|
||||
if prop.HasNaturalLanguageMap() {
|
||||
knownProps = knownProps.Else().If(
|
||||
jen.Id("k").Op("==").Lit(prop.PropertyName() + "Map"),
|
||||
).Block(
|
||||
jen.Continue(),
|
||||
)
|
||||
}
|
||||
}
|
||||
knownProps = knownProps.Commentf("End: Code that ensures a property name is unknown").Line()
|
||||
unknownCode := jen.Commentf("Begin: Unknown deserialization").Line().For(
|
||||
|
@ -158,10 +158,11 @@ func (l *langstring) Exit(key string, ctx *ParsingContext) (bool, error) {
|
||||
// Apply sets the langstring value in the context as a referenced spec.
|
||||
func (l *langstring) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
|
||||
for k, p := range ctx.Result.Vocab.Properties {
|
||||
for _, ref := range p.Range {
|
||||
for i, ref := range p.Range {
|
||||
if ref.Name == langstringSpec && ref.Vocab == l.alias {
|
||||
p.NaturalLanguageMap = true
|
||||
ctx.Result.Vocab.Properties[k] = p
|
||||
p.Range = append(p.Range[:i], p.Range[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
読み込み中…
新しいイシューから参照
ユーザーをブロックする