walk.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package js
  2. // IVisitor represents the AST Visitor
  3. // Each INode encountered by `Walk` is passed to `Enter`, children nodes will be ignored if the returned IVisitor is nil
  4. // `Exit` is called upon the exit of a node
  5. type IVisitor interface {
  6. Enter(n INode) IVisitor
  7. Exit(n INode)
  8. }
  9. // Walk traverses an AST in depth-first order
  10. func Walk(v IVisitor, n INode) {
  11. if n == nil {
  12. return
  13. }
  14. if v = v.Enter(n); v == nil {
  15. return
  16. }
  17. defer v.Exit(n)
  18. switch n := n.(type) {
  19. case *AST:
  20. Walk(v, &n.BlockStmt)
  21. case *Var:
  22. return
  23. case *BlockStmt:
  24. if n.List != nil {
  25. for i := 0; i < len(n.List); i++ {
  26. Walk(v, n.List[i])
  27. }
  28. }
  29. case *EmptyStmt:
  30. return
  31. case *ExprStmt:
  32. Walk(v, n.Value)
  33. case *IfStmt:
  34. Walk(v, n.Body)
  35. Walk(v, n.Else)
  36. Walk(v, n.Cond)
  37. case *DoWhileStmt:
  38. Walk(v, n.Body)
  39. Walk(v, n.Cond)
  40. case *WhileStmt:
  41. Walk(v, n.Body)
  42. Walk(v, n.Cond)
  43. case *ForStmt:
  44. if n.Body != nil {
  45. Walk(v, n.Body)
  46. }
  47. Walk(v, n.Init)
  48. Walk(v, n.Cond)
  49. Walk(v, n.Post)
  50. case *ForInStmt:
  51. if n.Body != nil {
  52. Walk(v, n.Body)
  53. }
  54. Walk(v, n.Init)
  55. Walk(v, n.Value)
  56. case *ForOfStmt:
  57. if n.Body != nil {
  58. Walk(v, n.Body)
  59. }
  60. Walk(v, n.Init)
  61. Walk(v, n.Value)
  62. case *CaseClause:
  63. if n.List != nil {
  64. for i := 0; i < len(n.List); i++ {
  65. Walk(v, n.List[i])
  66. }
  67. }
  68. Walk(v, n.Cond)
  69. case *SwitchStmt:
  70. if n.List != nil {
  71. for i := 0; i < len(n.List); i++ {
  72. Walk(v, &n.List[i])
  73. }
  74. }
  75. Walk(v, n.Init)
  76. case *BranchStmt:
  77. return
  78. case *ReturnStmt:
  79. Walk(v, n.Value)
  80. case *WithStmt:
  81. Walk(v, n.Body)
  82. Walk(v, n.Cond)
  83. case *LabelledStmt:
  84. Walk(v, n.Value)
  85. case *ThrowStmt:
  86. Walk(v, n.Value)
  87. case *TryStmt:
  88. if n.Body != nil {
  89. Walk(v, n.Body)
  90. }
  91. if n.Catch != nil {
  92. Walk(v, n.Catch)
  93. }
  94. if n.Finally != nil {
  95. Walk(v, n.Finally)
  96. }
  97. Walk(v, n.Binding)
  98. case *DebuggerStmt:
  99. return
  100. case *Alias:
  101. return
  102. case *ImportStmt:
  103. if n.List != nil {
  104. for i := 0; i < len(n.List); i++ {
  105. Walk(v, &n.List[i])
  106. }
  107. }
  108. case *ExportStmt:
  109. if n.List != nil {
  110. for i := 0; i < len(n.List); i++ {
  111. Walk(v, &n.List[i])
  112. }
  113. }
  114. Walk(v, n.Decl)
  115. case *DirectivePrologueStmt:
  116. return
  117. case *PropertyName:
  118. Walk(v, &n.Literal)
  119. Walk(v, n.Computed)
  120. case *BindingArray:
  121. if n.List != nil {
  122. for i := 0; i < len(n.List); i++ {
  123. Walk(v, &n.List[i])
  124. }
  125. }
  126. Walk(v, n.Rest)
  127. case *BindingObjectItem:
  128. if n.Key != nil {
  129. Walk(v, n.Key)
  130. }
  131. Walk(v, &n.Value)
  132. case *BindingObject:
  133. if n.List != nil {
  134. for i := 0; i < len(n.List); i++ {
  135. Walk(v, &n.List[i])
  136. }
  137. }
  138. if n.Rest != nil {
  139. Walk(v, n.Rest)
  140. }
  141. case *BindingElement:
  142. Walk(v, n.Binding)
  143. Walk(v, n.Default)
  144. case *VarDecl:
  145. if n.List != nil {
  146. for i := 0; i < len(n.List); i++ {
  147. Walk(v, &n.List[i])
  148. }
  149. }
  150. case *Params:
  151. if n.List != nil {
  152. for i := 0; i < len(n.List); i++ {
  153. Walk(v, &n.List[i])
  154. }
  155. }
  156. Walk(v, n.Rest)
  157. case *FuncDecl:
  158. Walk(v, &n.Body)
  159. Walk(v, &n.Params)
  160. if n.Name != nil {
  161. Walk(v, n.Name)
  162. }
  163. case *MethodDecl:
  164. Walk(v, &n.Body)
  165. Walk(v, &n.Params)
  166. Walk(v, &n.Name)
  167. case *Field:
  168. Walk(v, &n.Name)
  169. Walk(v, n.Init)
  170. case *ClassDecl:
  171. if n.Name != nil {
  172. Walk(v, n.Name)
  173. }
  174. Walk(v, n.Extends)
  175. for _, item := range n.List {
  176. if item.StaticBlock != nil {
  177. Walk(v, item.StaticBlock)
  178. } else if item.Method != nil {
  179. Walk(v, item.Method)
  180. } else {
  181. Walk(v, &item.Field)
  182. }
  183. }
  184. case *LiteralExpr:
  185. return
  186. case *Element:
  187. Walk(v, n.Value)
  188. case *ArrayExpr:
  189. if n.List != nil {
  190. for i := 0; i < len(n.List); i++ {
  191. Walk(v, &n.List[i])
  192. }
  193. }
  194. case *Property:
  195. if n.Name != nil {
  196. Walk(v, n.Name)
  197. }
  198. Walk(v, n.Value)
  199. Walk(v, n.Init)
  200. case *ObjectExpr:
  201. if n.List != nil {
  202. for i := 0; i < len(n.List); i++ {
  203. Walk(v, &n.List[i])
  204. }
  205. }
  206. case *TemplatePart:
  207. Walk(v, n.Expr)
  208. case *TemplateExpr:
  209. if n.List != nil {
  210. for i := 0; i < len(n.List); i++ {
  211. Walk(v, &n.List[i])
  212. }
  213. }
  214. Walk(v, n.Tag)
  215. case *GroupExpr:
  216. Walk(v, n.X)
  217. case *IndexExpr:
  218. Walk(v, n.X)
  219. Walk(v, n.Y)
  220. case *DotExpr:
  221. Walk(v, n.X)
  222. Walk(v, &n.Y)
  223. case *NewTargetExpr:
  224. return
  225. case *ImportMetaExpr:
  226. return
  227. case *Arg:
  228. Walk(v, n.Value)
  229. case *Args:
  230. if n.List != nil {
  231. for i := 0; i < len(n.List); i++ {
  232. Walk(v, &n.List[i])
  233. }
  234. }
  235. case *NewExpr:
  236. if n.Args != nil {
  237. Walk(v, n.Args)
  238. }
  239. Walk(v, n.X)
  240. case *CallExpr:
  241. Walk(v, &n.Args)
  242. Walk(v, n.X)
  243. case *UnaryExpr:
  244. Walk(v, n.X)
  245. case *BinaryExpr:
  246. Walk(v, n.X)
  247. Walk(v, n.Y)
  248. case *CondExpr:
  249. Walk(v, n.Cond)
  250. Walk(v, n.X)
  251. Walk(v, n.Y)
  252. case *YieldExpr:
  253. Walk(v, n.X)
  254. case *ArrowFunc:
  255. Walk(v, &n.Body)
  256. Walk(v, &n.Params)
  257. case *CommaExpr:
  258. for _, item := range n.List {
  259. Walk(v, item)
  260. }
  261. default:
  262. return
  263. }
  264. }