fix(binapigen): Fix name conflict for union field constructors 02/28602/1
authorOndrej Fabry <ofabry@cisco.com>
Fri, 28 Aug 2020 18:42:20 +0000 (20:42 +0200)
committerOndrej Fabry <ofabry@cisco.com>
Fri, 28 Aug 2020 18:42:20 +0000 (20:42 +0200)
PROBLEM

Issue discovered in flow_types.api on master (20.09-rc0), where
generator encountered inconsistent naming for union type Flow,
causing name conflicts with their constructors.

SOLUTION

Previous cases of union types (address, punt) both contain suffix
"Union", thus generator now adds "Union" suffix it is not defined.
This way we won't break previously generated code for users.

Change-Id: Iffadc167774d66d8416fe36485782bb68ca2a70d
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
binapigen/binapigen.go
binapigen/generate.go

index 2dbd661..35a07d0 100644 (file)
@@ -271,7 +271,7 @@ func newUnion(gen *Generator, file *File, apitype vppapi.UnionType) *Union {
        typ := &Union{
                UnionType: apitype,
                GoIdent: GoIdent{
-                       GoName:       camelCaseName(apitype.Name),
+                       GoName:       withSuffix(camelCaseName(apitype.Name), "Union"),
                        GoImportPath: file.GoImportPath,
                },
        }
index 698c798..834c989 100644 (file)
@@ -285,8 +285,10 @@ func genUnion(g *GenFile, union *Union) {
 
        g.P("type ", union.GoName, " struct {")
 
+       // generate field comments
+       g.P("// ", union.GoName, " can be one of:")
        for _, field := range union.Fields {
-               g.P("// ", field.GoName, " *", getFieldType(g, field))
+               g.P("// ", field.GoName, " *", getFieldType(g, field))
        }
 
        // generate data field
@@ -299,22 +301,23 @@ func genUnion(g *GenFile, union *Union) {
 
        // generate methods for fields
        for _, field := range union.Fields {
-               genUnionFieldMethods(g, union.GoName, field)
+               genUnionField(g, union, field)
        }
        g.P()
 }
 
-func genUnionFieldMethods(g *GenFile, structName string, field *Field) {
-       getterStruct := fieldGoType(g, field)
+func genUnionField(g *GenFile, union *Union, field *Field) {
+       fieldType := fieldGoType(g, field)
+       constructorName := union.GoName + field.GoName
 
        // Constructor
-       g.P("func ", structName, field.GoName, "(a ", getterStruct, ") (u ", structName, ") {")
+       g.P("func ", constructorName, "(a ", fieldType, ") (u ", union.GoName, ") {")
        g.P("   u.Set", field.GoName, "(a)")
        g.P("   return")
        g.P("}")
 
        // Setter
-       g.P("func (u *", structName, ") Set", field.GoName, "(a ", getterStruct, ") {")
+       g.P("func (u *", union.GoName, ") Set", field.GoName, "(a ", fieldType, ") {")
        g.P("   buf := ", govppCodecPkg.Ident("NewBuffer"), "(u.", fieldUnionData, "[:])")
        encodeField(g, field, "a", func(name string) string {
                return "a." + name
@@ -322,16 +325,24 @@ func genUnionFieldMethods(g *GenFile, structName string, field *Field) {
        g.P("}")
 
        // Getter
-       g.P("func (u *", structName, ") Get", field.GoName, "() (a ", getterStruct, ") {")
+       g.P("func (u *", union.GoName, ") Get", field.GoName, "() (a ", fieldType, ") {")
        g.P("   buf := ", govppCodecPkg.Ident("NewBuffer"), "(u.", fieldUnionData, "[:])")
        decodeField(g, field, "a", func(name string) string {
                return "a." + name
        }, 0)
        g.P("   return")
        g.P("}")
+
        g.P()
 }
 
+func withSuffix(s string, suffix string) string {
+       if strings.HasSuffix(s, suffix) {
+               return s
+       }
+       return s + suffix
+}
+
 func genField(g *GenFile, fields []*Field, i int) {
        field := fields[i]