Skip to content

Commit

Permalink
Do not copy node type in ast.Patch
Browse files Browse the repository at this point in the history
Fixes #468
  • Loading branch information
antonmedv committed Nov 16, 2023
1 parent 7f07463 commit fcf2b55
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
1 change: 0 additions & 1 deletion ast/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ type Node interface {
}

func Patch(node *Node, newNode Node) {
newNode.SetType((*node).Type())
newNode.SetLocation((*node).Location())
*node = newNode
}
Expand Down
8 changes: 8 additions & 0 deletions checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
56 changes: 56 additions & 0 deletions test/patch/set_type/set_type_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit fcf2b55

Please sign in to comment.