source: node_modules/estree-walker/src/async.js@ 57e58a3

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

Initial commit

  • Property mode set to 100644
File size: 2.6 KB
Line 
1// @ts-check
2import { WalkerBase } from './walker.js';
3
4/** @typedef { import('estree').BaseNode} BaseNode */
5/** @typedef { import('./walker').WalkerContext} WalkerContext */
6
7/** @typedef {(
8 * this: WalkerContext,
9 * node: BaseNode,
10 * parent: BaseNode,
11 * key: string,
12 * index: number
13 * ) => Promise<void>} AsyncHandler */
14
15export class AsyncWalker extends WalkerBase {
16 /**
17 *
18 * @param {AsyncHandler} enter
19 * @param {AsyncHandler} leave
20 */
21 constructor(enter, leave) {
22 super();
23
24 /** @type {AsyncHandler} */
25 this.enter = enter;
26
27 /** @type {AsyncHandler} */
28 this.leave = leave;
29 }
30
31 /**
32 *
33 * @param {BaseNode} node
34 * @param {BaseNode} parent
35 * @param {string} [prop]
36 * @param {number} [index]
37 * @returns {Promise<BaseNode>}
38 */
39 async visit(node, parent, prop, index) {
40 if (node) {
41 if (this.enter) {
42 const _should_skip = this.should_skip;
43 const _should_remove = this.should_remove;
44 const _replacement = this.replacement;
45 this.should_skip = false;
46 this.should_remove = false;
47 this.replacement = null;
48
49 await this.enter.call(this.context, node, parent, prop, index);
50
51 if (this.replacement) {
52 node = this.replacement;
53 this.replace(parent, prop, index, node);
54 }
55
56 if (this.should_remove) {
57 this.remove(parent, prop, index);
58 }
59
60 const skipped = this.should_skip;
61 const removed = this.should_remove;
62
63 this.should_skip = _should_skip;
64 this.should_remove = _should_remove;
65 this.replacement = _replacement;
66
67 if (skipped) return node;
68 if (removed) return null;
69 }
70
71 for (const key in node) {
72 const value = node[key];
73
74 if (typeof value !== "object") {
75 continue;
76 } else if (Array.isArray(value)) {
77 for (let i = 0; i < value.length; i += 1) {
78 if (value[i] !== null && typeof value[i].type === 'string') {
79 if (!(await this.visit(value[i], node, key, i))) {
80 // removed
81 i--;
82 }
83 }
84 }
85 } else if (value !== null && typeof value.type === "string") {
86 await this.visit(value, node, key, null);
87 }
88 }
89
90 if (this.leave) {
91 const _replacement = this.replacement;
92 const _should_remove = this.should_remove;
93 this.replacement = null;
94 this.should_remove = false;
95
96 await this.leave.call(this.context, node, parent, prop, index);
97
98 if (this.replacement) {
99 node = this.replacement;
100 this.replace(parent, prop, index, node);
101 }
102
103 if (this.should_remove) {
104 this.remove(parent, prop, index);
105 }
106
107 const removed = this.should_remove;
108
109 this.replacement = _replacement;
110 this.should_remove = _should_remove;
111
112 if (removed) return null;
113 }
114 }
115
116 return node;
117 }
118}
Note: See TracBrowser for help on using the repository browser.