From 49a53b26bb06f54b138595b5526fe7cacbba85e9 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 10 Feb 2015 22:39:07 +1100 Subject: [PATCH] add scope renaming helper method - fixes #645 - @RReverser --- lib/6to5/transformation/modules/common.js | 9 +++- lib/6to5/traversal/scope.js | 55 +++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index f2ce247b56..364aa11626 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -14,8 +14,15 @@ function CommonJSFormatter() { util.inherits(CommonJSFormatter, DefaultFormatter); CommonJSFormatter.prototype.init = function () { + var file = this.file; + var scope = file.scope; + + if (scope.hasBinding("module")) { + scope.rename("module", file.generateUidIdentifier("module").name); + } + if (!this.noInteropRequireImport && this.hasNonDefaultExports) { - this.file.ast.program.body.push(util.template("exports-module-declaration", true)); + file.ast.program.body.push(util.template("exports-module-declaration", true)); } }; diff --git a/lib/6to5/traversal/scope.js b/lib/6to5/traversal/scope.js index d155541b77..55c758ee5c 100644 --- a/lib/6to5/traversal/scope.js +++ b/lib/6to5/traversal/scope.js @@ -143,6 +143,35 @@ Scope.prototype.checkBlockScopedCollisions = function (kind, key, id) { } }; +Scope.prototype.rename = function (oldName, newName) { + var info = this.getBindingWithScope(oldName); + console.log(info); + if (!info) return; + + var binding = info.binding; + var scope = info.scope; + + scope.references[newName] = binding; + scope.bindings[newName] = binding; + + delete scope.references[oldName]; + delete scope.bindings[oldName]; + + binding.name = newName; + + scope.traverse(scope.block, { + enter: function (node, parent, scope) { + if (t.isReferencedIdentifier(node, parent) && node.name === oldName) { + node.name = newName; + } else if (t.isScope(node)) { + if (t.getBinding(oldName) !== binding) { + this.skip(); + } + } + } + }); +}; + Scope.prototype.inferType = function (node) { var target; @@ -150,10 +179,6 @@ Scope.prototype.inferType = function (node) { target = node.init; } - if (t.isLiteral(target) || t.isArrayExpression(target) || t.isObjectExpression(target)) { - // todo: possibly call some helper that will resolve these to a flow type annotation - } - if (t.isCallExpression(target)) { // todo: resolve this to a return type } @@ -411,6 +436,28 @@ Scope.prototype.addBindingToFunctionScope = function (node, kind) { if (kind) extend(scope.bindingKinds[kind], ids); }; +/** + * Walk up the scope tree and check to see if it has a binding with the provided + * name, if it does return the binding identifier and scope. + * + * @param {String} name + * @returns {Object} { binding, scope } + */ + +Scope.prototype.getBindingWithScope = function (name) { + var scope = this; + + do { + binding = scope.getOwnBinding(name); + var if (binding) { + return { + binding: binding, + scope: scope + }; + } + } while (scope = scope.parent); +}; + /** * Walk up the scope tree until we hit either a Function or reach the * very top and hit Program.