diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index fa2c7263fb..341846f4a0 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -9,8 +9,10 @@ function CommonJSFormatter(file) { DefaultFormatter.apply(this, arguments); var hasNonDefaultExports = false; - traverse(file.ast, function (node) { - if (t.isExportDeclaration(node) && !node.default) hasNonDefaultExports = true; + traverse(file.ast, { + enter: function (node) { + if (t.isExportDeclaration(node) && !node.default) hasNonDefaultExports = true; + } }); this.hasNonDefaultExports = hasNonDefaultExports; } @@ -31,9 +33,6 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) ])); } else { // import foo from "foo"; - if (specifier.default) { - specifier.id = t.identifier("default"); - } var templateName = "require-assign"; diff --git a/lib/6to5/transformation/modules/system.js b/lib/6to5/transformation/modules/system.js index 73ddc6f107..d2dc31dc3b 100644 --- a/lib/6to5/transformation/modules/system.js +++ b/lib/6to5/transformation/modules/system.js @@ -5,7 +5,6 @@ var t = require("../../types"); var _ = require("lodash"); var SETTER_MODULE_NAMESPACE = t.identifier("m"); -var DEFAULT_IDENTIFIER = t.identifier("default"); var NULL_SETTER = t.literal(null); function SystemFormatter(file) { @@ -117,9 +116,6 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node) { var variableName = t.getSpecifierName(specifier); // import foo from "foo"; - if (specifier.default) { - specifier.id = DEFAULT_IDENTIFIER; - } var MODULE_NAME = node.source.value; diff --git a/lib/6to5/transformation/transformers/_alias-functions.js b/lib/6to5/transformation/transformers/_alias-functions.js index 3ea43351a4..4d4b78ea67 100644 --- a/lib/6to5/transformation/transformers/_alias-functions.js +++ b/lib/6to5/transformation/transformers/_alias-functions.js @@ -15,38 +15,42 @@ var go = function (getBody, node, file, scope) { // traverse the function and find all alias functions so we can alias // `arguments` and `this` if necessary - traverse(node, function (node) { - if (!node._aliasFunction) { - if (t.isFunction(node)) { - // stop traversal of this node as it'll be hit again by this transformer - return false; - } else { - return; + traverse(node, { + enter: function (node) { + if (!node._aliasFunction) { + if (t.isFunction(node)) { + // stop traversal of this node as it'll be hit again by this transformer + return false; + } else { + return; + } } + + // traverse all child nodes of this function and find `arguments` and `this` + traverse(node, { + enter: function (node, parent) { + if (t.isFunction(node) && !node._aliasFunction) { + return false; + } + + if (node._ignoreAliasFunctions) return false; + + var getId; + + if (t.isIdentifier(node) && node.name === "arguments") { + getId = getArgumentsId; + } else if (t.isThisExpression(node)) { + getId = getThisId; + } else { + return; + } + + if (t.isReferenced(node, parent)) return getId(); + } + }); + + return false; } - - // traverse all child nodes of this function and find `arguments` and `this` - traverse(node, function (node, parent) { - if (t.isFunction(node) && !node._aliasFunction) { - return false; - } - - if (node._ignoreAliasFunctions) return false; - - var getId; - - if (t.isIdentifier(node) && node.name === "arguments") { - getId = getArgumentsId; - } else if (t.isThisExpression(node)) { - getId = getThisId; - } else { - return; - } - - if (t.isReferenced(node, parent)) return getId(); - }); - - return false; }); var body; diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 71e3e2680a..383a477d3d 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -247,17 +247,19 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var method = methodNode.value; var self = this; - traverse(method, function (node, parent) { - if (t.isIdentifier(node, { name: "super" })) { - return self.superIdentifier(methodNode, node, parent); - } else if (t.isCallExpression(node)) { - var callee = node.callee; - if (!t.isMemberExpression(callee)) return; - if (callee.object.name !== "super") return; + traverse(method, { + enter: function (node, parent) { + if (t.isIdentifier(node, { name: "super" })) { + return self.superIdentifier(methodNode, node, parent); + } else if (t.isCallExpression(node)) { + var callee = node.callee; + if (!t.isMemberExpression(callee)) return; + if (callee.object.name !== "super") return; - // super.test(); -> ClassName.prototype.MethodName.call(this); - callee.property = t.memberExpression(callee.property, t.identifier("call")); - node.arguments.unshift(t.thisExpression()); + // super.test(); -> ClassName.prototype.MethodName.call(this); + callee.property = t.memberExpression(callee.property, t.identifier("call")); + node.arguments.unshift(t.thisExpression()); + } } }); }; diff --git a/lib/6to5/transformation/transformers/es6-constants.js b/lib/6to5/transformation/transformers/es6-constants.js index 4266ceca44..a3021188fb 100644 --- a/lib/6to5/transformation/transformers/es6-constants.js +++ b/lib/6to5/transformation/transformers/es6-constants.js @@ -69,12 +69,14 @@ exports.ForStatement = function (node, parent, file) { if (!hasConstants) return; - traverse(node, function (child, parent, scope) { - if (child._ignoreConstant) return; - if (t.isVariableDeclaration(child)) return; + traverse(node, { + enter: function (child, parent, scope) { + if (child._ignoreConstant) return; + if (t.isVariableDeclaration(child)) return; - if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) { - check(parent, getIds(child), scope); + if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) { + check(parent, getIds(child), scope); + } } }); }; diff --git a/lib/6to5/transformation/transformers/es6-default-parameters.js b/lib/6to5/transformation/transformers/es6-default-parameters.js index 93b0ef284c..9715c2bbdc 100644 --- a/lib/6to5/transformation/transformers/es6-default-parameters.js +++ b/lib/6to5/transformation/transformers/es6-default-parameters.js @@ -37,7 +37,7 @@ exports.Function = function (node, parent, file, scope) { }; check(def, node); - traverse(def, check); + traverse(def, { enter: check }); }); // we're accessing a variable that's already defined within this function diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index 625159fce6..7d6fa09b76 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -176,7 +176,7 @@ LetScoping.prototype.remap = function () { var traverseReplace = function (node, parent) { replace(node, parent); - traverse(node, replace); + traverse(node, { enter: replace }); }; var loopParent = this.loopParent; @@ -186,7 +186,7 @@ LetScoping.prototype.remap = function () { traverseReplace(loopParent.update, loopParent); } - traverse(block, replace); + traverse(block, { enter: replace }); }; /** @@ -275,33 +275,35 @@ LetScoping.prototype.checkLoop = function () { hasBreak: false, }; - traverse(this.block, function (node, parent) { - var replace; + traverse(this.block, { + enter: function (node, parent) { + var replace; - if (t.isFunction(node) || t.isLoop(node)) { - return false; - } - - if (node && !node.label) { - if (t.isBreakStatement(node)) { - if (t.isSwitchCase(parent)) return; - - has.hasBreak = true; - replace = t.returnStatement(t.literal("break")); - } else if (t.isContinueStatement(node)) { - has.hasContinue = true; - replace = t.returnStatement(t.literal("continue")); + if (t.isFunction(node) || t.isLoop(node)) { + return false; } - } - if (t.isReturnStatement(node)) { - has.hasReturn = true; - replace = t.returnStatement(t.objectExpression([ - t.property("init", t.identifier("v"), node.argument || t.identifier("undefined")) - ])); - } + if (node && !node.label) { + if (t.isBreakStatement(node)) { + if (t.isSwitchCase(parent)) return; - if (replace) return t.inherits(replace, node); + has.hasBreak = true; + replace = t.returnStatement(t.literal("break")); + } else if (t.isContinueStatement(node)) { + has.hasContinue = true; + replace = t.returnStatement(t.literal("continue")); + } + } + + if (t.isReturnStatement(node)) { + has.hasReturn = true; + replace = t.returnStatement(t.objectExpression([ + t.property("init", t.identifier("v"), node.argument || t.identifier("undefined")) + ])); + } + + if (replace) return t.inherits(replace, node); + } }); return has; @@ -314,19 +316,21 @@ LetScoping.prototype.checkLoop = function () { LetScoping.prototype.hoistVarDeclarations = function () { var self = this; - traverse(this.block, function (node, parent) { - if (t.isForStatement(node)) { - if (isVar(node.init, node)) { - node.init = t.sequenceExpression(self.pushDeclar(node.init)); + traverse(this.block, { + enter: function (node, parent) { + if (t.isForStatement(node)) { + if (isVar(node.init, node)) { + node.init = t.sequenceExpression(self.pushDeclar(node.init)); + } + } else if (t.isFor(node)) { + if (isVar(node.left, node)) { + node.left = node.left.declarations[0].id; + } + } else if (isVar(node, parent)) { + return self.pushDeclar(node).map(t.expressionStatement); + } else if (t.isFunction(node)) { + return false; } - } else if (t.isFor(node)) { - if (isVar(node.left, node)) { - node.left = node.left.declarations[0].id; - } - } else if (isVar(node, parent)) { - return self.pushDeclar(node).map(t.expressionStatement); - } else if (t.isFunction(node)) { - return false; } }); }; @@ -359,31 +363,35 @@ LetScoping.prototype.getLetReferences = function () { // traverse through this block, stopping on functions and checking if they // contain any outside let references - traverse(this.block, function (node, parent, scope) { - if (t.isFunction(node)) { - traverse(node, function (node, parent) { - // not an identifier so we have no use - if (!t.isIdentifier(node)) return; + traverse(this.block, { + enter: function (node, parent, scope) { + if (t.isFunction(node)) { + traverse(node, { + enter: function (node, parent) { + // not an identifier so we have no use + if (!t.isIdentifier(node)) return; - // not a direct reference - if (!t.isReferenced(node, parent)) return; + // not a direct reference + if (!t.isReferenced(node, parent)) return; - // this scope has a variable with the same name so it couldn't belong - // to our let scope - if (scope.hasOwn(node.name)) return; + // this scope has a variable with the same name so it couldn't belong + // to our let scope + if (scope.hasOwn(node.name)) return; - closurify = true; + closurify = true; - // this key doesn't appear just outside our scope - if (!_.contains(self.info.outsideKeys, node.name)) return; + // this key doesn't appear just outside our scope + if (!_.contains(self.info.outsideKeys, node.name)) return; - // push this badboy - self.letReferences[node.name] = node; - }); + // push this badboy + self.letReferences[node.name] = node; + } + }); - return false; - } else if (t.isLoop(node)) { - return false; + return false; + } else if (t.isLoop(node)) { + return false; + } } }); diff --git a/lib/6to5/transformation/transformers/playground-object-getter-memoization.js b/lib/6to5/transformation/transformers/playground-object-getter-memoization.js index 8c3c835023..560f2967c3 100644 --- a/lib/6to5/transformation/transformers/playground-object-getter-memoization.js +++ b/lib/6to5/transformation/transformers/playground-object-getter-memoization.js @@ -21,11 +21,13 @@ exports.MethodDefinition = function (node, parent, file, scope) { var memoId = t.memberExpression(t.thisExpression(), t.identifier(key)); var doneId = t.memberExpression(t.thisExpression(), t.identifier(key + "Done")); - traverse(value, function (node) { - if (t.isFunction(node)) return; + traverse(value, { + enter: function (node) { + if (t.isFunction(node)) return; - if (t.isReturnStatement(node) && node.argument) { - node.argument = t.assignmentExpression("=", memoId, node.argument); + if (t.isReturnStatement(node) && node.argument) { + node.argument = t.assignmentExpression("=", memoId, node.argument); + } } }); diff --git a/lib/6to5/traverse/index.js b/lib/6to5/traverse/index.js index aea63764e0..fcbdf1f587 100644 --- a/lib/6to5/traverse/index.js +++ b/lib/6to5/traverse/index.js @@ -4,14 +4,14 @@ var Scope = require("./scope"); var t = require("../types"); var _ = require("lodash"); -function traverse(parent, callbacks, opts) { +function traverse(parent, opts, scope) { // falsy node if (!parent) return; // array of nodes if (_.isArray(parent)) { _.each(parent, function (node) { - traverse(node, callbacks, opts); + traverse(node, opts, scope); }); return; } @@ -21,13 +21,6 @@ function traverse(parent, callbacks, opts) { if (!keys) return; opts = opts || {}; - if (_.isArray(opts)) opts = { blacklist: opts }; - - // blacklist these node types from being traversed - var blacklistTypes = opts.blacklist || []; - - // normalise callbacks - if (_.isFunction(callbacks)) callbacks = { enter: callbacks }; for (var i in keys) { var key = keys[i]; @@ -41,7 +34,7 @@ function traverse(parent, callbacks, opts) { if (!node) return; // type is blacklisted - if (blacklistTypes.indexOf(node.type) > -1) return; + if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) return; // replace node var maybeReplace = function (result) { @@ -58,12 +51,12 @@ function traverse(parent, callbacks, opts) { }; // - var opts2 = { scope: opts.scope, blacklist: opts.blacklist }; - if (t.isScope(node)) opts2.scope = new Scope(node, opts.scope); + var ourScope = scope; + if (t.isScope(node)) ourScope = new Scope(node, scope); // enter - if (callbacks.enter) { - var result = callbacks.enter(node, parent, opts2.scope); + if (opts.enter) { + var result = opts.enter(node, parent, ourScope); maybeReplace(result); // stop iteration @@ -71,11 +64,11 @@ function traverse(parent, callbacks, opts) { } // traverse node - traverse(node, callbacks, opts2); + traverse(node, opts, ourScope); // exit - if (callbacks.exit) { - maybeReplace(callbacks.exit(node, parent, opts2.scope)); + if (opts.exit) { + maybeReplace(opts.exit(node, parent, ourScope)); } }; @@ -113,7 +106,7 @@ traverse.removeProperties = function (tree) { }; clear(tree); - traverse(tree, clear); + traverse(tree, { enter: clear }); return tree; }; @@ -129,12 +122,15 @@ traverse.hasType = function (tree, type, blacklistTypes) { // the type we're looking for is the same as the passed node if (tree.type === type) return true; - traverse(tree, function (node) { - if (node.type === type) { - has = true; - return false; + traverse(tree, { + blacklist: blacklistTypes, + enter: function (node) { + if (node.type === type) { + has = true; + return false; + } } - }, { blacklist: blacklistTypes }); + }); return has; }; diff --git a/lib/6to5/traverse/scope.js b/lib/6to5/traverse/scope.js index 603a33a823..e5acde3244 100644 --- a/lib/6to5/traverse/scope.js +++ b/lib/6to5/traverse/scope.js @@ -82,31 +82,33 @@ Scope.prototype.getInfo = function () { // Program, Function - var variables if (t.isProgram(block) || t.isFunction(block)) { - traverse(block, function (node, parent, scope) { - if (t.isFor(node)) { - _.each(FOR_KEYS, function (key) { - var declar = node[key]; - if (t.isVar(declar)) add(declar); - }); + traverse(block, { + enter: function (node, parent, scope) { + if (t.isFor(node)) { + _.each(FOR_KEYS, function (key) { + var declar = node[key]; + if (t.isVar(declar)) add(declar); + }); + } + + // this block is a function so we'll stop since none of the variables + // declared within are accessible + if (t.isFunction(node)) return false; + + // function identifier doesn't belong to this scope + if (block.id && node === block.id) return; + + if (t.isIdentifier(node) && t.isReferenced(node, parent) && !scope.has(node.name)) { + add(node, true); + } + + // we've ran into a declaration! + // we'll let the BlockStatement scope deal with `let` declarations unless + if (t.isDeclaration(node) && !t.isLet(node)) { + add(node); + } } - - // this block is a function so we'll stop since none of the variables - // declared within are accessible - if (t.isFunction(node)) return false; - - // function identifier doesn't belong to this scope - if (block.id && node === block.id) return; - - if (t.isIdentifier(node) && t.isReferenced(node, parent) && !scope.has(node.name)) { - add(node, true); - } - - // we've ran into a declaration! - // we'll let the BlockStatement scope deal with `let` declarations unless - if (t.isDeclaration(node) && !t.isLet(node)) { - add(node); - } - }, { scope: this }); + }, this); } // Function - params, rest diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 1478340ae8..6afcdef2c7 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -150,9 +150,11 @@ exports.template = function (name, nodes, keepExpression) { template = _.cloneDeep(template); if (!_.isEmpty(nodes)) { - traverse(template, function (node) { - if (t.isIdentifier(node) && _.has(nodes, node.name)) { - return nodes[node.name]; + traverse(template, { + enter: function (node) { + if (t.isIdentifier(node) && _.has(nodes, node.name)) { + return nodes[node.name]; + } } }); }