Skip to content

Commit 337130d

Browse files
committed
fix ambiguous embed struct reference
1 parent f006ea4 commit 337130d

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

checker/checker.go

+3
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ func (v *visitor) IdentifierNode(node *ast.IdentifierNode) reflect.Type {
125125
return interfaceType
126126
}
127127
if t, ok := v.types[node.Value]; ok {
128+
if t.Ambiguous {
129+
return v.error(node, "ambiguous identifier %v", node.Value)
130+
}
128131
return t.Type
129132
}
130133
if !v.strict {

checker/types.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func fieldType(ntype reflect.Type, name string) (reflect.Type, bool) {
209209
// First check all struct's fields.
210210
for i := 0; i < ntype.NumField(); i++ {
211211
f := ntype.Field(i)
212-
if !f.Anonymous && f.Name == name {
212+
if f.Name == name {
213213
return f.Type, true
214214
}
215215
}

conf/types_table.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package conf
33
import "reflect"
44

55
type Tag struct {
6-
Type reflect.Type
7-
Method bool
6+
Type reflect.Type
7+
Method bool
8+
Ambiguous bool
89
}
910

1011
type TypesTable map[string]Tag
@@ -73,7 +74,11 @@ func FieldsFromStruct(t reflect.Type) TypesTable {
7374

7475
if f.Anonymous {
7576
for name, typ := range FieldsFromStruct(f.Type) {
76-
types[name] = typ
77+
if _, ok := types[name]; ok {
78+
types[name] = Tag{Ambiguous: true}
79+
} else {
80+
types[name] = typ
81+
}
7782
}
7883
}
7984

expr_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,36 @@ func TestEval_exposed_error(t *testing.T) {
10931093
require.Equal(t, 1, fileError.Line)
10941094
}
10951095

1096+
func TestIssue105(t *testing.T) {
1097+
type A struct {
1098+
Field string
1099+
}
1100+
type B struct {
1101+
Field int
1102+
}
1103+
type C struct {
1104+
A
1105+
B
1106+
}
1107+
type Env struct {
1108+
C
1109+
}
1110+
1111+
code := `
1112+
A.Field == '' &&
1113+
C.A.Field == '' &&
1114+
B.Field == 0 &&
1115+
C.B.Field == 0
1116+
`
1117+
1118+
_, err := expr.Compile(code, expr.Env(Env{}))
1119+
require.NoError(t, err)
1120+
1121+
_, err = expr.Compile(`Field == ''`, expr.Env(Env{}))
1122+
require.Error(t, err)
1123+
require.Contains(t, err.Error(), "ambiguous identifier Field")
1124+
}
1125+
10961126
//
10971127
// Mock types
10981128
//

0 commit comments

Comments
 (0)