diff --git a/lib/babel/transformation/transformers/es6/block-scoping-tdz.js b/lib/babel/transformation/transformers/es6/block-scoping-tdz.js index e851632a28..8b765b7d9a 100644 --- a/lib/babel/transformation/transformers/es6/block-scoping-tdz.js +++ b/lib/babel/transformation/transformers/es6/block-scoping-tdz.js @@ -21,7 +21,7 @@ var visitor = { if (t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) { if (parent._ignoreBlockScopingTDZ) return; - this.parentPath.replaceNode(t.sequenceExpression([assert, parent])); + this.parentPath.node = t.sequenceExpression([assert, parent]); } else { return t.logicalExpression("&&", assert, node); } diff --git a/lib/babel/traversal/path.js b/lib/babel/traversal/path.js index 08220853b0..de267cc604 100644 --- a/lib/babel/traversal/path.js +++ b/lib/babel/traversal/path.js @@ -2,14 +2,12 @@ module.exports = TraversalPath; -/* jshint maxparams:7 */ - var traverse = require("./index"); var includes = require("lodash/collection/includes"); var Scope = require("./scope"); var t = require("../types"); -function TraversalPath(context, parent, obj, key) { +function TraversalPath(context, parent, container, key) { this.shouldRemove = false; this.shouldSkip = false; this.shouldStop = false; @@ -19,14 +17,30 @@ function TraversalPath(context, parent, obj, key) { this.state = this.context.state; this.opts = this.context.opts; - this.key = key; - this.obj = obj; + this.container = container; + this.key = key; this.parent = parent; - this.scope = TraversalPath.getScope(this.getNode(), parent, context.scope); this.state = context.state; + + this.setScope(); } +TraversalPath.getScope = function (node, parent, scope) { + var ourScope = scope; + + // we're entering a new scope so let's construct it! + if (t.isScope(node, parent)) { + ourScope = new Scope(node, parent, scope); + } + + return ourScope; +}; + +TraversalPath.prototype.setScope = function () { + this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope); +}; + TraversalPath.prototype.remove = function () { this.shouldRemove = true; this.shouldSkip = true; @@ -45,67 +59,48 @@ TraversalPath.prototype.flatten = function () { this.context.flatten(); }; -TraversalPath.getScope = function (node, parent, scope) { - var ourScope = scope; +Object.defineProperty(TraversalPath.prototype, "node", { + get: function () { + return this.container[this.key]; + }, - // we're entering a new scope so let's construct it! - if (t.isScope(node, parent)) { - ourScope = new Scope(node, parent, scope); - } + set: function (replacement) { + var isArray = Array.isArray(replacement); - return ourScope; -}; + // inherit comments from original node to the first replacement node + var inheritTo = replacement; + if (isArray) inheritTo = replacement[0]; + if (inheritTo) t.inheritsComments(inheritTo, this.node); -TraversalPath.prototype.maybeRemove = function () { - if (this.shouldRemove) { - this.setNode(null); - this.flatten(); - } -}; + // replace the node + this.container[this.key] = replacement; + this.setScope(); -TraversalPath.prototype.setNode = function (val) { - return this.obj[this.key] = val; -}; - -TraversalPath.prototype.getNode = function () { - return this.obj[this.key]; -}; - -TraversalPath.prototype.replaceNode = function (replacement) { - var isArray = Array.isArray(replacement); - - // inherit comments from original node to the first replacement node - var inheritTo = replacement; - if (isArray) inheritTo = replacement[0]; - if (inheritTo) t.inheritsComments(inheritTo, this.getNode()); - - // replace the node - this.setNode(replacement); - - var file = this.scope && this.scope.file; - if (file) { - if (isArray) { - for (var i = 0; i < replacement.length; i++) { - file.checkNode(replacement[i], this.scope); + var file = this.scope && this.scope.file; + if (file) { + if (isArray) { + for (var i = 0; i < replacement.length; i++) { + file.checkNode(replacement[i], this.scope); + } + } else { + file.checkNode(replacement, this.scope); } - } else { - file.checkNode(replacement, this.scope); - } - } - - // we're replacing a statement or block node with an array of statements so we better - // ensure that it's a block - if (isArray) { - if (includes(t.STATEMENT_OR_BLOCK_KEYS, this.key) && !t.isBlockStatement(this.obj)) { - t.ensureBlock(this.obj, this.key); } - this.flatten(); + // we're replacing a statement or block node with an array of statements so we better + // ensure that it's a block + if (isArray) { + if (includes(t.STATEMENT_OR_BLOCK_KEYS, this.key) && !t.isBlockStatement(this.container)) { + t.ensureBlock(this.container, this.key); + } + + this.flatten(); + } } -}; +}); TraversalPath.prototype.call = function (key) { - var node = this.getNode(); + var node = this.node; if (!node) return; var opts = this.opts; @@ -115,18 +110,18 @@ TraversalPath.prototype.call = function (key) { var replacement = fn.call(this, node, this.parent, this.scope, this.state); if (replacement) { - this.replaceNode(replacement); - node = replacement; + this.node = replacement; } - this.maybeRemove(); - - return node; + if (this.shouldRemove) { + this.container[this.key] = null; + this.flatten(); + } }; TraversalPath.prototype.visit = function () { var opts = this.opts; - var node = this.getNode(); + var node = this.node; // type is blacklisted if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) { @@ -139,7 +134,7 @@ TraversalPath.prototype.visit = function () { return this.shouldStop; } - node = this.getNode(); + node = this.node; if (Array.isArray(node)) { // traverse over these replacement nodes we purposely don't call exitNode @@ -154,3 +149,7 @@ TraversalPath.prototype.visit = function () { return this.shouldStop; }; + +TraversalPath.prototype.isReferencedIdentifier = function () { + return t.isReferencedIdentifier(this.node); +};