Skip to content

Commit 7e43dd0

Browse files
committed
pre/post hooks: address review comments
1 parent bc71703 commit 7e43dd0

File tree

2 files changed

+53
-59
lines changed

2 files changed

+53
-59
lines changed

__tests__/integration-test.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -57,56 +57,56 @@ describe('regexp-tree', () => {
5757
// 2. Traverse.
5858

5959
// 2a. With functions.
60-
const traverseFunctions_visited = [];
60+
const traverseFunctionsVisited = [];
6161

6262
regexpTree.traverse(ast, {
6363
RegExp({node}) {
64-
traverseFunctions_visited.push(node.type);
64+
traverseFunctionsVisited.push(node.type);
6565
expect(node.type).toBe('RegExp');
6666
},
6767

6868
Char({node}) {
69-
traverseFunctions_visited.push(node.type);
69+
traverseFunctionsVisited.push(node.type);
7070
expect(node.type).toBe('Char');
7171
expect(node.value).toBe('a');
7272
}
7373
});
7474

75-
expect(traverseFunctions_visited).toEqual([
75+
expect(traverseFunctionsVisited).toEqual([
7676
'RegExp',
7777
'Char',
7878
]);
7979

8080
// 2b. With objects.
81-
const traverseObjects_visited = [];
81+
const traverseObjectsVisited = [];
8282

8383
regexpTree.traverse(ast, {
8484
RegExp: {
8585
pre({node}) {
86-
traverseObjects_visited.push(`${node.type}_pre`);
86+
traverseObjectsVisited.push(`${node.type}_pre`);
8787
expect(node.type).toBe('RegExp');
8888
},
8989
post({node}) {
90-
traverseObjects_visited.push(`${node.type}_post`);
90+
traverseObjectsVisited.push(`${node.type}_post`);
9191
expect(node.type).toBe('RegExp');
9292
}
9393
},
9494

9595
Char: {
9696
pre({node}) {
97-
traverseObjects_visited.push(`${node.type}_pre`);
97+
traverseObjectsVisited.push(`${node.type}_pre`);
9898
expect(node.type).toBe('Char');
9999
expect(node.value).toBe('a');
100100
},
101101
post({node}) {
102-
traverseObjects_visited.push(`${node.type}_post`);
102+
traverseObjectsVisited.push(`${node.type}_post`);
103103
expect(node.type).toBe('Char');
104104
expect(node.value).toBe('a');
105105
}
106106
}
107107
});
108108

109-
expect(traverseObjects_visited).toEqual([
109+
expect(traverseObjectsVisited).toEqual([
110110
'RegExp_pre',
111111
'Char_pre',
112112
'Char_post',

src/traverse/index.js

+43-49
Original file line numberDiff line numberDiff line change
@@ -160,33 +160,33 @@ module.exports = {
160160
}
161161
});
162162

163+
function _getPathFor (node, parent, prop, index) {
164+
const parentPath = NodePath.getForNode(parent);
165+
const nodePath = NodePath.getForNode(
166+
node,
167+
parentPath,
168+
prop,
169+
index
170+
);
171+
172+
return nodePath;
173+
}
174+
163175
// Handle actual nodes.
164176
astTraverse(ast, {
165-
166177
/**
167178
* Handler on node enter.
168179
*/
169180
pre(node, parent, prop, index) {
170-
let parentPath;
171181
let nodePath;
172-
173182
if (!options.asNodes) {
174-
parentPath = NodePath.getForNode(parent);
175-
176-
nodePath = NodePath.getForNode(
177-
node,
178-
parentPath,
179-
prop,
180-
index
181-
);
183+
nodePath = _getPathFor(node, parent, prop, index);
182184
}
183185

184186
for (const handler of handlers) {
185187
// "Catch-all" `*` handler.
186188
if (typeof handler['*'] === 'function') {
187-
if (options.asNodes) {
188-
handler['*'](node, parent, prop, index);
189-
} else {
189+
if (nodePath) {
190190
// A path/node can be removed by some previous handler.
191191
if (!nodePath.isRemoved()) {
192192
const handlerResult = handler['*'](nodePath);
@@ -196,32 +196,34 @@ module.exports = {
196196
}
197197
}
198198
}
199+
else {
200+
handler['*'](node, parent, prop, index);
201+
}
199202
}
200203

201204
// Per-node handler.
202-
let handlerFunc_pre = null;
203-
if (handler[node.type] &&
204-
typeof handler[node.type] === 'function') {
205-
handlerFunc_pre = handler[node.type].bind(handler);
206-
}
207-
else if (handler[node.type] &&
208-
typeof handler[node.type] === 'object' &&
209-
typeof handler[node.type].pre === 'function') {
210-
handlerFunc_pre = handler[node.type].pre.bind(handler);
205+
let handlerFuncPre;
206+
if (typeof handler[node.type] === 'function') {
207+
handlerFuncPre = handler[node.type];
208+
} else if (
209+
typeof handler[node.type] === 'object' &&
210+
typeof handler[node.type].pre === 'function'
211+
) {
212+
handlerFuncPre = handler[node.type].pre;
211213
}
212214

213-
if (handlerFunc_pre) {
214-
if (options.asNodes) {
215-
handlerFunc_pre(node, parent, prop, index);
216-
} else {
215+
if (handlerFuncPre) {
216+
if (nodePath) {
217217
// A path/node can be removed by some previous handler.
218218
if (!nodePath.isRemoved()) {
219-
const handlerResult = handlerFunc_pre(nodePath);
219+
const handlerResult = handlerFuncPre.call(handler, nodePath);
220220
// Explicitly stop traversal.
221221
if (handlerResult === false) {
222222
return false;
223223
}
224224
}
225+
} else {
226+
handlerFuncPre.call(handler, node, parent, prop, index);
225227
}
226228
}
227229
} // Loop over handlers
@@ -232,45 +234,37 @@ module.exports = {
232234
* Handler on node exit.
233235
*/
234236
post(node, parent, prop, index) {
235-
if (!node) { // No node? Not sure how this can happen, but without it many tests fail.
237+
if (!node) {
236238
return;
237239
}
238240

239-
let parentPath;
240241
let nodePath;
241-
242242
if (!options.asNodes) {
243-
parentPath = NodePath.getForNode(parent);
244-
245-
nodePath = NodePath.getForNode(
246-
node,
247-
parentPath,
248-
prop,
249-
index
250-
);
243+
nodePath = _getPathFor(node, parent, prop, index);
251244
}
252245

253246
for (const handler of handlers) {
254247
// Per-node handler.
255-
let handlerFunc_post = null;
256-
if (handler[node.type] &&
257-
typeof handler[node.type] === 'object' &&
258-
typeof handler[node.type].post === 'function') {
259-
handlerFunc_post = handler[node.type].post;
248+
let handlerFuncPost;
249+
if (
250+
typeof handler[node.type] === 'object' &&
251+
typeof handler[node.type].post === 'function'
252+
) {
253+
handlerFuncPost = handler[node.type].post;
260254
}
261255

262-
if (handlerFunc_post) {
263-
if (options.asNodes) {
264-
handlerFunc_post(node, parent, prop, index);
265-
} else {
256+
if (handlerFuncPost) {
257+
if (nodePath) {
266258
// A path/node can be removed by some previous handler.
267259
if (!nodePath.isRemoved()) {
268-
const handlerResult = handlerFunc_post(nodePath);
260+
const handlerResult = handlerFuncPost.call(handler, nodePath);
269261
// Explicitly stop traversal.
270262
if (handlerResult === false) {
271263
return false;
272264
}
273265
}
266+
} else {
267+
handlerFuncPost.call(handler, node, parent, prop, index);
274268
}
275269
}
276270
} // Loop over handlers

0 commit comments

Comments
 (0)