MCPcopy
hub / github.com/expr-lang/expr / Visit

Method Visit

optimizer/const_expr.go:20–81  ·  view source on GitHub ↗
(node *Node)

Source from the content-addressed store, hash-verified

18}
19
20func (c *constExpr) Visit(node *Node) {
21 defer func() {
22 if r := recover(); r != nil {
23 msg := fmt.Sprintf("%v", r)
24 // Make message more actual, it's a runtime error, but at compile step.
25 msg = strings.Replace(msg, "runtime error:", "compile error:", 1)
26 c.err = &file.Error{
27 Location: (*node).Location(),
28 Message: msg,
29 }
30 }
31 }()
32
33 if call, ok := (*node).(*CallNode); ok {
34 if name, ok := call.Callee.(*IdentifierNode); ok {
35 fn, ok := c.fns[name.Value]
36 if ok {
37 in := make([]reflect.Value, len(call.Arguments))
38 for i := 0; i < len(call.Arguments); i++ {
39 arg := call.Arguments[i]
40 var param any
41
42 switch a := arg.(type) {
43 case *NilNode:
44 param = nil
45 case *IntegerNode:
46 param = a.Value
47 case *FloatNode:
48 param = a.Value
49 case *BoolNode:
50 param = a.Value
51 case *StringNode:
52 param = a.Value
53 case *ConstantNode:
54 param = a.Value
55
56 default:
57 return // Const expr optimization not applicable.
58 }
59
60 if param == nil && reflect.TypeOf(param) == nil {
61 // In case of nil value and nil type use this hack,
62 // otherwise reflect.Call will panic on zero value.
63 in[i] = reflect.ValueOf(&param).Elem()
64 } else {
65 in[i] = reflect.ValueOf(param)
66 }
67 }
68
69 out := fn.Call(in)
70 value := out[0].Interface()
71 if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() {
72 c.err = out[1].Interface().(error)
73 return
74 }
75 constNode := &ConstantNode{Value: value}
76 patchWithType(node, constNode)
77 c.applied = true

Callers

nothing calls this directly

Calls 5

patchWithTypeFunction · 0.85
SprintfMethod · 0.80
ElemMethod · 0.80
LocationMethod · 0.65
TypeMethod · 0.65

Tested by

no test coverage detected