-
| 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…