Do not copy node type in ast.Patch

Fixes #468
This commit is contained in:
Anton Medvedev
2023-11-16 15:41:43 +01:00
parent fe7f698b81
commit 3274bda123
3 changed files with 64 additions and 1 deletions
-1
View File
@@ -17,7 +17,6 @@ type Node interface {
}
func Patch(node *Node, newNode Node) {
newNode.SetType((*node).Type())
newNode.SetLocation((*node).Location())
*node = newNode
}
+8
View File
@@ -536,6 +536,14 @@ func (v *checker) SliceNode(node *ast.SliceNode) (reflect.Type, info) {
}
func (v *checker) CallNode(node *ast.CallNode) (reflect.Type, info) {
t, i := v.functionReturnType(node)
if node.Type() != nil {
return node.Type(), i
}
return t, i
}
func (v *checker) functionReturnType(node *ast.CallNode) (reflect.Type, info) {
fn, fnInfo := v.visit(node.Callee)
if fnInfo.fn != nil {
+56
View File
@@ -0,0 +1,56 @@
package set_type_test
import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/ast"
)
func TestPatch_SetType(t *testing.T) {
_, err := expr.Compile(
`Value + "string"`,
expr.Env(Env{}),
expr.Function(
"getValue",
func(params ...any) (any, error) {
return params[0].(Value).Int, nil
},
// We can set function type right here,
// but we want to check what SetType in
// getValuePatcher will take an effect.
),
expr.Patch(getValuePatcher{}),
)
require.Error(t, err)
}
type Value struct {
Int int
}
type Env struct {
Value Value
}
var valueType = reflect.TypeOf((*Value)(nil)).Elem()
type getValuePatcher struct{}
func (getValuePatcher) Visit(node *ast.Node) {
id, ok := (*node).(*ast.IdentifierNode)
if !ok {
return
}
if id.Type() == valueType {
newNode := &ast.CallNode{
Callee: &ast.IdentifierNode{Value: "getValue"},
Arguments: []ast.Node{id},
}
newNode.SetType(reflect.TypeOf(0))
ast.Patch(node, newNode)
}
}