Skip to content

Commit 23d52b6

Browse files
committed
Refactor type checker of fieldType helper
1 parent 9ad0964 commit 23d52b6

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

type.go

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,22 @@ func fieldType(ntype Type, name string) (Type, bool) {
374374
case reflect.Interface:
375375
return interfaceType, true
376376
case reflect.Struct:
377-
t, ok := ntype.FieldByName(name)
378-
if ok {
379-
return t.Type, true
377+
// First check all struct's fields.
378+
for i := 0; i < ntype.NumField(); i++ {
379+
f := ntype.Field(i)
380+
if !f.Anonymous && f.Name == name {
381+
return f.Type, true
382+
}
380383
}
381384

382-
if t, ok := checkEmbeddedFieldNames(ntype, name); ok {
383-
return t, true
385+
// Second check fields of embedded structs.
386+
for i := 0; i < ntype.NumField(); i++ {
387+
f := ntype.Field(i)
388+
if f.Anonymous {
389+
if t, ok := fieldType(f.Type, name); ok {
390+
return t, true
391+
}
392+
}
384393
}
385394
case reflect.Map:
386395
return ntype.Elem(), true
@@ -390,26 +399,6 @@ func fieldType(ntype Type, name string) (Type, bool) {
390399
return nil, false
391400
}
392401

393-
func checkEmbeddedFieldNames(t reflect.Type, name string) (Type, bool) {
394-
t = dereference(t)
395-
if t.Kind() == reflect.Struct {
396-
for i := 0; i < t.NumField(); i++ {
397-
f := t.Field(i)
398-
399-
fType := dereference(f.Type)
400-
if fType.Kind() == reflect.Struct {
401-
return checkEmbeddedFieldNames(fType, name)
402-
}
403-
404-
if f.Anonymous && f.Name == name {
405-
return fType, true
406-
}
407-
}
408-
}
409-
410-
return nil, false
411-
}
412-
413402
func indexType(ntype Type) (Type, bool) {
414403
ntype = dereference(ntype)
415404
if ntype == nil {

type_test.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ var typeTests = []typeTest{
7373
"Int + Int + Int",
7474
"Int % Int > 1",
7575
"Int in Int..Int",
76-
"FieldStr == ''",
77-
"FieldStr2 == ''",
76+
"EmbStr == ''",
77+
"EmbPtrStr == ''",
78+
"SubStr ~ ''",
7879
"OkFn() and OkFn()",
7980
"Foo.Fn() or Foo.Fn()",
8081
}
@@ -280,6 +281,10 @@ var typeErrorTests = []typeErrorTest{
280281
"1 in Foo",
281282
"invalid operation: 1 in Foo (mismatched types float64 and *expr_test.foo)",
282283
},
284+
{
285+
"Embedded.EmbStr ~ Str",
286+
"unknown name Embedded",
287+
},
283288
}
284289

285290
type abc interface {
@@ -293,18 +298,19 @@ type foo struct {
293298
Fn func() bool
294299
Abc abc
295300
}
296-
297-
type StringStruct struct {
298-
FieldStr string
301+
type SubEmbedded struct {
302+
SubStr string
299303
}
300-
301-
type StringStructPtr struct {
302-
FieldStr2 string
304+
type Embedded struct {
305+
SubEmbedded
306+
EmbStr string
307+
}
308+
type EmbeddedPtr struct {
309+
EmbPtrStr string
303310
}
304-
305311
type payload struct {
306-
StringStruct
307-
*StringStructPtr
312+
Embedded
313+
*EmbeddedPtr
308314
Abc abc
309315
Foo *foo
310316
Arr []*foo

0 commit comments

Comments
 (0)