UNPKG

5.78 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.explode = explode;
5exports.verify = verify;
6exports.merge = merge;
7// istanbul ignore next
8
9function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
10
11// istanbul ignore next
12
13function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }
14
15var _pathLibVirtualTypes = require("./path/lib/virtual-types");
16
17var virtualTypes = _interopRequireWildcard(_pathLibVirtualTypes);
18
19var _messages = require("../messages");
20
21var messages = _interopRequireWildcard(_messages);
22
23var _types = require("../types");
24
25var t = _interopRequireWildcard(_types);
26
27var _lodashLangClone = require("lodash/lang/clone");
28
29var _lodashLangClone2 = _interopRequireDefault(_lodashLangClone);
30
31/**
32 * [Please add a description.]
33 */
34
35function explode(visitor) {
36 if (visitor._exploded) return visitor;
37 visitor._exploded = true;
38
39 // normalise pipes
40 for (var nodeType in visitor) {
41 if (shouldIgnoreKey(nodeType)) continue;
42
43 var parts = nodeType.split("|");
44 if (parts.length === 1) continue;
45
46 var fns = visitor[nodeType];
47 delete visitor[nodeType];
48
49 var _arr = parts;
50 for (var _i = 0; _i < _arr.length; _i++) {
51 var part = _arr[_i];
52 visitor[part] = fns;
53 }
54 }
55
56 // verify data structure
57 verify(visitor);
58
59 // make sure there's no __esModule type since this is because we're using loose mode
60 // and it sets __esModule to be enumerable on all modules :(
61 delete visitor.__esModule;
62
63 // ensure visitors are objects
64 ensureEntranceObjects(visitor);
65
66 // ensure enter/exit callbacks are arrays
67 ensureCallbackArrays(visitor);
68
69 // add type wrappers
70
71 var _arr2 = Object.keys(visitor);
72
73 for (var _i2 = 0; _i2 < _arr2.length; _i2++) {
74 var nodeType = _arr2[_i2];
75 if (shouldIgnoreKey(nodeType)) continue;
76
77 var wrapper = virtualTypes[nodeType];
78 if (!wrapper) continue;
79
80 // wrap all the functions
81 var fns = visitor[nodeType];
82 for (var type in fns) {
83 fns[type] = wrapCheck(wrapper, fns[type]);
84 }
85
86 // clear it from the visitor
87 delete visitor[nodeType];
88
89 if (wrapper.types) {
90 var _arr4 = wrapper.types;
91
92 for (var _i4 = 0; _i4 < _arr4.length; _i4++) {
93 var type = _arr4[_i4];
94 // merge the visitor if necessary or just put it back in
95 if (visitor[type]) {
96 mergePair(visitor[type], fns);
97 } else {
98 visitor[type] = fns;
99 }
100 }
101 } else {
102 mergePair(visitor, fns);
103 }
104 }
105
106 // add aliases
107 for (var nodeType in visitor) {
108 if (shouldIgnoreKey(nodeType)) continue;
109
110 var fns = visitor[nodeType];
111
112 var aliases = t.FLIPPED_ALIAS_KEYS[nodeType];
113 if (!aliases) continue;
114
115 // clear it from the visitor
116 delete visitor[nodeType];
117
118 var _arr3 = aliases;
119 for (var _i3 = 0; _i3 < _arr3.length; _i3++) {
120 var alias = _arr3[_i3];
121 var existing = visitor[alias];
122 if (existing) {
123 mergePair(existing, fns);
124 } else {
125 visitor[alias] = _lodashLangClone2["default"](fns);
126 }
127 }
128 }
129
130 for (var nodeType in visitor) {
131 if (shouldIgnoreKey(nodeType)) continue;
132
133 ensureCallbackArrays(visitor[nodeType]);
134 }
135
136 return visitor;
137}
138
139/**
140 * [Please add a description.]
141 */
142
143function verify(visitor) {
144 if (visitor._verified) return;
145
146 if (typeof visitor === "function") {
147 throw new Error(messages.get("traverseVerifyRootFunction"));
148 }
149
150 for (var nodeType in visitor) {
151 if (shouldIgnoreKey(nodeType)) continue;
152
153 if (t.TYPES.indexOf(nodeType) < 0) {
154 throw new Error(messages.get("traverseVerifyNodeType", nodeType));
155 }
156
157 var visitors = visitor[nodeType];
158 if (typeof visitors === "object") {
159 for (var visitorKey in visitors) {
160 if (visitorKey === "enter" || visitorKey === "exit") continue;
161 throw new Error(messages.get("traverseVerifyVisitorProperty", nodeType, visitorKey));
162 }
163 }
164 }
165
166 visitor._verified = true;
167}
168
169/**
170 * [Please add a description.]
171 */
172
173function merge(visitors) {
174 var rootVisitor = {};
175
176 var _arr5 = visitors;
177 for (var _i5 = 0; _i5 < _arr5.length; _i5++) {
178 var visitor = _arr5[_i5];
179 explode(visitor);
180
181 for (var type in visitor) {
182 var nodeVisitor = rootVisitor[type] = rootVisitor[type] || {};
183 mergePair(nodeVisitor, visitor[type]);
184 }
185 }
186
187 return rootVisitor;
188}
189
190/**
191 * [Please add a description.]
192 */
193
194function ensureEntranceObjects(obj) {
195 for (var key in obj) {
196 if (shouldIgnoreKey(key)) continue;
197
198 var fns = obj[key];
199 if (typeof fns === "function") {
200 obj[key] = { enter: fns };
201 }
202 }
203}
204
205/**
206 * Makes sure that enter and exit callbacks are arrays.
207 */
208
209function ensureCallbackArrays(obj) {
210 if (obj.enter && !Array.isArray(obj.enter)) obj.enter = [obj.enter];
211 if (obj.exit && !Array.isArray(obj.exit)) obj.exit = [obj.exit];
212}
213
214/**
215 * [Please add a description.]
216 */
217
218function wrapCheck(wrapper, fn) {
219 return function () {
220 if (wrapper.checkPath(this)) {
221 return fn.apply(this, arguments);
222 }
223 };
224}
225
226/**
227 * [Please add a description.]
228 */
229
230function shouldIgnoreKey(key) {
231 // internal/hidden key
232 if (key[0] === "_") return true;
233
234 // ignore function keys
235 if (key === "enter" || key === "exit" || key === "shouldSkip") return true;
236
237 // ignore other options
238 if (key === "blacklist" || key === "noScope" || key === "skipKeys") return true;
239
240 return false;
241}
242
243/**
244 * [Please add a description.]
245 */
246
247function mergePair(dest, src) {
248 for (var key in src) {
249 dest[key] = [].concat(dest[key] || [], src[key]);
250 }
251}
\No newline at end of file