mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-19 07:28:08 +08:00
chore: upgrade coredns version (#550)
This commit is contained in:
59
vendor/github.com/expr-lang/expr/ast/dump.go
generated
vendored
Normal file
59
vendor/github.com/expr-lang/expr/ast/dump.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func Dump(node Node) string {
|
||||
return dump(reflect.ValueOf(node), "")
|
||||
}
|
||||
|
||||
func dump(v reflect.Value, ident string) string {
|
||||
if !v.IsValid() {
|
||||
return "nil"
|
||||
}
|
||||
t := v.Type()
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
out := t.Name() + "{\n"
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if isPrivate(f.Name) {
|
||||
continue
|
||||
}
|
||||
s := v.Field(i)
|
||||
out += fmt.Sprintf("%v%v: %v,\n", ident+"\t", f.Name, dump(s, ident+"\t"))
|
||||
}
|
||||
return out + ident + "}"
|
||||
case reflect.Slice:
|
||||
if v.Len() == 0 {
|
||||
return t.String() + "{}"
|
||||
}
|
||||
out := t.String() + "{\n"
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
s := v.Index(i)
|
||||
out += fmt.Sprintf("%v%v,", ident+"\t", dump(s, ident+"\t"))
|
||||
if i+1 < v.Len() {
|
||||
out += "\n"
|
||||
}
|
||||
}
|
||||
return out + "\n" + ident + "}"
|
||||
case reflect.Ptr:
|
||||
return dump(v.Elem(), ident)
|
||||
case reflect.Interface:
|
||||
return dump(reflect.ValueOf(v.Interface()), ident)
|
||||
|
||||
case reflect.String:
|
||||
return fmt.Sprintf("%q", v)
|
||||
default:
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
|
||||
var isCapital = regexp.MustCompile("^[A-Z]")
|
||||
|
||||
func isPrivate(s string) bool {
|
||||
return !isCapital.Match([]byte(s))
|
||||
}
|
||||
18
vendor/github.com/expr-lang/expr/ast/find.go
generated
vendored
Normal file
18
vendor/github.com/expr-lang/expr/ast/find.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package ast
|
||||
|
||||
func Find(node Node, fn func(node Node) bool) Node {
|
||||
v := &finder{fn: fn}
|
||||
Walk(&node, v)
|
||||
return v.node
|
||||
}
|
||||
|
||||
type finder struct {
|
||||
node Node
|
||||
fn func(node Node) bool
|
||||
}
|
||||
|
||||
func (f *finder) Visit(node *Node) {
|
||||
if f.fn(*node) {
|
||||
f.node = *node
|
||||
}
|
||||
}
|
||||
243
vendor/github.com/expr-lang/expr/ast/node.go
generated
vendored
Normal file
243
vendor/github.com/expr-lang/expr/ast/node.go
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/expr-lang/expr/checker/nature"
|
||||
"github.com/expr-lang/expr/file"
|
||||
)
|
||||
|
||||
var (
|
||||
anyType = reflect.TypeOf(new(any)).Elem()
|
||||
)
|
||||
|
||||
// Node represents items of abstract syntax tree.
|
||||
type Node interface {
|
||||
Location() file.Location
|
||||
SetLocation(file.Location)
|
||||
Nature() nature.Nature
|
||||
SetNature(nature.Nature)
|
||||
Type() reflect.Type
|
||||
SetType(reflect.Type)
|
||||
String() string
|
||||
}
|
||||
|
||||
// Patch replaces the node with a new one.
|
||||
// Location information is preserved.
|
||||
// Type information is lost.
|
||||
func Patch(node *Node, newNode Node) {
|
||||
newNode.SetLocation((*node).Location())
|
||||
*node = newNode
|
||||
}
|
||||
|
||||
// base is a base struct for all nodes.
|
||||
type base struct {
|
||||
loc file.Location
|
||||
nature nature.Nature
|
||||
}
|
||||
|
||||
// Location returns the location of the node in the source code.
|
||||
func (n *base) Location() file.Location {
|
||||
return n.loc
|
||||
}
|
||||
|
||||
// SetLocation sets the location of the node in the source code.
|
||||
func (n *base) SetLocation(loc file.Location) {
|
||||
n.loc = loc
|
||||
}
|
||||
|
||||
// Nature returns the nature of the node.
|
||||
func (n *base) Nature() nature.Nature {
|
||||
return n.nature
|
||||
}
|
||||
|
||||
// SetNature sets the nature of the node.
|
||||
func (n *base) SetNature(nature nature.Nature) {
|
||||
n.nature = nature
|
||||
}
|
||||
|
||||
// Type returns the type of the node.
|
||||
func (n *base) Type() reflect.Type {
|
||||
if n.nature.Type == nil {
|
||||
return anyType
|
||||
}
|
||||
return n.nature.Type
|
||||
}
|
||||
|
||||
// SetType sets the type of the node.
|
||||
func (n *base) SetType(t reflect.Type) {
|
||||
n.nature.Type = t
|
||||
}
|
||||
|
||||
// NilNode represents nil.
|
||||
type NilNode struct {
|
||||
base
|
||||
}
|
||||
|
||||
// IdentifierNode represents an identifier.
|
||||
type IdentifierNode struct {
|
||||
base
|
||||
Value string // Name of the identifier. Like "foo" in "foo.bar".
|
||||
}
|
||||
|
||||
// IntegerNode represents an integer.
|
||||
type IntegerNode struct {
|
||||
base
|
||||
Value int // Value of the integer.
|
||||
}
|
||||
|
||||
// FloatNode represents a float.
|
||||
type FloatNode struct {
|
||||
base
|
||||
Value float64 // Value of the float.
|
||||
}
|
||||
|
||||
// BoolNode represents a boolean.
|
||||
type BoolNode struct {
|
||||
base
|
||||
Value bool // Value of the boolean.
|
||||
}
|
||||
|
||||
// StringNode represents a string.
|
||||
type StringNode struct {
|
||||
base
|
||||
Value string // Value of the string.
|
||||
}
|
||||
|
||||
// ConstantNode represents a constant.
|
||||
// Constants are predefined values like nil, true, false, array, map, etc.
|
||||
// The parser.Parse will never generate ConstantNode, it is only generated
|
||||
// by the optimizer.
|
||||
type ConstantNode struct {
|
||||
base
|
||||
Value any // Value of the constant.
|
||||
}
|
||||
|
||||
// UnaryNode represents a unary operator.
|
||||
type UnaryNode struct {
|
||||
base
|
||||
Operator string // Operator of the unary operator. Like "!" in "!foo" or "not" in "not foo".
|
||||
Node Node // Node of the unary operator. Like "foo" in "!foo".
|
||||
}
|
||||
|
||||
// BinaryNode represents a binary operator.
|
||||
type BinaryNode struct {
|
||||
base
|
||||
Operator string // Operator of the binary operator. Like "+" in "foo + bar" or "matches" in "foo matches bar".
|
||||
Left Node // Left node of the binary operator.
|
||||
Right Node // Right node of the binary operator.
|
||||
}
|
||||
|
||||
// ChainNode represents an optional chaining group.
|
||||
// A few MemberNode nodes can be chained together,
|
||||
// and will be wrapped in a ChainNode. Example:
|
||||
//
|
||||
// foo.bar?.baz?.qux
|
||||
//
|
||||
// The whole chain will be wrapped in a ChainNode.
|
||||
type ChainNode struct {
|
||||
base
|
||||
Node Node // Node of the chain.
|
||||
}
|
||||
|
||||
// MemberNode represents a member access.
|
||||
// It can be a field access, a method call,
|
||||
// or an array element access.
|
||||
// Example:
|
||||
//
|
||||
// foo.bar or foo["bar"]
|
||||
// foo.bar()
|
||||
// array[0]
|
||||
type MemberNode struct {
|
||||
base
|
||||
Node Node // Node of the member access. Like "foo" in "foo.bar".
|
||||
Property Node // Property of the member access. For property access it is a StringNode.
|
||||
Optional bool // If true then the member access is optional. Like "foo?.bar".
|
||||
Method bool
|
||||
}
|
||||
|
||||
// SliceNode represents access to a slice of an array.
|
||||
// Example:
|
||||
//
|
||||
// array[1:4]
|
||||
type SliceNode struct {
|
||||
base
|
||||
Node Node // Node of the slice. Like "array" in "array[1:4]".
|
||||
From Node // From an index of the array. Like "1" in "array[1:4]".
|
||||
To Node // To an index of the array. Like "4" in "array[1:4]".
|
||||
}
|
||||
|
||||
// CallNode represents a function or a method call.
|
||||
type CallNode struct {
|
||||
base
|
||||
Callee Node // Node of the call. Like "foo" in "foo()".
|
||||
Arguments []Node // Arguments of the call.
|
||||
}
|
||||
|
||||
// BuiltinNode represents a builtin function call.
|
||||
type BuiltinNode struct {
|
||||
base
|
||||
Name string // Name of the builtin function. Like "len" in "len(foo)".
|
||||
Arguments []Node // Arguments of the builtin function.
|
||||
Throws bool // If true then accessing a field or array index can throw an error. Used by optimizer.
|
||||
Map Node // Used by optimizer to fold filter() and map() builtins.
|
||||
}
|
||||
|
||||
// PredicateNode represents a predicate.
|
||||
// Example:
|
||||
//
|
||||
// filter(foo, .bar == 1)
|
||||
//
|
||||
// The predicate is ".bar == 1".
|
||||
type PredicateNode struct {
|
||||
base
|
||||
Node Node // Node of the predicate body.
|
||||
}
|
||||
|
||||
// PointerNode represents a pointer to a current value in predicate.
|
||||
type PointerNode struct {
|
||||
base
|
||||
Name string // Name of the pointer. Like "index" in "#index".
|
||||
}
|
||||
|
||||
// ConditionalNode represents a ternary operator.
|
||||
type ConditionalNode struct {
|
||||
base
|
||||
Cond Node // Condition of the ternary operator. Like "foo" in "foo ? bar : baz".
|
||||
Exp1 Node // Expression 1 of the ternary operator. Like "bar" in "foo ? bar : baz".
|
||||
Exp2 Node // Expression 2 of the ternary operator. Like "baz" in "foo ? bar : baz".
|
||||
}
|
||||
|
||||
// VariableDeclaratorNode represents a variable declaration.
|
||||
type VariableDeclaratorNode struct {
|
||||
base
|
||||
Name string // Name of the variable. Like "foo" in "let foo = 1; foo + 1".
|
||||
Value Node // Value of the variable. Like "1" in "let foo = 1; foo + 1".
|
||||
Expr Node // Expression of the variable. Like "foo + 1" in "let foo = 1; foo + 1".
|
||||
}
|
||||
|
||||
// SequenceNode represents a sequence of nodes separated by semicolons.
|
||||
// All nodes are executed, only the last node will be returned.
|
||||
type SequenceNode struct {
|
||||
base
|
||||
Nodes []Node
|
||||
}
|
||||
|
||||
// ArrayNode represents an array.
|
||||
type ArrayNode struct {
|
||||
base
|
||||
Nodes []Node // Nodes of the array.
|
||||
}
|
||||
|
||||
// MapNode represents a map.
|
||||
type MapNode struct {
|
||||
base
|
||||
Pairs []Node // PairNode nodes.
|
||||
}
|
||||
|
||||
// PairNode represents a key-value pair of a map.
|
||||
type PairNode struct {
|
||||
base
|
||||
Key Node // Key of the pair.
|
||||
Value Node // Value of the pair.
|
||||
}
|
||||
253
vendor/github.com/expr-lang/expr/ast/print.go
generated
vendored
Normal file
253
vendor/github.com/expr-lang/expr/ast/print.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/expr-lang/expr/parser/operator"
|
||||
"github.com/expr-lang/expr/parser/utils"
|
||||
)
|
||||
|
||||
func (n *NilNode) String() string {
|
||||
return "nil"
|
||||
}
|
||||
|
||||
func (n *IdentifierNode) String() string {
|
||||
return n.Value
|
||||
}
|
||||
|
||||
func (n *IntegerNode) String() string {
|
||||
return fmt.Sprintf("%d", n.Value)
|
||||
}
|
||||
|
||||
func (n *FloatNode) String() string {
|
||||
return fmt.Sprintf("%v", n.Value)
|
||||
}
|
||||
|
||||
func (n *BoolNode) String() string {
|
||||
return fmt.Sprintf("%t", n.Value)
|
||||
}
|
||||
|
||||
func (n *StringNode) String() string {
|
||||
return fmt.Sprintf("%q", n.Value)
|
||||
}
|
||||
|
||||
func (n *ConstantNode) String() string {
|
||||
if n.Value == nil {
|
||||
return "nil"
|
||||
}
|
||||
b, err := json.Marshal(n.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (n *UnaryNode) String() string {
|
||||
op := n.Operator
|
||||
if n.Operator == "not" {
|
||||
op = fmt.Sprintf("%s ", n.Operator)
|
||||
}
|
||||
wrap := false
|
||||
switch b := n.Node.(type) {
|
||||
case *BinaryNode:
|
||||
if operator.Binary[b.Operator].Precedence <
|
||||
operator.Unary[n.Operator].Precedence {
|
||||
wrap = true
|
||||
}
|
||||
case *ConditionalNode:
|
||||
wrap = true
|
||||
}
|
||||
if wrap {
|
||||
return fmt.Sprintf("%s(%s)", op, n.Node.String())
|
||||
}
|
||||
return fmt.Sprintf("%s%s", op, n.Node.String())
|
||||
}
|
||||
|
||||
func (n *BinaryNode) String() string {
|
||||
if n.Operator == ".." {
|
||||
return fmt.Sprintf("%s..%s", n.Left, n.Right)
|
||||
}
|
||||
|
||||
var lhs, rhs string
|
||||
var lwrap, rwrap bool
|
||||
|
||||
if l, ok := n.Left.(*UnaryNode); ok {
|
||||
if operator.Unary[l.Operator].Precedence <
|
||||
operator.Binary[n.Operator].Precedence {
|
||||
lwrap = true
|
||||
}
|
||||
}
|
||||
if lb, ok := n.Left.(*BinaryNode); ok {
|
||||
if operator.Less(lb.Operator, n.Operator) {
|
||||
lwrap = true
|
||||
}
|
||||
if operator.Binary[lb.Operator].Precedence ==
|
||||
operator.Binary[n.Operator].Precedence &&
|
||||
operator.Binary[n.Operator].Associativity == operator.Right {
|
||||
lwrap = true
|
||||
}
|
||||
if lb.Operator == "??" {
|
||||
lwrap = true
|
||||
}
|
||||
if operator.IsBoolean(lb.Operator) && n.Operator != lb.Operator {
|
||||
lwrap = true
|
||||
}
|
||||
}
|
||||
if rb, ok := n.Right.(*BinaryNode); ok {
|
||||
if operator.Less(rb.Operator, n.Operator) {
|
||||
rwrap = true
|
||||
}
|
||||
if operator.Binary[rb.Operator].Precedence ==
|
||||
operator.Binary[n.Operator].Precedence &&
|
||||
operator.Binary[n.Operator].Associativity == operator.Left {
|
||||
rwrap = true
|
||||
}
|
||||
if operator.IsBoolean(rb.Operator) && n.Operator != rb.Operator {
|
||||
rwrap = true
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := n.Left.(*ConditionalNode); ok {
|
||||
lwrap = true
|
||||
}
|
||||
if _, ok := n.Right.(*ConditionalNode); ok {
|
||||
rwrap = true
|
||||
}
|
||||
|
||||
if lwrap {
|
||||
lhs = fmt.Sprintf("(%s)", n.Left.String())
|
||||
} else {
|
||||
lhs = n.Left.String()
|
||||
}
|
||||
|
||||
if rwrap {
|
||||
rhs = fmt.Sprintf("(%s)", n.Right.String())
|
||||
} else {
|
||||
rhs = n.Right.String()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s %s", lhs, n.Operator, rhs)
|
||||
}
|
||||
|
||||
func (n *ChainNode) String() string {
|
||||
return n.Node.String()
|
||||
}
|
||||
|
||||
func (n *MemberNode) String() string {
|
||||
node := n.Node.String()
|
||||
if _, ok := n.Node.(*BinaryNode); ok {
|
||||
node = fmt.Sprintf("(%s)", node)
|
||||
}
|
||||
|
||||
if n.Optional {
|
||||
if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
|
||||
return fmt.Sprintf("%s?.%s", node, str.Value)
|
||||
} else {
|
||||
return fmt.Sprintf("%s?.[%s]", node, n.Property.String())
|
||||
}
|
||||
}
|
||||
if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
|
||||
if _, ok := n.Node.(*PointerNode); ok {
|
||||
return fmt.Sprintf(".%s", str.Value)
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", node, str.Value)
|
||||
}
|
||||
return fmt.Sprintf("%s[%s]", node, n.Property.String())
|
||||
}
|
||||
|
||||
func (n *SliceNode) String() string {
|
||||
if n.From == nil && n.To == nil {
|
||||
return fmt.Sprintf("%s[:]", n.Node.String())
|
||||
}
|
||||
if n.From == nil {
|
||||
return fmt.Sprintf("%s[:%s]", n.Node.String(), n.To.String())
|
||||
}
|
||||
if n.To == nil {
|
||||
return fmt.Sprintf("%s[%s:]", n.Node.String(), n.From.String())
|
||||
}
|
||||
return fmt.Sprintf("%s[%s:%s]", n.Node.String(), n.From.String(), n.To.String())
|
||||
}
|
||||
|
||||
func (n *CallNode) String() string {
|
||||
arguments := make([]string, len(n.Arguments))
|
||||
for i, arg := range n.Arguments {
|
||||
arguments[i] = arg.String()
|
||||
}
|
||||
return fmt.Sprintf("%s(%s)", n.Callee.String(), strings.Join(arguments, ", "))
|
||||
}
|
||||
|
||||
func (n *BuiltinNode) String() string {
|
||||
arguments := make([]string, len(n.Arguments))
|
||||
for i, arg := range n.Arguments {
|
||||
arguments[i] = arg.String()
|
||||
}
|
||||
return fmt.Sprintf("%s(%s)", n.Name, strings.Join(arguments, ", "))
|
||||
}
|
||||
|
||||
func (n *PredicateNode) String() string {
|
||||
return n.Node.String()
|
||||
}
|
||||
|
||||
func (n *PointerNode) String() string {
|
||||
return fmt.Sprintf("#%s", n.Name)
|
||||
}
|
||||
|
||||
func (n *VariableDeclaratorNode) String() string {
|
||||
return fmt.Sprintf("let %s = %s; %s", n.Name, n.Value.String(), n.Expr.String())
|
||||
}
|
||||
|
||||
func (n *SequenceNode) String() string {
|
||||
nodes := make([]string, len(n.Nodes))
|
||||
for i, node := range n.Nodes {
|
||||
nodes[i] = node.String()
|
||||
}
|
||||
return strings.Join(nodes, "; ")
|
||||
}
|
||||
|
||||
func (n *ConditionalNode) String() string {
|
||||
var cond, exp1, exp2 string
|
||||
if _, ok := n.Cond.(*ConditionalNode); ok {
|
||||
cond = fmt.Sprintf("(%s)", n.Cond.String())
|
||||
} else {
|
||||
cond = n.Cond.String()
|
||||
}
|
||||
if _, ok := n.Exp1.(*ConditionalNode); ok {
|
||||
exp1 = fmt.Sprintf("(%s)", n.Exp1.String())
|
||||
} else {
|
||||
exp1 = n.Exp1.String()
|
||||
}
|
||||
if _, ok := n.Exp2.(*ConditionalNode); ok {
|
||||
exp2 = fmt.Sprintf("(%s)", n.Exp2.String())
|
||||
} else {
|
||||
exp2 = n.Exp2.String()
|
||||
}
|
||||
return fmt.Sprintf("%s ? %s : %s", cond, exp1, exp2)
|
||||
}
|
||||
|
||||
func (n *ArrayNode) String() string {
|
||||
nodes := make([]string, len(n.Nodes))
|
||||
for i, node := range n.Nodes {
|
||||
nodes[i] = node.String()
|
||||
}
|
||||
return fmt.Sprintf("[%s]", strings.Join(nodes, ", "))
|
||||
}
|
||||
|
||||
func (n *MapNode) String() string {
|
||||
pairs := make([]string, len(n.Pairs))
|
||||
for i, pair := range n.Pairs {
|
||||
pairs[i] = pair.String()
|
||||
}
|
||||
return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
|
||||
}
|
||||
|
||||
func (n *PairNode) String() string {
|
||||
if str, ok := n.Key.(*StringNode); ok {
|
||||
if utils.IsValidIdentifier(str.Value) {
|
||||
return fmt.Sprintf("%s: %s", str.Value, n.Value.String())
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", str.String(), n.Value.String())
|
||||
}
|
||||
return fmt.Sprintf("(%s): %s", n.Key.String(), n.Value.String())
|
||||
}
|
||||
78
vendor/github.com/expr-lang/expr/ast/visitor.go
generated
vendored
Normal file
78
vendor/github.com/expr-lang/expr/ast/visitor.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package ast
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Visitor interface {
|
||||
Visit(node *Node)
|
||||
}
|
||||
|
||||
func Walk(node *Node, v Visitor) {
|
||||
if *node == nil {
|
||||
return
|
||||
}
|
||||
switch n := (*node).(type) {
|
||||
case *NilNode:
|
||||
case *IdentifierNode:
|
||||
case *IntegerNode:
|
||||
case *FloatNode:
|
||||
case *BoolNode:
|
||||
case *StringNode:
|
||||
case *ConstantNode:
|
||||
case *UnaryNode:
|
||||
Walk(&n.Node, v)
|
||||
case *BinaryNode:
|
||||
Walk(&n.Left, v)
|
||||
Walk(&n.Right, v)
|
||||
case *ChainNode:
|
||||
Walk(&n.Node, v)
|
||||
case *MemberNode:
|
||||
Walk(&n.Node, v)
|
||||
Walk(&n.Property, v)
|
||||
case *SliceNode:
|
||||
Walk(&n.Node, v)
|
||||
if n.From != nil {
|
||||
Walk(&n.From, v)
|
||||
}
|
||||
if n.To != nil {
|
||||
Walk(&n.To, v)
|
||||
}
|
||||
case *CallNode:
|
||||
Walk(&n.Callee, v)
|
||||
for i := range n.Arguments {
|
||||
Walk(&n.Arguments[i], v)
|
||||
}
|
||||
case *BuiltinNode:
|
||||
for i := range n.Arguments {
|
||||
Walk(&n.Arguments[i], v)
|
||||
}
|
||||
case *PredicateNode:
|
||||
Walk(&n.Node, v)
|
||||
case *PointerNode:
|
||||
case *VariableDeclaratorNode:
|
||||
Walk(&n.Value, v)
|
||||
Walk(&n.Expr, v)
|
||||
case *SequenceNode:
|
||||
for i := range n.Nodes {
|
||||
Walk(&n.Nodes[i], v)
|
||||
}
|
||||
case *ConditionalNode:
|
||||
Walk(&n.Cond, v)
|
||||
Walk(&n.Exp1, v)
|
||||
Walk(&n.Exp2, v)
|
||||
case *ArrayNode:
|
||||
for i := range n.Nodes {
|
||||
Walk(&n.Nodes[i], v)
|
||||
}
|
||||
case *MapNode:
|
||||
for i := range n.Pairs {
|
||||
Walk(&n.Pairs[i], v)
|
||||
}
|
||||
case *PairNode:
|
||||
Walk(&n.Key, v)
|
||||
Walk(&n.Value, v)
|
||||
default:
|
||||
panic(fmt.Sprintf("undefined node type (%T)", node))
|
||||
}
|
||||
|
||||
v.Visit(node)
|
||||
}
|
||||
Reference in New Issue
Block a user