|
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? |
Answered by
antonmedv
Jan 11, 2024
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.
) |
9 replies
Answer selected by
tw1nk
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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…