Skip to content
This repository was archived by the owner on Mar 29, 2018. It is now read-only.

Commit 036e76b

Browse files
Merge branch 'optimize-with-a-split-visitor'
2 parents 528cc38 + 547eccf commit 036e76b

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

lib/index.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ var util = require('ast-util');
1919
*/
2020
function ArrowFunctionExpressionVisitor() {
2121
PathVisitor.call(this);
22+
23+
// In order to optimize the visitor we use a specific one for parsing the
24+
// the body of the arrow function. This way very common types like Identifier
25+
// are only visited under the subtree we're interested in.
26+
this.bodyVisitor = new BodyVisitor(this);
2227
}
2328
ArrowFunctionExpressionVisitor.prototype = Object.create(PathVisitor.prototype);
2429
ArrowFunctionExpressionVisitor.prototype.constructor = ArrowFunctionExpressionVisitor;
@@ -30,7 +35,8 @@ ArrowFunctionExpressionVisitor.prototype.constructor = ArrowFunctionExpressionVi
3035
* @return {?Node}
3136
*/
3237
ArrowFunctionExpressionVisitor.prototype.visitArrowFunctionExpression = function(path) {
33-
this.traverse(path);
38+
// Descend into the body using a specific visitor
39+
this.traverse(path, this.bodyVisitor);
3440

3541
var node = path.node;
3642
var hasThisExpression = ThisExpressionVisitor.hasThisExpression(node);
@@ -53,13 +59,29 @@ ArrowFunctionExpressionVisitor.prototype.visitArrowFunctionExpression = function
5359
}
5460
};
5561

62+
/**
63+
* Visits the body of an arrow function expressions.
64+
*
65+
* @constructor
66+
* @private
67+
* @extends PathVisitor
68+
*/
69+
function BodyVisitor(parent) {
70+
// Support nested arrow function expressions by delegating on the parent visitor
71+
this.visitArrowFunctionExpression = parent.visitArrowFunctionExpression;
72+
73+
PathVisitor.call(this);
74+
}
75+
BodyVisitor.prototype = Object.create(PathVisitor.prototype);
76+
BodyVisitor.prototype.constructor = BodyVisitor;
77+
5678
/**
5779
* Ensures that `arguments` directly contained in arrow functions is hoisted.
5880
*
5981
* @param {types.NodePath} path
6082
* @return {?Node}
6183
*/
62-
ArrowFunctionExpressionVisitor.prototype.visitIdentifier = function(path) {
84+
BodyVisitor.prototype.visitIdentifier = function(path) {
6385
var node = path.node;
6486

6587
if (node.name === 'arguments' && util.isReference(path)) {
@@ -69,15 +91,15 @@ ArrowFunctionExpressionVisitor.prototype.visitIdentifier = function(path) {
6991
}
7092
}
7193

72-
this.traverse(path);
94+
return false; // nothing else to look at here
7395
};
7496

7597
/**
7698
* @private
7799
* @param {types.NodePath} path
78100
* @return {?types.Scope} The nearest non-arrow function scope above `path`.
79101
*/
80-
ArrowFunctionExpressionVisitor.prototype.associatedFunctionScope = function(path) {
102+
BodyVisitor.prototype.associatedFunctionScope = function(path) {
81103
var scope = path.scope;
82104
while (scope && n.ArrowFunctionExpression.check(scope.path.node)) {
83105
scope = scope.parent;

0 commit comments

Comments
 (0)