ensure that a scope is always passed to traverse and allow scopes to have access to file
This commit is contained in:
parent
0b6d49e421
commit
3205c78f01
@ -262,7 +262,7 @@ File.prototype.transform = function (ast) {
|
||||
var self = this;
|
||||
|
||||
this.ast = ast;
|
||||
this.scope = new Scope(ast.program);
|
||||
this.scope = new Scope(ast.program, null, this);
|
||||
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
|
||||
var astRun = function (key) {
|
||||
|
||||
@ -13,11 +13,11 @@ var traverser = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function (node, callId) {
|
||||
module.exports = function (node, callId, scope) {
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
traverse(node, traverser);
|
||||
traverse(node, traverser, scope);
|
||||
|
||||
var call = t.callExpression(callId, [node]);
|
||||
|
||||
|
||||
@ -12,15 +12,17 @@ var t = require("../../types");
|
||||
* @param {Object} className
|
||||
* @param {Object} superName
|
||||
* @param {Boolean} isLoose
|
||||
* @param {Scope} scope
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
function ReplaceSupers(methodNode, className, superName, isLoose, file) {
|
||||
function ReplaceSupers(methodNode, className, superName, isLoose, scope, file) {
|
||||
this.topLevelThisReference = null;
|
||||
this.methodNode = methodNode;
|
||||
this.className = className;
|
||||
this.superName = superName;
|
||||
this.isLoose = isLoose;
|
||||
this.scope = scope;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@ -140,7 +142,7 @@ var traverser = {
|
||||
|
||||
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
|
||||
var state = { self: this, topLevel: topLevel };
|
||||
traverse(node, traverser, null, state);
|
||||
traverse(node, traverser, this.scope, state);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -29,7 +29,7 @@ var exportsTraverser = {
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
var localExports = {};
|
||||
traverse(this.file.ast, exportsTraverser, null, localExports);
|
||||
traverse(this.file.ast, exportsTraverser, this.file.scope, localExports);
|
||||
return localExports;
|
||||
};
|
||||
|
||||
@ -43,7 +43,7 @@ var importsTraverser = {
|
||||
|
||||
DefaultFormatter.prototype.getLocalImports = function () {
|
||||
var localImports = {};
|
||||
traverse(this.file.ast, importsTraverser, null, localImports);
|
||||
traverse(this.file.ast, importsTraverser, this.file.scope, localImports);
|
||||
return localImports;
|
||||
};
|
||||
|
||||
@ -140,7 +140,7 @@ var remapTraverser = {
|
||||
|
||||
DefaultFormatter.prototype.remapAssignments = function () {
|
||||
var state = { self: this };
|
||||
traverse(this.file.ast, remapTraverser, null, state);
|
||||
traverse(this.file.ast, remapTraverser, this.file.scope, state);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
|
||||
@ -18,7 +18,7 @@ function CommonJSFormatter(file) {
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
|
||||
var state = { hasNonDefaultExports: false };
|
||||
traverse(file.ast, traverser, null, state);
|
||||
traverse(file.ast, traverser, file.scope, state);
|
||||
|
||||
this.hasNonDefaultExports = state.hasNonDefaultExports;
|
||||
}
|
||||
|
||||
@ -83,6 +83,8 @@ var runnerSettersTraverser = {
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) {
|
||||
var scope = this.file.scope;
|
||||
|
||||
return t.arrayExpression(_.map(this.ids, function (uid, source) {
|
||||
var state = {
|
||||
source: source,
|
||||
@ -90,7 +92,7 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
|
||||
hoistDeclarators: hoistDeclarators
|
||||
};
|
||||
|
||||
traverse(block, runnerSettersTraverser, null, state);
|
||||
traverse(block, runnerSettersTraverser, scope, state);
|
||||
|
||||
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
|
||||
}));
|
||||
@ -171,7 +173,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
var returnStatement = handlerBody.pop();
|
||||
|
||||
// hoist up all variable declarations
|
||||
traverse(block, hoistVariablesTraverser, null, hoistDeclarators);
|
||||
traverse(block, hoistVariablesTraverser, this.file.scope, hoistDeclarators);
|
||||
|
||||
if (hoistDeclarators.length) {
|
||||
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
|
||||
@ -180,7 +182,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
}
|
||||
|
||||
// hoist up function declarations for circular references
|
||||
traverse(block, hoistFunctionsTraverser, null, handlerBody);
|
||||
traverse(block, hoistFunctionsTraverser, this.file.scope, handlerBody);
|
||||
|
||||
handlerBody.push(returnStatement);
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ Transformer.prototype.transform = function (file) {
|
||||
this.astRun(file, "before");
|
||||
|
||||
var state = { file: file, transformer: this.transformer };
|
||||
traverse(file.ast, transformTraverser, null, state);
|
||||
traverse(file.ast, transformTraverser, file.scope, state);
|
||||
|
||||
this.astRun(file, "after");
|
||||
};
|
||||
|
||||
@ -37,7 +37,7 @@ var functionTraverser = {
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, functionChildrenTraverser, null, state);
|
||||
traverse(node, functionChildrenTraverser, scope, state);
|
||||
|
||||
return context.skip();
|
||||
}
|
||||
@ -58,7 +58,7 @@ 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, functionTraverser, null, state);
|
||||
traverse(node, functionTraverser, scope, state);
|
||||
|
||||
var body;
|
||||
|
||||
|
||||
@ -212,7 +212,7 @@ LetScoping.prototype.needsClosure = function () {
|
||||
var call = t.callExpression(fn, params);
|
||||
var ret = this.file.generateUidIdentifier("ret", this.scope);
|
||||
|
||||
var hasYield = traverse.hasType(fn.body, "YieldExpression", t.FUNCTION_TYPES);
|
||||
var hasYield = traverse.hasType(fn.body, this.scope, "YieldExpression", t.FUNCTION_TYPES);
|
||||
if (hasYield) {
|
||||
fn.generator = true;
|
||||
call = t.yieldExpression(call, true);
|
||||
|
||||
@ -137,7 +137,7 @@ Class.prototype.buildBody = function () {
|
||||
for (var i = 0; i < classBody.length; i++) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
var replaceSupers = new ReplaceSupers(node, this.className, this.superName, this.isLoose, this.file);
|
||||
var replaceSupers = new ReplaceSupers(node, this.className, this.superName, this.isLoose, this.scope, this.file);
|
||||
replaceSupers.replace();
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
|
||||
@ -83,5 +83,5 @@ exports.ForStatement = function (node, parent, scope, context, file) {
|
||||
if (!hasConstants) return;
|
||||
|
||||
var state = { check: check, getIds: getIds };
|
||||
traverse(node, traverser, null, state);
|
||||
traverse(node, traverser, scope, state);
|
||||
};
|
||||
|
||||
@ -36,7 +36,7 @@ var array = function (node, parent, scope, file) {
|
||||
var block = container.callee.body;
|
||||
var body = block.body;
|
||||
|
||||
if (traverse.hasType(node, "YieldExpression", t.FUNCTION_TYPES)) {
|
||||
if (traverse.hasType(node, scope, "YieldExpression", t.FUNCTION_TYPES)) {
|
||||
container.callee.generator = true;
|
||||
container = t.yieldExpression(container, true);
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"));
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);
|
||||
};
|
||||
|
||||
@ -16,6 +16,7 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
|
||||
return remapAsyncToGenerator(
|
||||
node,
|
||||
t.memberExpression(file.addImport("bluebird"), t.identifier("coroutine"))
|
||||
t.memberExpression(file.addImport("bluebird"), t.identifier("coroutine")),
|
||||
scope
|
||||
);
|
||||
};
|
||||
|
||||
@ -36,5 +36,5 @@ exports.MethodDefinition = function (node, parent, scope, context, file) {
|
||||
file: file
|
||||
};
|
||||
|
||||
traverse(value, traverser, null, state);
|
||||
traverse(value, traverser, scope, state);
|
||||
};
|
||||
|
||||
@ -164,6 +164,12 @@ function traverse(parent, opts, scope, state) {
|
||||
// falsy node
|
||||
if (!parent) return;
|
||||
|
||||
if (!scope) {
|
||||
if (parent.type !== "Program" && parent.type !== "File") {
|
||||
throw new Error("Must pass a scope unless traversing a Program/File got a " + parent.type + " node");
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts) opts = {};
|
||||
if (!opts.enter) opts.enter = _.noop;
|
||||
if (!opts.exit) opts.exit = _.noop;
|
||||
@ -217,7 +223,7 @@ function hasBlacklistedType(node, parent, scope, context, state) {
|
||||
}
|
||||
}
|
||||
|
||||
traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
traverse.hasType = function (tree, scope, type, blacklistTypes) {
|
||||
// the node we're searching in is blacklisted
|
||||
if (_.contains(blacklistTypes, tree.type)) return false;
|
||||
|
||||
@ -232,7 +238,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
traverse(tree, {
|
||||
blacklist: blacklistTypes,
|
||||
enter: hasBlacklistedType
|
||||
}, null, state);
|
||||
}, scope, state);
|
||||
|
||||
return state.has;
|
||||
};
|
||||
|
||||
@ -14,11 +14,13 @@ var FOR_KEYS = ["left", "init"];
|
||||
*
|
||||
* @param {Node} block
|
||||
* @param {Scope} [parent]
|
||||
* @param {File} [file]
|
||||
*/
|
||||
|
||||
function Scope(block, parent) {
|
||||
function Scope(block, parent, file) {
|
||||
this.parent = parent;
|
||||
this.block = block;
|
||||
this.file = parent ? parent.file : file;
|
||||
|
||||
var info = this.getInfo();
|
||||
this.references = info.references;
|
||||
@ -34,7 +36,7 @@ Scope.defaultDeclarations = _.flatten([
|
||||
vars.reservedVars
|
||||
].map(_.keys));
|
||||
|
||||
Scope.add = function (node, references) {
|
||||
Scope.add = function (node, references, throwOnDuplicate) {
|
||||
if (!node) return;
|
||||
_.defaults(references, t.getIds(node, true));
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user