visitor.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package ast
  2. import (
  3. "reflect"
  4. )
  5. type Visitor interface {
  6. Visit(Node) bool
  7. }
  8. func Walk(v Visitor, node Node) {
  9. if node == nil || reflect.ValueOf(node).IsNil() {
  10. return
  11. }
  12. if !v.Visit(node) {
  13. return
  14. }
  15. switch n := node.(type) {
  16. case *SelectStatement:
  17. Walk(v, n.Fields)
  18. Walk(v, n.Sources)
  19. Walk(v, n.Joins)
  20. Walk(v, n.Condition)
  21. Walk(v, n.Dimensions)
  22. Walk(v, n.Having)
  23. Walk(v, n.SortFields)
  24. case Fields:
  25. for _, f := range n {
  26. Walk(v, &f)
  27. }
  28. case *Field:
  29. Walk(v, n.Expr)
  30. if fr, ok := n.Expr.(*FieldRef); ok && fr.IsAlias() {
  31. Walk(v, fr.Expression)
  32. }
  33. case Sources:
  34. for _, s := range n {
  35. Walk(v, s)
  36. }
  37. //case *Table:
  38. case Joins:
  39. for _, s := range n {
  40. Walk(v, &s)
  41. }
  42. case *Join:
  43. Walk(v, n.Expr)
  44. case Dimensions:
  45. Walk(v, n.GetWindow())
  46. for _, dimension := range n.GetGroups() {
  47. Walk(v, dimension.Expr)
  48. }
  49. case *Window:
  50. Walk(v, n.Length)
  51. Walk(v, n.Interval)
  52. Walk(v, n.Filter)
  53. case SortFields:
  54. for _, sf := range n {
  55. Walk(v, &sf)
  56. }
  57. //case *SortField:
  58. case *BinaryExpr:
  59. Walk(v, n.LHS)
  60. Walk(v, n.RHS)
  61. case *Call:
  62. for _, expr := range n.Args {
  63. Walk(v, expr)
  64. }
  65. case *ParenExpr:
  66. Walk(v, n.Expr)
  67. case *CaseExpr:
  68. Walk(v, n.Value)
  69. for _, w := range n.WhenClauses {
  70. Walk(v, w)
  71. }
  72. Walk(v, n.ElseClause)
  73. case *WhenClause:
  74. Walk(v, n.Expr)
  75. Walk(v, n.Result)
  76. }
  77. }
  78. // WalkFunc traverses a node hierarchy in depth-first order.
  79. func WalkFunc(node Node, fn func(Node) bool) {
  80. Walk(walkFuncVisitor(fn), node)
  81. }
  82. type walkFuncVisitor func(Node) bool
  83. func (fn walkFuncVisitor) Visit(n Node) bool { return fn(n) }