mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
@@ -17,7 +17,6 @@ type Node interface {
|
||||
}
|
||||
|
||||
func Patch(node *Node, newNode Node) {
|
||||
newNode.SetType((*node).Type())
|
||||
newNode.SetLocation((*node).Location())
|
||||
*node = newNode
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user