Skip to content

Commit cc08cbc

Browse files
committed
fix(codegen): GoDefine 支持指针等类型
1 parent 0a1c678 commit cc08cbc

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

codegen/object.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,13 @@ func GoDefine(t reflect.Type, m map[reflect.Type]string, unexported bool) string
2828
goDefine(buf, 0, t, m, unexported, false)
2929
s := buf.String()
3030

31-
if len(s) > 0 && s[0] == '{' { // 结构可能由于 m 的关系返回一个非结构体的类型定义,所以只能由开头是否为 { 判断是否为结构体。
32-
return "type " + t.Name() + " struct " + s
31+
if strings.HasPrefix(s, "struct {") { // 结构可能由于 m 的关系返回一个非结构体的类型定义,所以只能由开头是否为 struct { 判断是否为结构体。
32+
return "type " + t.Name() + " " + s
3333
}
3434
return buf.String()
3535
}
3636

3737
func goDefine(buf *errwrap.Buffer, indent int, t reflect.Type, m map[reflect.Type]string, unexported, anonymous bool) {
38-
for t.Kind() == reflect.Pointer {
39-
t = t.Elem()
40-
}
41-
4238
if len(m) > 0 {
4339
if s, found := m[t]; found {
4440
buf.WString(s)
@@ -48,21 +44,35 @@ func goDefine(buf *errwrap.Buffer, indent int, t reflect.Type, m map[reflect.Typ
4844

4945
switch t.Kind() {
5046
case reflect.Func, reflect.Chan: // 忽略
47+
case reflect.Pointer:
48+
buf.WByte('*')
49+
goDefine(buf, indent, t.Elem(), m, unexported, anonymous)
5150
case reflect.Slice:
52-
buf.WString("[]").WString(t.Elem().Name())
51+
buf.WString("[]")
52+
goDefine(buf, indent, t.Elem(), m, unexported, anonymous)
5353
case reflect.Array:
54-
buf.WByte('[').WString(strconv.Itoa(t.Len())).WByte(']').WString(t.Elem().Name())
54+
buf.WByte('[').WString(strconv.Itoa(t.Len())).WByte(']')
55+
goDefine(buf, indent, t.Elem(), m, unexported, anonymous)
5556
case reflect.Struct:
5657
if !anonymous {
57-
buf.WString("{\n")
58+
if t.NumField() == 0 {
59+
buf.WString("struct {}")
60+
return
61+
}
62+
63+
buf.WString("struct {\n")
5864
indent++
5965
}
6066

6167
for i := 0; i < t.NumField(); i++ {
6268
f := t.Field(i)
6369

6470
if f.Anonymous {
65-
goDefine(buf, indent, f.Type, m, unexported, true)
71+
tt := f.Type
72+
for tt.Kind() == reflect.Pointer { // 匿名字段需要去掉指针类型
73+
tt = tt.Elem()
74+
}
75+
goDefine(buf, indent, tt, m, unexported, true)
6676
continue
6777
}
6878

codegen/object_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,18 @@ type object5 struct {
4040
Str string
4141
}
4242

43+
type object6 struct {
44+
XMLName struct{} `json:"root"`
45+
Str []*object3
46+
}
47+
4348
func TestGoDefine(t *testing.T) {
4449
a := assert.New(t, false)
4550

4651
wont := "type object1 struct {\n\tInt\tint\t`json:\"int\" yaml:\"int\"`\n\tArray\t[5]int\n\tSlice\t[]string\n\tByte\tuint8\n}"
4752
a.Equal(GoDefine(reflect.TypeFor[object1](), nil, false), wont)
4853

49-
wont = "type object2 struct {\n\tInt\tint\t`json:\"int\" yaml:\"int\"`\n\tObject\t{\n\t\tInt\tint\t`json:\"int\" yaml:\"int\"`\n\t\tArray\t[5]int\n\t\tSlice\t[]string\n\t\tByte\tuint8\n\t}\t`json:\"object\"`\n}"
54+
wont = "type object2 struct {\n\tInt\tint\t`json:\"int\" yaml:\"int\"`\n\tObject\t*struct {\n\t\tInt\tint\t`json:\"int\" yaml:\"int\"`\n\t\tArray\t[5]int\n\t\tSlice\t[]string\n\t\tByte\tuint8\n\t}\t`json:\"object\"`\n}"
5055
a.Equal(GoDefine(reflect.TypeFor[*object2](), nil, false), wont)
5156

5257
a.Equal(GoDefine(reflect.TypeFor[int](), nil, false), "int")
@@ -71,4 +76,6 @@ func TestGoDefine(t *testing.T) {
7176

7277
a.Equal(GoDefine(reflect.TypeFor[time.Time](), m, false), "string")
7378
a.Equal(GoDefine(reflect.TypeFor[time.Time](), nil, false), "type Time struct {\n}")
79+
80+
a.Equal(GoDefine(reflect.TypeFor[object6](), m, false), "type object6 struct {\n\tXMLName\tstruct {}\t`json:\"root\"`\n\tStr\t[]*struct {\n\t\tT\tstring\t`json:\"t\"`\n\t}\n}")
7481
}

0 commit comments

Comments
 (0)