1 | # AbstractSyntaxTree
|
2 |
|
3 | You might find the class useful if you want to abstract away some ast manipulations such as adding, removing, replacing the nodes and others. The test folder is a good starting point for examples of usage. PRs are highly welcome.
|
4 |
|
5 | - [x] 100% coverage
|
6 |
|
7 | ## Installation
|
8 |
|
9 | `npm install --save @buxlabs/ast`
|
10 |
|
11 | ## Methods
|
12 |
|
13 | ### has
|
14 |
|
15 | Check if ast contains a node of given type.
|
16 |
|
17 | ```javascript
|
18 | var source = 'var a = "x";';
|
19 | var ast = new AbstractSyntaxTree(source);
|
20 | ast.has('VariableDeclaration');
|
21 | ```
|
22 |
|
23 | ### count
|
24 |
|
25 | Count ast nodes of given type.
|
26 |
|
27 | ```javascript
|
28 | var source = 'var a = "x"; var b = "y";';
|
29 | var ast = new AbstractSyntaxTree(source);
|
30 | ast.count('VariableDeclaration');
|
31 | ```
|
32 |
|
33 | ### find
|
34 |
|
35 | Find all nodes of given type.
|
36 |
|
37 | ```javascript
|
38 | var source = 'var a = "x";';
|
39 | var ast = new AbstractSyntaxTree(source);
|
40 | ast.find('VariableDeclaration');
|
41 | ```
|
42 |
|
43 | ```javascript
|
44 | var source = 'var a = "x";';
|
45 | var ast = new AbstractSyntaxTree(source, { engine: 'astq' });
|
46 | ast.find(`
|
47 | // VariableDeclarator [
|
48 | /:id Identifier [ @name ]
|
49 | && /:init Literal [ @value ]
|
50 | ]
|
51 | `, { engine: 'astq' });
|
52 | ```
|
53 |
|
54 | ### each
|
55 |
|
56 | Iterate over all nodes of given type.
|
57 |
|
58 | ```javascript
|
59 | var source = 'var a = "x";';
|
60 | var ast = new AbstractSyntaxTree(source);
|
61 | ast.each('VariableDeclaration', node => {
|
62 | console.log(node);
|
63 | });
|
64 | ```
|
65 |
|
66 | ### first
|
67 |
|
68 | First first node of given type.
|
69 |
|
70 | ```javascript
|
71 | var source = 'var a = "x";';
|
72 | var ast = new AbstractSyntaxTree(source);
|
73 | ast.first('VariableDeclaration');
|
74 | ```
|
75 |
|
76 | ### last
|
77 |
|
78 | Find last node of given type.
|
79 |
|
80 | ```javascript
|
81 | var source = 'var a = "x";';
|
82 | var ast = new AbstractSyntaxTree(source);
|
83 | ast.last('VariableDeclaration');
|
84 | ```
|
85 |
|
86 | ### remove
|
87 |
|
88 | Remove all nodes that match the criteria.
|
89 |
|
90 | ```javascript
|
91 | var source = '"use strict"; var b = 4;';
|
92 | var ast = new AbstractSyntaxTree(source);
|
93 | ast.remove({ type: 'Literal', value: 'use strict' });
|
94 | ```
|
95 |
|
96 | ```javascript
|
97 | var source = 'function hello () { var foo = "bar"; return "world"; }';
|
98 | var ast = new AbstractSyntaxTree(source);
|
99 | ast.remove('BlockStatement > VariableDeclaration');
|
100 | ```
|
101 |
|
102 | ### walk
|
103 |
|
104 | Walks over all nodes
|
105 |
|
106 | ```javascript
|
107 | var source = 'var a = 1';
|
108 | var ast = new AbstractSyntaxTree(source);
|
109 | ast.walk((node, parent) => {
|
110 | console.log(node, parent);
|
111 | });
|
112 | ```
|
113 |
|
114 | ### traverse
|
115 |
|
116 | Walks over all nodes
|
117 |
|
118 | ```javascript
|
119 | var source = 'var a = 1';
|
120 | var ast = new AbstractSyntaxTree(source);
|
121 | ast.walk({
|
122 | enter: function (node) {
|
123 | console.log(node);
|
124 | },
|
125 | leave: function (node) {
|
126 | console.log(node);
|
127 | }
|
128 | });
|
129 | ```
|
130 |
|
131 | ### replace
|
132 |
|
133 | Replace all nodes that match the criteria.
|
134 |
|
135 | ```javascript
|
136 | var source = 'var a = 1';
|
137 | var ast = new AbstractSyntaxTree(source);
|
138 | ast.replace({
|
139 | enter: function (node) {
|
140 | if (node.type === 'VariableDeclaration') {
|
141 | node.kind = 'let';
|
142 | }
|
143 | return node;
|
144 | }
|
145 | });
|
146 | ```
|
147 |
|
148 | ### prepend
|
149 |
|
150 | Prepend a node to the body.
|
151 |
|
152 | ```javascript
|
153 | var source = 'var a = 1;';
|
154 | var ast = new AbstractSyntaxTree(source);
|
155 | ast.prepend({
|
156 | type: 'ExpressionStatement',
|
157 | expression: {
|
158 | type: 'Literal',
|
159 | value: 'use strict'
|
160 | }
|
161 | });
|
162 | ```
|
163 |
|
164 | ### append
|
165 |
|
166 | Append a node to the body.
|
167 |
|
168 | ```javascript
|
169 | var source = 'var a = 1;';
|
170 | var ast = new AbstractSyntaxTree(source);
|
171 | ast.append({
|
172 | type: 'ExpressionStatement',
|
173 | expression: {
|
174 | type: 'Literal',
|
175 | value: 'test'
|
176 | }
|
177 | });
|
178 | ```
|
179 |
|
180 | ### wrap
|
181 |
|
182 | Wrap body with given node.
|
183 |
|
184 | ```javascript
|
185 | var source = 'var a = 1;';
|
186 | var ast = new AbstractSyntaxTree(source);
|
187 | ast.wrap(body => {
|
188 | return [
|
189 | {
|
190 | "type": "ExpressionStatement",
|
191 | "expression": {
|
192 | "type": "CallExpression",
|
193 | "callee": {
|
194 | "type": "FunctionExpression",
|
195 | "id": null,
|
196 | "params": [],
|
197 | "defaults": [],
|
198 | "body": {
|
199 | "type": "BlockStatement",
|
200 | "body": body
|
201 | },
|
202 | "rest": null,
|
203 | "generator": false,
|
204 | "expression": false
|
205 | },
|
206 | "arguments": []
|
207 | }
|
208 | }
|
209 | ];
|
210 | });
|
211 | ```
|
212 |
|
213 | ### unwrap
|
214 |
|
215 | Change the code to the first BlockStatement body
|
216 |
|
217 | ```javascript
|
218 | var source = '(function () { console.log(1); }())';
|
219 | var ast = new AbstractSyntaxTree(source);
|
220 | ast.unwrap();
|
221 | ast.toSource();
|
222 | ```
|
223 |
|
224 | ### template
|
225 |
|
226 | Create ast partials from templates
|
227 |
|
228 | ```javascript
|
229 | var source = 'console.log(1);';
|
230 | var ast = new AbstractSyntaxTree(source);
|
231 | ast.template('var foo = <%= bar %>;' { bar: { type: 'Literal', value: 1 } });
|
232 | ```
|
233 |
|
234 | ### toSource / toString
|
235 |
|
236 | Convert the ast to string.
|
237 |
|
238 | ```javascript
|
239 | var source = 'var a = 1;';
|
240 | var ast = new AbstractSyntaxTree(source);
|
241 | ast.toSource();
|
242 | ```
|