-
Context: I have a patcher that modifies the CallNode function arguments as I don't want our users to have to add in 1.15.7 this works type ContextPatcher struct{}
func (p *ContextPatcher) Visit(node *ast.Node) {
// we need to set the node type to nil to make sure we're not getting
// caught by invalid types
// https://github.com/expr-lang/expr/discussions/473#discussioncomment-7666118
(*node).SetType(nil)
contextType := reflect.TypeOf((*context.Context)(nil)).Elem()
if callNode, ok := (*node).(*ast.CallNode); ok {
if callNode.Func != nil {
// patch context calls so we don't have to pass the context in the code
funcType := callNode.Func.Types[0]
if funcType.NumIn() > 0 {
firstIn := funcType.In(0)
if firstIn.Implements(contextType) {
// prepend patch context calls so we don't need to specify the context
args := append([]ast.Node{
&ast.IdentifierNode{
Value: "ctx",
},
}, callNode.Arguments...)
ast.Patch(node, &ast.CallNode{
Callee: callNode.Callee,
Arguments: args,
Typed: callNode.Typed,
Fast: callNode.Fast,
Func: callNode.Func,
})
}
}
}
}
} When looking at the PR #504 (https://github.com/expr-lang/expr/pull/504/files) which removed the Func field from CallNode I can't find out how I can get access to the function information anymore? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 9 replies
-
Yes, this is still possible to do. Your current implementation has a few errors and I removed Func specifically to emphasize a correct solution: use switch (*node).(type) {
case *ast.CallNode:
call := (*node).(*ast.CallNode)
fn := call.Callee.Type()
if fn.Kind() != reflect.Func {
return
}
if fn.NumIn() == 0 {
return
}
if fn.In(0).String() != "context.Context" {
return
}
ast.Patch(node, &ast.CallNode{
Callee: call.Callee,
Arguments: append([]ast.Node{
&ast.IdentifierNode{Value: "ctx"},
}, call.Arguments...),
})
} Or you can also use a patcher that comes with Expr itself https://pkg.go.dev/github.com/expr-lang/expr#WithContext program, err := expr.Compile(`fn(1, 2)`,
expr.Env(env),
expr.WithContext("ctx"), // Pass context variable name.
) |
Beta Was this translation helpful? Give feedback.
Yes, this is still possible to do. Your current implementation has a few errors and I removed Func specifically to emphasize a correct solution: use
call.Callee.Type()
to get a func type.Or you can also use a patcher that comes with Expr itself https://pkg.go.dev/github.com/expr-lan…