VisitExpressionTree walks through an expression tree and calls the visitor function for each ExpressionNode (literal expression) found in the tree
(node ConditionNode, visitor func(expr *ExpressionNode) error)
| 284 | // VisitExpressionTree walks through an expression tree and calls the visitor function |
| 285 | // for each ExpressionNode (literal expression) found in the tree |
| 286 | func VisitExpressionTree(node ConditionNode, visitor func(expr *ExpressionNode) error) error { |
| 287 | if node == nil { |
| 288 | expressionsLog.Print("VisitExpressionTree called with nil node") |
| 289 | return nil |
| 290 | } |
| 291 | |
| 292 | switch n := node.(type) { |
| 293 | case *ExpressionNode: |
| 294 | return visitor(n) |
| 295 | case *AndNode: |
| 296 | if err := VisitExpressionTree(n.Left, visitor); err != nil { |
| 297 | return err |
| 298 | } |
| 299 | return VisitExpressionTree(n.Right, visitor) |
| 300 | case *OrNode: |
| 301 | if err := VisitExpressionTree(n.Left, visitor); err != nil { |
| 302 | return err |
| 303 | } |
| 304 | return VisitExpressionTree(n.Right, visitor) |
| 305 | case *NotNode: |
| 306 | return VisitExpressionTree(n.Child, visitor) |
| 307 | case *DisjunctionNode: |
| 308 | for _, term := range n.Terms { |
| 309 | if err := VisitExpressionTree(term, visitor); err != nil { |
| 310 | return err |
| 311 | } |
| 312 | } |
| 313 | default: |
| 314 | // For other node types (ComparisonNode, PropertyAccessNode, etc.) |
| 315 | // we don't recurse since they represent complete literal expressions |
| 316 | return nil |
| 317 | } |
| 318 | |
| 319 | return nil |
| 320 | } |
| 321 | |
| 322 | // BreakLongExpression breaks a long expression into multiple lines at logical points |
| 323 | // such as after || and && operators for better readability |