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