Skip to content

Commit

Permalink
fix multiple fields with the same name issue
Browse files Browse the repository at this point in the history
  • Loading branch information
tsingbx committed Jan 15, 2025
1 parent 61c90ac commit af0c6b9
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 6 deletions.
19 changes: 16 additions & 3 deletions cmd/gogensig/convert/names/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,23 @@ func removePrefixedName(name string, trimPrefixes []string) string {
return name
}

func getSuffixUndercores(name string) string {
suffix := ""
for before, found := strings.CutSuffix(name, "_"); found; {
suffix += "_"
name = before
before, found = strings.CutSuffix(name, "_")
}
return suffix
}

func PubName(name string) string {
if len(name) == 0 {
return name
}

originSuffix := getSuffixUndercores(name)

toCamelCase := func(s string) string {
parts := strings.Split(s, "_")
for i := 0; i < len(parts); i++ {
Expand All @@ -93,11 +106,11 @@ func PubName(name string) string {
i++
}
prefix := name[:i]
return "X" + prefix + toCamelCase(name[i:])
return "X" + prefix + toCamelCase(name[i:]) + originSuffix
} else if unicode.IsDigit(rune(name[0])) {
return "X" + toCamelCase(name)
return "X" + toCamelCase(name) + originSuffix
}
return toCamelCase(name)
return toCamelCase(name) + originSuffix
}

// /path/to/foo.h -> foo.go
Expand Down
73 changes: 73 additions & 0 deletions cmd/gogensig/convert/names/names_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package names

import (
"testing"
)

func Test_getSuffixUndercores(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want string
}{
{
"_",
args{"_PyCfgBasicblock_"},
"_",
},
{
"__",
args{"_PyCfgBasicblock__"},
"__",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getSuffixUndercores(tt.args.name); got != tt.want {
t.Errorf("getSuffixUndercores() = %v, want %v", got, tt.want)
}
})
}
}

func TestPubName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want string
}{
{
"_name",
args{"_PyCfgBasicblock"},
"X_PyCfgBasicblock",
},
{
"_name_",
args{"_PyCfgBasicblock_"},
"X_PyCfgBasicblock_",
},
{
"_name__",
args{"_PyCfgBasicblock__"},
"X_PyCfgBasicblock__",
},
{
"__name__",
args{"__PyCfgBasicblock__"},
"X__PyCfgBasicblock__",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := PubName(tt.args.name); got != tt.want {
t.Errorf("PubName() = %v, want %v", got, tt.want)
}
})
}
}
44 changes: 42 additions & 2 deletions cmd/gogensig/convert/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,19 @@ func (p *TypeConv) fieldToVar(field *ast.Field, hasNamedParam bool, argIndex int
return types.NewVar(token.NoPos, p.Types, name, typ), nil
}

func (p *TypeConv) RecordTypeToStruct(recordType *ast.RecordType) (types.Type, error) {
func (p *TypeConv) newStruct(fields []*types.Var, tags []string) (retType types.Type, retError error) {
defer func() {
e := recover()
if e != nil {
fields = p.uniqueFields(fields)
retType = types.NewStruct(fields, nil)
}
}()
retType = types.NewStruct(fields, tags)
return retType, retError
}

func (p *TypeConv) RecordTypeToStruct(recordType *ast.RecordType) (retType types.Type, retError error) {
ctx := p.ctx
p.ctx = Record
defer func() { p.ctx = ctx }()
Expand All @@ -361,7 +373,35 @@ func (p *TypeConv) RecordTypeToStruct(recordType *ast.RecordType) (types.Type, e
fields = []*types.Var{maxFld}
}
}
return types.NewStruct(fields, nil), nil
return p.newStruct(fields, nil)
}

func genUniqueName(name string, index int, fieldMap map[string]struct{}) string {
newName := fmt.Sprintf("%s%d", name, index)
_, ok := fieldMap[newName]
if !ok {
return newName
}
return genUniqueName(name, index+1, fieldMap)
}

func (p *TypeConv) uniqueFields(fields []*types.Var) []*types.Var {
fieldMap := make(map[string]struct{})
newFields := make([]*types.Var, 0, len(fields))
for index, field := range fields {
name := field.Name()
_, ok := fieldMap[name]
if ok {
name = genUniqueName(field.Name(), index, fieldMap)
fieldVar := types.NewVar(token.NoPos, p.Types, name, field.Type())
newFields = append(newFields, fieldVar)
fieldMap[name] = struct{}{}
} else {
fieldMap[name] = struct{}{}
newFields = append(newFields, field)
}
}
return newFields
}

func (p *TypeConv) ToDefaultEnumType() types.Type {
Expand Down
2 changes: 1 addition & 1 deletion cmd/gogensig/gogensig.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func main() {
check(err)

err = runGoCmds(wd, conf.Name)
check(err)
fmt.Println(err)

p, _, err := basic.ConvertProcesser(&basic.Config{
AstConvertConfig: convert.AstConvertConfig{
Expand Down

0 comments on commit af0c6b9

Please sign in to comment.