From fc7fc384c9d878c1f5b558a7116d0899c8538518 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:06:56 +1100 Subject: [PATCH] add declaration/reference support to scope --- lib/6to5/traverse/index.js | 2 +- lib/6to5/traverse/scope.js | 49 +++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/6to5/traverse/index.js b/lib/6to5/traverse/index.js index 32bad31add..add0a38df1 100644 --- a/lib/6to5/traverse/index.js +++ b/lib/6to5/traverse/index.js @@ -93,9 +93,9 @@ function traverse(parent, callbacks, opts) { traverse.removeProperties = function (tree) { var clear = function (node) { - delete node._scopeReferences; delete node._declarations; delete node.extendedRange; + delete node._scopeInfo; delete node._parent; delete node._scope; delete node.tokens; diff --git a/lib/6to5/traverse/scope.js b/lib/6to5/traverse/scope.js index b2faeab838..603a33a823 100644 --- a/lib/6to5/traverse/scope.js +++ b/lib/6to5/traverse/scope.js @@ -18,9 +18,14 @@ function Scope(block, parent) { this.parent = parent; this.block = block; - this.references = this.getReferences(); + var info = this.getInfo(); + this.references = info.references; + this.declarations = info.declarations; } +var vars = require("jshint/src/vars"); +Scope.defaultDeclarations = _.flatten([vars.newEcmaIdentifiers, vars.node, vars.ecmaIdentifiers, vars.reservedVars].map(_.keys)); + Scope.add = function (node, references) { if (!node) return; _.defaults(references, t.getIds(node, true)); @@ -35,14 +40,17 @@ Scope.prototype.generateTemp = function (file, name) { return id; }; -Scope.prototype.getReferences = function () { +Scope.prototype.getInfo = function () { var block = this.block; - if (block._scopeReferences) return block._scopeReferences; + if (block._scopeInfo) return block._scopeInfo; - var references = block._scopeReferences = {}; + var info = block._scopeInfo = {}; + var references = info.references = {}; + var declarations = info.declarations = {}; - var add = function (node) { + var add = function (node, reference) { Scope.add(node, references); + if (!reference) Scope.add(node, declarations); }; // ForStatement - left, init @@ -90,7 +98,7 @@ Scope.prototype.getReferences = function () { if (block.id && node === block.id) return; if (t.isIdentifier(node) && t.isReferenced(node, parent) && !scope.has(node.name)) { - add(node); + add(node, true); } // we've ran into a declaration! @@ -110,7 +118,7 @@ Scope.prototype.getReferences = function () { }); } - return references; + return info; }; Scope.prototype.push = function (opts) { @@ -137,26 +145,29 @@ Scope.prototype.add = function (node) { Scope.add(node, this.references); }; -Scope.prototype.get = function (id) { - return id && (this.getOwn(id) || this.parentGet(id)); +Scope.prototype.get = function (id, decl) { + return id && (this.getOwn(id, decl) || this.parentGet(id, decl)); }; -Scope.prototype.getOwn = function (id) { - return _.has(this.references, id) && this.references[id]; +Scope.prototype.getOwn = function (id, decl) { + var refs = this.references; + if (decl) refs = this.declarations; + return _.has(refs, id) && refs[id]; }; -Scope.prototype.parentGet = function (id) { - return this.parent && this.parent.get(id); +Scope.prototype.parentGet = function (id, decl) { + return this.parent && this.parent.get(id, decl); }; -Scope.prototype.has = function (id) { - return id && (this.hasOwn(id) || this.parentHas(id)); +Scope.prototype.has = function (id, decl) { + return (id && (this.hasOwn(id, decl) || this.parentHas(id, decl))) || + _.contains(Scope.defaultDeclarations, id); }; -Scope.prototype.hasOwn = function (id) { - return !!this.getOwn(id); +Scope.prototype.hasOwn = function (id, decl) { + return !!this.getOwn(id, decl); }; -Scope.prototype.parentHas = function (id) { - return this.parent && this.parent.has(id); +Scope.prototype.parentHas = function (id, decl) { + return this.parent && this.parent.has(id, decl); };