source: node_modules/estree-walker/dist/umd/estree-walker.js

Last change on this file was 57e58a3, checked in by ste08 <sjovanoska@…>, 4 months ago

Initial commit

  • Property mode set to 100644
File size: 7.6 KB
Line 
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = global || self, factory(global.estreeWalker = {}));
5}(this, (function (exports) { 'use strict';
6
7 // @ts-check
8 /** @typedef { import('estree').BaseNode} BaseNode */
9
10 /** @typedef {{
11 skip: () => void;
12 remove: () => void;
13 replace: (node: BaseNode) => void;
14 }} WalkerContext */
15
16 class WalkerBase {
17 constructor() {
18 /** @type {boolean} */
19 this.should_skip = false;
20
21 /** @type {boolean} */
22 this.should_remove = false;
23
24 /** @type {BaseNode | null} */
25 this.replacement = null;
26
27 /** @type {WalkerContext} */
28 this.context = {
29 skip: () => (this.should_skip = true),
30 remove: () => (this.should_remove = true),
31 replace: (node) => (this.replacement = node)
32 };
33 }
34
35 /**
36 *
37 * @param {any} parent
38 * @param {string} prop
39 * @param {number} index
40 * @param {BaseNode} node
41 */
42 replace(parent, prop, index, node) {
43 if (parent) {
44 if (index !== null) {
45 parent[prop][index] = node;
46 } else {
47 parent[prop] = node;
48 }
49 }
50 }
51
52 /**
53 *
54 * @param {any} parent
55 * @param {string} prop
56 * @param {number} index
57 */
58 remove(parent, prop, index) {
59 if (parent) {
60 if (index !== null) {
61 parent[prop].splice(index, 1);
62 } else {
63 delete parent[prop];
64 }
65 }
66 }
67 }
68
69 // @ts-check
70
71 /** @typedef { import('estree').BaseNode} BaseNode */
72 /** @typedef { import('./walker.js').WalkerContext} WalkerContext */
73
74 /** @typedef {(
75 * this: WalkerContext,
76 * node: BaseNode,
77 * parent: BaseNode,
78 * key: string,
79 * index: number
80 * ) => void} SyncHandler */
81
82 class SyncWalker extends WalkerBase {
83 /**
84 *
85 * @param {SyncHandler} enter
86 * @param {SyncHandler} leave
87 */
88 constructor(enter, leave) {
89 super();
90
91 /** @type {SyncHandler} */
92 this.enter = enter;
93
94 /** @type {SyncHandler} */
95 this.leave = leave;
96 }
97
98 /**
99 *
100 * @param {BaseNode} node
101 * @param {BaseNode} parent
102 * @param {string} [prop]
103 * @param {number} [index]
104 * @returns {BaseNode}
105 */
106 visit(node, parent, prop, index) {
107 if (node) {
108 if (this.enter) {
109 const _should_skip = this.should_skip;
110 const _should_remove = this.should_remove;
111 const _replacement = this.replacement;
112 this.should_skip = false;
113 this.should_remove = false;
114 this.replacement = null;
115
116 this.enter.call(this.context, node, parent, prop, index);
117
118 if (this.replacement) {
119 node = this.replacement;
120 this.replace(parent, prop, index, node);
121 }
122
123 if (this.should_remove) {
124 this.remove(parent, prop, index);
125 }
126
127 const skipped = this.should_skip;
128 const removed = this.should_remove;
129
130 this.should_skip = _should_skip;
131 this.should_remove = _should_remove;
132 this.replacement = _replacement;
133
134 if (skipped) return node;
135 if (removed) return null;
136 }
137
138 for (const key in node) {
139 const value = node[key];
140
141 if (typeof value !== "object") {
142 continue;
143 } else if (Array.isArray(value)) {
144 for (let i = 0; i < value.length; i += 1) {
145 if (value[i] !== null && typeof value[i].type === 'string') {
146 if (!this.visit(value[i], node, key, i)) {
147 // removed
148 i--;
149 }
150 }
151 }
152 } else if (value !== null && typeof value.type === "string") {
153 this.visit(value, node, key, null);
154 }
155 }
156
157 if (this.leave) {
158 const _replacement = this.replacement;
159 const _should_remove = this.should_remove;
160 this.replacement = null;
161 this.should_remove = false;
162
163 this.leave.call(this.context, node, parent, prop, index);
164
165 if (this.replacement) {
166 node = this.replacement;
167 this.replace(parent, prop, index, node);
168 }
169
170 if (this.should_remove) {
171 this.remove(parent, prop, index);
172 }
173
174 const removed = this.should_remove;
175
176 this.replacement = _replacement;
177 this.should_remove = _should_remove;
178
179 if (removed) return null;
180 }
181 }
182
183 return node;
184 }
185 }
186
187 // @ts-check
188
189 /** @typedef { import('estree').BaseNode} BaseNode */
190 /** @typedef { import('./walker').WalkerContext} WalkerContext */
191
192 /** @typedef {(
193 * this: WalkerContext,
194 * node: BaseNode,
195 * parent: BaseNode,
196 * key: string,
197 * index: number
198 * ) => Promise<void>} AsyncHandler */
199
200 class AsyncWalker extends WalkerBase {
201 /**
202 *
203 * @param {AsyncHandler} enter
204 * @param {AsyncHandler} leave
205 */
206 constructor(enter, leave) {
207 super();
208
209 /** @type {AsyncHandler} */
210 this.enter = enter;
211
212 /** @type {AsyncHandler} */
213 this.leave = leave;
214 }
215
216 /**
217 *
218 * @param {BaseNode} node
219 * @param {BaseNode} parent
220 * @param {string} [prop]
221 * @param {number} [index]
222 * @returns {Promise<BaseNode>}
223 */
224 async visit(node, parent, prop, index) {
225 if (node) {
226 if (this.enter) {
227 const _should_skip = this.should_skip;
228 const _should_remove = this.should_remove;
229 const _replacement = this.replacement;
230 this.should_skip = false;
231 this.should_remove = false;
232 this.replacement = null;
233
234 await this.enter.call(this.context, node, parent, prop, index);
235
236 if (this.replacement) {
237 node = this.replacement;
238 this.replace(parent, prop, index, node);
239 }
240
241 if (this.should_remove) {
242 this.remove(parent, prop, index);
243 }
244
245 const skipped = this.should_skip;
246 const removed = this.should_remove;
247
248 this.should_skip = _should_skip;
249 this.should_remove = _should_remove;
250 this.replacement = _replacement;
251
252 if (skipped) return node;
253 if (removed) return null;
254 }
255
256 for (const key in node) {
257 const value = node[key];
258
259 if (typeof value !== "object") {
260 continue;
261 } else if (Array.isArray(value)) {
262 for (let i = 0; i < value.length; i += 1) {
263 if (value[i] !== null && typeof value[i].type === 'string') {
264 if (!(await this.visit(value[i], node, key, i))) {
265 // removed
266 i--;
267 }
268 }
269 }
270 } else if (value !== null && typeof value.type === "string") {
271 await this.visit(value, node, key, null);
272 }
273 }
274
275 if (this.leave) {
276 const _replacement = this.replacement;
277 const _should_remove = this.should_remove;
278 this.replacement = null;
279 this.should_remove = false;
280
281 await this.leave.call(this.context, node, parent, prop, index);
282
283 if (this.replacement) {
284 node = this.replacement;
285 this.replace(parent, prop, index, node);
286 }
287
288 if (this.should_remove) {
289 this.remove(parent, prop, index);
290 }
291
292 const removed = this.should_remove;
293
294 this.replacement = _replacement;
295 this.should_remove = _should_remove;
296
297 if (removed) return null;
298 }
299 }
300
301 return node;
302 }
303 }
304
305 // @ts-check
306
307 /** @typedef { import('estree').BaseNode} BaseNode */
308 /** @typedef { import('./sync.js').SyncHandler} SyncHandler */
309 /** @typedef { import('./async.js').AsyncHandler} AsyncHandler */
310
311 /**
312 *
313 * @param {BaseNode} ast
314 * @param {{
315 * enter?: SyncHandler
316 * leave?: SyncHandler
317 * }} walker
318 * @returns {BaseNode}
319 */
320 function walk(ast, { enter, leave }) {
321 const instance = new SyncWalker(enter, leave);
322 return instance.visit(ast, null);
323 }
324
325 /**
326 *
327 * @param {BaseNode} ast
328 * @param {{
329 * enter?: AsyncHandler
330 * leave?: AsyncHandler
331 * }} walker
332 * @returns {Promise<BaseNode>}
333 */
334 async function asyncWalk(ast, { enter, leave }) {
335 const instance = new AsyncWalker(enter, leave);
336 return await instance.visit(ast, null);
337 }
338
339 exports.asyncWalk = asyncWalk;
340 exports.walk = walk;
341
342 Object.defineProperty(exports, '__esModule', { value: true });
343
344})));
Note: See TracBrowser for help on using the repository browser.