Skip to content

Commit fcf2b55

Browse files
committed
Do not copy node type in ast.Patch
Fixes #468
1 parent 7f07463 commit fcf2b55

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

ast/node.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ type Node interface {
1717
}
1818

1919
func Patch(node *Node, newNode Node) {
20-
newNode.SetType((*node).Type())
2120
newNode.SetLocation((*node).Location())
2221
*node = newNode
2322
}

checker/checker.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,14 @@ func (v *checker) SliceNode(node *ast.SliceNode) (reflect.Type, info) {
536536
}
537537

538538
func (v *checker) CallNode(node *ast.CallNode) (reflect.Type, info) {
539+
t, i := v.functionReturnType(node)
540+
if node.Type() != nil {
541+
return node.Type(), i
542+
}
543+
return t, i
544+
}
545+
546+
func (v *checker) functionReturnType(node *ast.CallNode) (reflect.Type, info) {
539547
fn, fnInfo := v.visit(node.Callee)
540548

541549
if fnInfo.fn != nil {

test/patch/set_type/set_type_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package set_type_test
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/antonmedv/expr"
10+
"github.com/antonmedv/expr/ast"
11+
)
12+
13+
func TestPatch_SetType(t *testing.T) {
14+
_, err := expr.Compile(
15+
`Value + "string"`,
16+
expr.Env(Env{}),
17+
expr.Function(
18+
"getValue",
19+
func(params ...any) (any, error) {
20+
return params[0].(Value).Int, nil
21+
},
22+
// We can set function type right here,
23+
// but we want to check what SetType in
24+
// getValuePatcher will take an effect.
25+
),
26+
expr.Patch(getValuePatcher{}),
27+
)
28+
require.Error(t, err)
29+
}
30+
31+
type Value struct {
32+
Int int
33+
}
34+
35+
type Env struct {
36+
Value Value
37+
}
38+
39+
var valueType = reflect.TypeOf((*Value)(nil)).Elem()
40+
41+
type getValuePatcher struct{}
42+
43+
func (getValuePatcher) Visit(node *ast.Node) {
44+
id, ok := (*node).(*ast.IdentifierNode)
45+
if !ok {
46+
return
47+
}
48+
if id.Type() == valueType {
49+
newNode := &ast.CallNode{
50+
Callee: &ast.IdentifierNode{Value: "getValue"},
51+
Arguments: []ast.Node{id},
52+
}
53+
newNode.SetType(reflect.TypeOf(0))
54+
ast.Patch(node, newNode)
55+
}
56+
}

0 commit comments

Comments
 (0)