1 | # Acorn AST walker
|
2 |
|
3 | An abstract syntax tree walker for the
|
4 | [ESTree](https://github.com/estree/estree) format.
|
5 |
|
6 | ## Community
|
7 |
|
8 | Acorn is open source software released under an
|
9 | [MIT license](https://github.com/acornjs/acorn/blob/master/acorn-walk/LICENSE).
|
10 |
|
11 | You are welcome to
|
12 | [report bugs](https://github.com/acornjs/acorn/issues) or create pull
|
13 | requests on [github](https://github.com/acornjs/acorn). For questions
|
14 | and discussion, please use the
|
15 | [Tern discussion forum](https://discuss.ternjs.net).
|
16 |
|
17 | ## Installation
|
18 |
|
19 | The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
|
20 |
|
21 | ```sh
|
22 | npm install acorn-walk
|
23 | ```
|
24 |
|
25 | Alternately, you can download the source and build acorn yourself:
|
26 |
|
27 | ```sh
|
28 | git clone https://github.com/acornjs/acorn.git
|
29 | cd acorn
|
30 | npm install
|
31 | ```
|
32 |
|
33 | ## Interface
|
34 |
|
35 | An algorithm for recursing through a syntax tree is stored as an
|
36 | object, with a property for each tree node type holding a function
|
37 | that will recurse through such a node. There are several ways to run
|
38 | such a walker.
|
39 |
|
40 | **simple**`(node, visitors, base, state)` does a 'simple' walk over a
|
41 | tree. `node` should be the AST node to walk, and `visitors` an object
|
42 | with properties whose names correspond to node types in the [ESTree
|
43 | spec](https://github.com/estree/estree). The properties should contain
|
44 | functions that will be called with the node object and, if applicable
|
45 | the state at that point. The last two arguments are optional. `base`
|
46 | is a walker algorithm, and `state` is a start state. The default
|
47 | walker will simply visit all statements and expressions and not
|
48 | produce a meaningful state. (An example of a use of state is to track
|
49 | scope at each point in the tree.)
|
50 |
|
51 | ```js
|
52 | const acorn = require("acorn")
|
53 | const walk = require("acorn-walk")
|
54 |
|
55 | walk.simple(acorn.parse("let x = 10"), {
|
56 | Literal(node) {
|
57 | console.log(`Found a literal: ${node.value}`)
|
58 | }
|
59 | })
|
60 | ```
|
61 |
|
62 | **ancestor**`(node, visitors, base, state)` does a 'simple' walk over
|
63 | a tree, building up an array of ancestor nodes (including the current node)
|
64 | and passing the array to the callbacks as a third parameter.
|
65 |
|
66 | ```js
|
67 | const acorn = require("acorn")
|
68 | const walk = require("acorn-walk")
|
69 |
|
70 | walk.ancestor(acorn.parse("foo('hi')"), {
|
71 | Literal(_, ancestors) {
|
72 | console.log("This literal's ancestors are:", ancestors.map(n => n.type))
|
73 | }
|
74 | })
|
75 | ```
|
76 |
|
77 | **recursive**`(node, state, functions, base)` does a 'recursive'
|
78 | walk, where the walker functions are responsible for continuing the
|
79 | walk on the child nodes of their target node. `state` is the start
|
80 | state, and `functions` should contain an object that maps node types
|
81 | to walker functions. Such functions are called with `(node, state, c)`
|
82 | arguments, and can cause the walk to continue on a sub-node by calling
|
83 | the `c` argument on it with `(node, state)` arguments. The optional
|
84 | `base` argument provides the fallback walker functions for node types
|
85 | that aren't handled in the `functions` object. If not given, the
|
86 | default walkers will be used.
|
87 |
|
88 | **make**`(functions, base)` builds a new walker object by using the
|
89 | walker functions in `functions` and filling in the missing ones by
|
90 | taking defaults from `base`.
|
91 |
|
92 | **full**`(node, callback, base, state)` does a 'full' walk over a
|
93 | tree, calling the callback with the arguments (node, state, type) for
|
94 | each node
|
95 |
|
96 | **fullAncestor**`(node, callback, base, state)` does a 'full' walk
|
97 | over a tree, building up an array of ancestor nodes (including the
|
98 | current node) and passing the array to the callbacks as a third
|
99 | parameter.
|
100 |
|
101 | ```js
|
102 | const acorn = require("acorn")
|
103 | const walk = require("acorn-walk")
|
104 |
|
105 | walk.full(acorn.parse("1 + 1"), node => {
|
106 | console.log(`There's a ${node.type} node at ${node.ch}`)
|
107 | })
|
108 | ```
|
109 |
|
110 | **findNodeAt**`(node, start, end, test, base, state)` tries to locate
|
111 | a node in a tree at the given start and/or end offsets, which
|
112 | satisfies the predicate `test`. `start` and `end` can be either `null`
|
113 | (as wildcard) or a number. `test` may be a string (indicating a node
|
114 | type) or a function that takes `(nodeType, node)` arguments and
|
115 | returns a boolean indicating whether this node is interesting. `base`
|
116 | and `state` are optional, and can be used to specify a custom walker.
|
117 | Nodes are tested from inner to outer, so if two nodes match the
|
118 | boundaries, the inner one will be preferred.
|
119 |
|
120 | **findNodeAround**`(node, pos, test, base, state)` is a lot like
|
121 | `findNodeAt`, but will match any node that exists 'around' (spanning)
|
122 | the given position.
|
123 |
|
124 | **findNodeAfter**`(node, pos, test, base, state)` is similar to
|
125 | `findNodeAround`, but will match all nodes *after* the given position
|
126 | (testing outer nodes before inner nodes).
|