UNPKG

2.8 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8var _path = require("./path");
9
10var _t = require("@babel/types");
11
12const {
13 VISITOR_KEYS
14} = _t;
15
16class TraversalContext {
17 constructor(scope, opts, state, parentPath) {
18 this.queue = null;
19 this.priorityQueue = null;
20 this.parentPath = parentPath;
21 this.scope = scope;
22 this.state = state;
23 this.opts = opts;
24 }
25
26 shouldVisit(node) {
27 const opts = this.opts;
28 if (opts.enter || opts.exit) return true;
29 if (opts[node.type]) return true;
30 const keys = VISITOR_KEYS[node.type];
31 if (!(keys != null && keys.length)) return false;
32
33 for (const key of keys) {
34 if (node[key]) return true;
35 }
36
37 return false;
38 }
39
40 create(node, obj, key, listKey) {
41 return _path.default.get({
42 parentPath: this.parentPath,
43 parent: node,
44 container: obj,
45 key: key,
46 listKey
47 });
48 }
49
50 maybeQueue(path, notPriority) {
51 if (this.queue) {
52 if (notPriority) {
53 this.queue.push(path);
54 } else {
55 this.priorityQueue.push(path);
56 }
57 }
58 }
59
60 visitMultiple(container, parent, listKey) {
61 if (container.length === 0) return false;
62 const queue = [];
63
64 for (let key = 0; key < container.length; key++) {
65 const node = container[key];
66
67 if (node && this.shouldVisit(node)) {
68 queue.push(this.create(parent, container, key, listKey));
69 }
70 }
71
72 return this.visitQueue(queue);
73 }
74
75 visitSingle(node, key) {
76 if (this.shouldVisit(node[key])) {
77 return this.visitQueue([this.create(node, node, key)]);
78 } else {
79 return false;
80 }
81 }
82
83 visitQueue(queue) {
84 this.queue = queue;
85 this.priorityQueue = [];
86 const visited = new WeakSet();
87 let stop = false;
88
89 for (const path of queue) {
90 path.resync();
91
92 if (path.contexts.length === 0 || path.contexts[path.contexts.length - 1] !== this) {
93 path.pushContext(this);
94 }
95
96 if (path.key === null) continue;
97 const {
98 node
99 } = path;
100 if (visited.has(node)) continue;
101 if (node) visited.add(node);
102
103 if (path.visit()) {
104 stop = true;
105 break;
106 }
107
108 if (this.priorityQueue.length) {
109 stop = this.visitQueue(this.priorityQueue);
110 this.priorityQueue = [];
111 this.queue = queue;
112 if (stop) break;
113 }
114 }
115
116 for (const path of queue) {
117 path.popContext();
118 }
119
120 this.queue = null;
121 return stop;
122 }
123
124 visit(node, key) {
125 const nodes = node[key];
126 if (!nodes) return false;
127
128 if (Array.isArray(nodes)) {
129 return this.visitMultiple(nodes, node, key);
130 } else {
131 return this.visitSingle(node, key);
132 }
133 }
134
135}
136
137exports.default = TraversalContext;
\No newline at end of file