Skip to content

Commit 5a4a8a3

Browse files
committed
Fix deref if types not available
1 parent 2213166 commit 5a4a8a3

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

checker/checker.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ func (v *visitor) NilNode(*ast.NilNode) (reflect.Type, info) {
125125

126126
func (v *visitor) IdentifierNode(node *ast.IdentifierNode) (reflect.Type, info) {
127127
if v.config.Types == nil {
128+
node.Deref = true
128129
return anyType, info{}
129130
}
130131
if t, ok := v.config.Types[node.Value]; ok {
@@ -387,6 +388,7 @@ func (v *visitor) MemberNode(node *ast.MemberNode) (reflect.Type, info) {
387388

388389
switch base.Kind() {
389390
case reflect.Interface:
391+
node.Deref = true
390392
return anyType, info{}
391393

392394
case reflect.Map:

compiler/compiler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ func (c *compiler) IdentifierNode(node *ast.IdentifierNode) {
211211
}
212212
if node.Deref {
213213
c.emit(OpDeref)
214+
} else if node.Type() == nil {
215+
c.emit(OpDeref)
214216
}
215217
}
216218

@@ -496,6 +498,8 @@ func (c *compiler) MemberNode(node *ast.MemberNode) {
496498
deref:
497499
if original.Deref {
498500
c.emit(OpDeref)
501+
} else if original.Type() == nil {
502+
c.emit(OpDeref)
499503
}
500504
}
501505

expr_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,50 @@ func TestCompile_exposed_error(t *testing.T) {
12761276
require.Equal(t, `{"Line":1,"Column":2,"Message":"invalid operation: == (mismatched types int and bool)","Snippet":"\n | 1 == true\n | ..^"}`, string(b))
12771277
}
12781278

1279+
func TestCompile_deref(t *testing.T) {
1280+
i := 1
1281+
env := map[string]interface{}{
1282+
"i": &i,
1283+
"map": map[string]interface{}{
1284+
"i": &i,
1285+
},
1286+
}
1287+
{
1288+
// With specified env, OpDeref added and == works as expected.
1289+
program, err := expr.Compile(`i == 1 && map.i == 1`, expr.Env(env))
1290+
require.NoError(t, err)
1291+
1292+
env["any"] = &i
1293+
out, err := expr.Run(program, env)
1294+
require.NoError(t, err)
1295+
require.Equal(t, true, out)
1296+
}
1297+
{
1298+
// Compile without expr.Env() also works as expected,
1299+
// and should add OpDeref automatically.
1300+
program, err := expr.Compile(`i == 1 && map.i == 1`)
1301+
require.NoError(t, err)
1302+
1303+
out, err := expr.Run(program, env)
1304+
require.NoError(t, err)
1305+
require.Equal(t, true, out)
1306+
}
1307+
}
1308+
1309+
func TestEval_deref(t *testing.T) {
1310+
i := 1
1311+
env := map[string]interface{}{
1312+
"i": &i,
1313+
"map": map[string]interface{}{
1314+
"i": &i,
1315+
},
1316+
}
1317+
1318+
out, err := expr.Eval(`i == 1 && map.i == 1`, env)
1319+
require.NoError(t, err)
1320+
require.Equal(t, true, out)
1321+
}
1322+
12791323
func TestAsBool_exposed_error(t *testing.T) {
12801324
_, err := expr.Compile(`42`, expr.AsBool())
12811325
require.Error(t, err)

0 commit comments

Comments
 (0)