Add IRI support and fix all build errors.
Generated code now will also compile, for the first time in forever!
このコミットが含まれているのは:
コミット
7ac133d101
|
@ -7,6 +7,10 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
iriMember = "iri"
|
||||
)
|
||||
|
||||
// FunctionalPropertyGenerator produces Go code for properties that can have
|
||||
// only one value. The resulting property is a struct type that can have one
|
||||
// value that could be from multiple Kinds of values. If there is only one
|
||||
|
@ -306,22 +310,32 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
|||
jen.Nil(),
|
||||
)},
|
||||
jen.Commentf("%s converts this into an interface representation suitable for marshalling into a text or binary format.", p.serializeFnName()))
|
||||
deserializeFns := jen.Empty()
|
||||
valueDeserializeFns := jen.Empty()
|
||||
typeDeserializeFns := jen.Empty()
|
||||
foundValue := false
|
||||
foundType := false
|
||||
for i, kind := range p.Kinds {
|
||||
if i > 0 {
|
||||
deserializeFns = deserializeFns.Else()
|
||||
}
|
||||
values := jen.Dict{
|
||||
jen.Id(p.memberName(i)): jen.Id("v"),
|
||||
}
|
||||
if !kind.Nilable {
|
||||
values[jen.Id(p.hasMemberName(i))] = jen.True()
|
||||
}
|
||||
deserializeFns = deserializeFns.If(
|
||||
tmp := jen.Empty()
|
||||
if kind.isValue() && foundValue {
|
||||
tmp = tmp.Else()
|
||||
} else if !kind.isValue() && foundType {
|
||||
tmp = tmp.Else()
|
||||
}
|
||||
variable := jen.Id("i")
|
||||
if !kind.isValue() {
|
||||
variable = jen.Id("m")
|
||||
}
|
||||
tmp = tmp.If(
|
||||
jen.List(
|
||||
jen.Id("v"),
|
||||
jen.Err(),
|
||||
).Op(":=").Add(kind.deserializeFnCode(jen.Id("i"))),
|
||||
).Op(":=").Add(kind.deserializeFnCode(variable)),
|
||||
jen.Err().Op("!=").Nil(),
|
||||
).Block(
|
||||
jen.Id(codegen.This()).Op(":=").Op("&").Id(p.StructName()).Values(
|
||||
|
@ -332,9 +346,15 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
|||
jen.Nil(),
|
||||
),
|
||||
)
|
||||
if kind.isValue() {
|
||||
foundValue = true
|
||||
valueDeserializeFns = valueDeserializeFns.Add(tmp)
|
||||
} else {
|
||||
foundType = true
|
||||
typeDeserializeFns = typeDeserializeFns.Add(tmp)
|
||||
}
|
||||
}
|
||||
var deserialize *codegen.Function
|
||||
// TODO: IRI Value
|
||||
if p.asIterator {
|
||||
deserialize = codegen.NewCommentedFunction(
|
||||
p.GetPrivatePackage().Path(),
|
||||
|
@ -342,19 +362,13 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
|||
[]jen.Code{jen.Id("i").Interface()},
|
||||
[]jen.Code{jen.Op("*").Id(p.StructName()), jen.Error()},
|
||||
[]jen.Code{
|
||||
p.addUnknownDeserializeCode(deserializeFns).Else().Block(
|
||||
jen.Return(
|
||||
jen.Nil(),
|
||||
jen.Qual("fmt", "Errorf").Call(
|
||||
jen.Lit("could not deserialize %q property"),
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
p.wrapDeserializeCode(valueDeserializeFns, typeDeserializeFns, false).Line().Return(
|
||||
jen.Nil(),
|
||||
jen.Qual("fmt", "Errorf").Call(
|
||||
jen.Lit("could not deserialize %q property"),
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
),
|
||||
jen.Return(
|
||||
jen.Nil(),
|
||||
jen.Nil(),
|
||||
),
|
||||
},
|
||||
jen.Commentf("%s creates an iterator from an element that has been unmarshalled from a text or binary format.", p.DeserializeFnName()))
|
||||
} else {
|
||||
|
@ -373,7 +387,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() (*codegen.Method, *co
|
|||
),
|
||||
jen.Id("ok"),
|
||||
).Block(
|
||||
p.addUnknownDeserializeCode(deserializeFns),
|
||||
p.wrapDeserializeCode(valueDeserializeFns, typeDeserializeFns, true),
|
||||
),
|
||||
jen.Return(
|
||||
jen.Nil(),
|
||||
|
@ -409,6 +423,7 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *codegen.Struct {
|
|||
}
|
||||
}
|
||||
kindMembers = append(kindMembers, p.unknownMemberDef())
|
||||
kindMembers = append(kindMembers, p.iriMemberDef())
|
||||
if p.HasNaturalLanguageMap {
|
||||
kindMembers = append(kindMembers, jen.Id(langMapMember).Map(jen.String()).String())
|
||||
}
|
||||
|
@ -596,6 +611,7 @@ func (p *FunctionalPropertyGenerator) multiTypeDef() *codegen.Struct {
|
|||
}
|
||||
}
|
||||
kindMembers = append(kindMembers, p.unknownMemberDef())
|
||||
kindMembers = append(kindMembers, p.iriMemberDef())
|
||||
if p.HasNaturalLanguageMap {
|
||||
kindMembers = append(kindMembers, jen.Id(langMapMember).Map(jen.String()).String())
|
||||
}
|
||||
|
@ -820,13 +836,58 @@ func (p *FunctionalPropertyGenerator) unknownMemberDef() jen.Code {
|
|||
return jen.Id(unknownMemberName).Index().Byte()
|
||||
}
|
||||
|
||||
// addUnknownDeserializeCode generates the "else if it's a []byte" code used for
|
||||
// deserializing unknown values.
|
||||
func (p *FunctionalPropertyGenerator) addUnknownDeserializeCode(existing jen.Code) *jen.Statement {
|
||||
if len(p.Kinds) > 0 {
|
||||
existing = jen.Add(existing, jen.Else())
|
||||
// iriMemberDef returns the definition of a struct member that handles
|
||||
// a property whose type is an IRI.
|
||||
func (p *FunctionalPropertyGenerator) iriMemberDef() jen.Code {
|
||||
return jen.Id(iriMember).Op("*").Qual("net/url", "URL")
|
||||
}
|
||||
|
||||
// wrapDeserializeCode generates the "else if it's a []byte" code and IRI code
|
||||
// used for deserializing unknown values.
|
||||
func (p *FunctionalPropertyGenerator) wrapDeserializeCode(valueExisting, typeExisting jen.Code, errorAtEnd bool) *jen.Statement {
|
||||
iriCode := jen.Empty()
|
||||
if !p.hasURIKind() {
|
||||
iriCode = jen.If(
|
||||
jen.List(
|
||||
jen.Id("s"),
|
||||
jen.Id("ok"),
|
||||
).Op(":=").Id("i").Assert(jen.String()),
|
||||
jen.Id("ok"),
|
||||
).Block(
|
||||
// IRI
|
||||
jen.List(
|
||||
jen.Id("u"),
|
||||
jen.Err(),
|
||||
).Op(":=").Qual("net/url", "Parse").Call(jen.Id("s")),
|
||||
jen.Commentf("If error exists, don't error out -- skip this and treat as unknown string ([]byte) at worst"),
|
||||
jen.If(jen.Err().Op("==").Nil()).Block(
|
||||
jen.Id(codegen.This()).Op(":=").Op("&").Id(p.StructName()).Values(
|
||||
jen.Dict{
|
||||
jen.Id(iriMember): jen.Id("u"),
|
||||
},
|
||||
),
|
||||
jen.Return(
|
||||
jen.Id(codegen.This()),
|
||||
jen.Nil(),
|
||||
),
|
||||
),
|
||||
).Line()
|
||||
}
|
||||
return jen.Add(existing,
|
||||
if p.hasTypeKind() {
|
||||
iriCode = iriCode.If(
|
||||
jen.List(
|
||||
jen.Id("m"),
|
||||
jen.Id("ok"),
|
||||
).Op(":=").Id("i").Assert(jen.Map(jen.String()).Interface()),
|
||||
jen.Id("ok"),
|
||||
).Block(
|
||||
typeExisting,
|
||||
).Else()
|
||||
}
|
||||
if p.hasValueKind() {
|
||||
iriCode = iriCode.Add(valueExisting).Else()
|
||||
}
|
||||
iriCode = iriCode.Add(
|
||||
jen.If(
|
||||
jen.List(
|
||||
jen.Id("v"),
|
||||
|
@ -847,4 +908,46 @@ func (p *FunctionalPropertyGenerator) addUnknownDeserializeCode(existing jen.Cod
|
|||
),
|
||||
),
|
||||
)
|
||||
if errorAtEnd {
|
||||
iriCode = iriCode.Else().Block(
|
||||
jen.Return(
|
||||
jen.Nil(),
|
||||
jen.Qual("fmt", "Errorf").Call(
|
||||
jen.Lit("could not deserialize %q property"),
|
||||
jen.Lit(p.PropertyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
return iriCode
|
||||
}
|
||||
|
||||
// hasURIKind returns true if this property already has a Kind that is a URI.
|
||||
func (p *FunctionalPropertyGenerator) hasURIKind() bool {
|
||||
for _, k := range p.Kinds {
|
||||
if k.IsURI {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// hasTypeKind returns true if this property has a Kind that is a type.
|
||||
func (p *FunctionalPropertyGenerator) hasTypeKind() bool {
|
||||
for _, k := range p.Kinds {
|
||||
if !k.isValue() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// hasValueKind returns true if this property has a Kind that is a Value.
|
||||
func (p *FunctionalPropertyGenerator) hasValueKind() bool {
|
||||
for _, k := range p.Kinds {
|
||||
if k.isValue() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -386,8 +386,9 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() (*codegen.Method,
|
|||
),
|
||||
jen.Err().Op("!=").Nil(),
|
||||
).Block(
|
||||
jen.Id("ret").Op(":=").Id(p.StructName()).Call(jen.Id(codegen.This())),
|
||||
jen.Return(
|
||||
jen.Id(codegen.This()),
|
||||
jen.Op("&").Id("ret"),
|
||||
jen.Err(),
|
||||
),
|
||||
).Else().If(
|
||||
|
@ -403,7 +404,7 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() (*codegen.Method,
|
|||
p.GetPrivatePackage().Path(),
|
||||
p.DeserializeFnName(),
|
||||
[]jen.Code{jen.Id("m").Map(jen.String()).Interface()},
|
||||
[]jen.Code{jen.Id(p.StructName()), jen.Error()},
|
||||
[]jen.Code{jen.Qual(p.GetPublicPackage().Path(), p.InterfaceName()), jen.Error()},
|
||||
[]jen.Code{
|
||||
jen.Var().Id(codegen.This()).Index().Op("*").Id(p.iteratorTypeName().CamelName),
|
||||
jen.If(
|
||||
|
@ -436,8 +437,9 @@ func (p *NonFunctionalPropertyGenerator) serializationFuncs() (*codegen.Method,
|
|||
deserializeFn("i"),
|
||||
),
|
||||
),
|
||||
jen.Id("ret").Op(":=").Id(p.StructName()).Call(jen.Id(codegen.This())),
|
||||
jen.Return(
|
||||
jen.Id(codegen.This()),
|
||||
jen.Op("&").Id("ret"),
|
||||
jen.Nil(),
|
||||
),
|
||||
},
|
||||
|
|
|
@ -87,7 +87,7 @@ type Kind struct {
|
|||
func (k Kind) lessFnCode(this, other *jen.Statement) *jen.Statement {
|
||||
// LessFn is nil case -- call comparison Less method directly on the LHS
|
||||
lessCall := this.Clone().Dot(compareLessMethod).Call(other.Clone())
|
||||
if k.LessFn != nil {
|
||||
if k.isValue() {
|
||||
// LessFn is indeed a function -- call this function
|
||||
lessCall = k.LessFn.Clone().Call(
|
||||
this.Clone(),
|
||||
|
@ -98,8 +98,7 @@ func (k Kind) lessFnCode(this, other *jen.Statement) *jen.Statement {
|
|||
}
|
||||
|
||||
func (k Kind) deserializeFnCode(this *jen.Statement) *jen.Statement {
|
||||
// LessFn is not nil, this means it is a value.
|
||||
if k.LessFn != nil {
|
||||
if k.isValue() {
|
||||
return k.DeserializeFn.Clone().Call(this)
|
||||
} else {
|
||||
// If LessFn is nil, this means it is a type. Which requires an
|
||||
|
@ -108,6 +107,13 @@ func (k Kind) deserializeFnCode(this *jen.Statement) *jen.Statement {
|
|||
}
|
||||
}
|
||||
|
||||
func (k Kind) isValue() bool {
|
||||
// LessFn is not nil, this means it is a value.
|
||||
// If LessFn is nil, this means it is a type. Types will have their
|
||||
// LessThan method called directly on the type.
|
||||
return k.LessFn != nil
|
||||
}
|
||||
|
||||
// PropertyGenerator is a common base struct used in both Functional and
|
||||
// NonFunctional ActivityStreams properties. It provides common naming patterns,
|
||||
// logic, and common Go code to be generated.
|
||||
|
|
|
@ -21,6 +21,7 @@ const (
|
|||
compareLessMethod = "LessThan"
|
||||
getUnknownMethod = "GetUnknownProperties"
|
||||
unknownMember = "unknown"
|
||||
getMethodFormat = "Get%s"
|
||||
)
|
||||
|
||||
// TypeInterface returns the Type Interface that is needed for ActivityStream
|
||||
|
@ -559,12 +560,16 @@ func (t *TypeGenerator) lessMethod() (less *codegen.Method) {
|
|||
jen.Commentf("Compare property %q", prop.PropertyName()).Line(),
|
||||
jen.If(
|
||||
jen.Id(codegen.This()).Dot(t.memberName(prop)).Dot(compareLessMethod).Call(
|
||||
jen.Id("o").Dot(t.memberName(prop)),
|
||||
jen.Id("o").Dot(
|
||||
fmt.Sprintf(getMethodFormat, t.memberName(prop)),
|
||||
).Call(),
|
||||
),
|
||||
).Block(
|
||||
jen.Return(jen.True()),
|
||||
).Else().If(
|
||||
jen.Id("o").Dot(t.memberName(prop)).Dot(compareLessMethod).Call(
|
||||
jen.Id("o").Dot(
|
||||
fmt.Sprintf(getMethodFormat, t.memberName(prop)),
|
||||
).Call().Dot(compareLessMethod).Call(
|
||||
jen.Id(codegen.This()).Dot(t.memberName(prop)),
|
||||
),
|
||||
).Block(
|
||||
|
@ -693,7 +698,7 @@ func (t *TypeGenerator) allGetters() (m []*codegen.Method) {
|
|||
for _, property := range t.allProperties() {
|
||||
m = append(m, codegen.NewCommentedValueMethod(
|
||||
t.PrivatePackage().Path(),
|
||||
fmt.Sprintf("Get%s", t.memberName(property)),
|
||||
fmt.Sprintf(getMethodFormat, t.memberName(property)),
|
||||
t.TypeName(),
|
||||
/*params=*/ nil,
|
||||
[]jen.Code{jen.Qual(property.GetPublicPackage().Path(), property.InterfaceName())},
|
||||
|
@ -702,7 +707,7 @@ func (t *TypeGenerator) allGetters() (m []*codegen.Method) {
|
|||
jen.Id(codegen.This()).Dot(t.memberName(property)),
|
||||
),
|
||||
},
|
||||
jen.Commentf("Get%s returns the %q property if it exists, and nil otherwise.", t.memberName(property), property.PropertyName())))
|
||||
jen.Commentf(getMethodFormat+" returns the %q property if it exists, and nil otherwise.", t.memberName(property), property.PropertyName())))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -719,7 +724,7 @@ func (t *TypeGenerator) allSetters() (m []*codegen.Method) {
|
|||
[]jen.Code{
|
||||
jen.Id(codegen.This()).Dot(t.memberName(property)).Op("=").Id("i"),
|
||||
},
|
||||
jen.Commentf("Get%s returns the %q property if it exists, and nil otherwise.", t.memberName(property), property.PropertyName())))
|
||||
jen.Commentf("Set%s returns the %q property if it exists, and nil otherwise.", t.memberName(property), property.PropertyName())))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
読み込み中…
新しいイシューから参照