clean up statement to expression explosion
This commit is contained in:
parent
3d28ce7903
commit
a87f6f6fdd
@ -18,9 +18,7 @@ var hoistVariablesVisitor = {
|
||||
if (this.isVariableDeclaration() && node.kind === "var") {
|
||||
var bindings = this.getBindingIdentifiers();
|
||||
for (var key in bindings) {
|
||||
scope.push({
|
||||
id: bindings[key].identifiers
|
||||
});
|
||||
scope.push({ id: bindings[key] });
|
||||
}
|
||||
|
||||
var exprs = [];
|
||||
@ -210,16 +208,18 @@ export default class TraversalPath {
|
||||
var paths = [];
|
||||
|
||||
var add = function (path) {
|
||||
paths = paths.concat(path.getLastStatements());
|
||||
if (path) paths = paths.concat(path.getLastStatements());
|
||||
};
|
||||
|
||||
if (this.isIfStatement()) {
|
||||
add(this.get("consequent"));
|
||||
add(this.get("alternate"));
|
||||
} else if (this.isFor() || this.isWhile()) {
|
||||
} else if (this.isDoExpression()) {
|
||||
add(this.get("body"));
|
||||
} else if (this.isProgram() || this.isBlockStatement()) {
|
||||
add(this.get("body").pop());
|
||||
} else {
|
||||
paths.push(this);
|
||||
}
|
||||
|
||||
return paths;
|
||||
@ -231,9 +231,8 @@ export default class TraversalPath {
|
||||
if (toSequenceExpression) {
|
||||
return this.node = toSequenceExpression;
|
||||
} else {
|
||||
var container = t.shadowFunctionExpression(null, [], t.blockStatement(nodes));
|
||||
|
||||
this.node = t.callExpression(container, []);
|
||||
var container = t.functionExpression(null, [], t.blockStatement(nodes));
|
||||
container.shadow = true;
|
||||
|
||||
// add implicit returns to all ending expression statements
|
||||
var last = this.getLastStatements();
|
||||
@ -244,6 +243,8 @@ export default class TraversalPath {
|
||||
}
|
||||
}
|
||||
|
||||
this.node = t.callExpression(container, []);
|
||||
|
||||
this.traverse(hoistVariablesVisitor);
|
||||
|
||||
return this.node;
|
||||
|
||||
@ -510,7 +510,7 @@ export default class Scope {
|
||||
|
||||
getFunctionParent() {
|
||||
var scope = this;
|
||||
while (scope.parent && !t.isFunction(scope.block) && !t.isShadowFunctionExpression(scope.block)) {
|
||||
while (scope.parent && !t.isFunction(scope.block)) {
|
||||
scope = scope.parent;
|
||||
}
|
||||
return scope;
|
||||
@ -627,6 +627,7 @@ export default class Scope {
|
||||
if (!name) return false;
|
||||
if (this.hasOwnBinding(name)) return true;
|
||||
if (this.parentHasBinding(name)) return true;
|
||||
if (this.uids[name]) return true;
|
||||
if (includes(Scope.globals, name)) return true;
|
||||
if (includes(Scope.contextVariables, name)) return true;
|
||||
return false;
|
||||
|
||||
@ -28,50 +28,73 @@ export function toComputedKey(node: Object, key: Object = node.key || node.prope
|
||||
|
||||
export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object {
|
||||
var declars = [];
|
||||
var exprs = [];
|
||||
var bailed = false;
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
if (t.isExpression(node)) {
|
||||
exprs.push(node);
|
||||
} else if (t.isExpressionStatement(node)) {
|
||||
exprs.push(node.expression);
|
||||
} else if (t.isVariableDeclaration(node)) {
|
||||
if (node.kind !== "var") return; // bailed
|
||||
|
||||
each(node.declarations, function (declar) {
|
||||
declars.push({
|
||||
kind: node.kind,
|
||||
id: declar.id
|
||||
});
|
||||
exprs.push(t.assignmentExpression("=", declar.id, declar.init));
|
||||
});
|
||||
} else if (t.isIfStatement(node)) {
|
||||
exprs.push(t.conditionalExpression(
|
||||
node.test,
|
||||
node.consequent ? t.toSequenceExpression([node.consequent]) : t.identifier("undefined"),
|
||||
node.alternate ? t.toSequenceExpression([node.alternate]) : t.identifier("undefined")
|
||||
));
|
||||
} else if (t.isBlockStatement(node)) {
|
||||
exprs.push(t.toSequenceExpression(node.body));
|
||||
} else {
|
||||
// bailed, we can't understand this
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
var result = convert(nodes);
|
||||
if (bailed) return;
|
||||
|
||||
for (let i = 0; i < declars.length; i++) {
|
||||
scope.push(declars[i]);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
|
||||
if (exprs.length === 1) {
|
||||
return exprs[0];
|
||||
} else {
|
||||
return t.sequenceExpression(exprs);
|
||||
function convert(nodes) {
|
||||
var ensureLastUndefined = false;
|
||||
var exprs = [];
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
if (t.isExpression(node)) {
|
||||
exprs.push(node);
|
||||
} else if (t.isExpressionStatement(node)) {
|
||||
exprs.push(node.expression);
|
||||
} else if (t.isVariableDeclaration(node)) {
|
||||
if (node.kind !== "var") return bailed = true; // bailed
|
||||
|
||||
each(node.declarations, function (declar) {
|
||||
var bindings = t.getBindingIdentifiers(declar);
|
||||
for (var key in bindings) {
|
||||
declars.push({
|
||||
kind: node.kind,
|
||||
id: bindings[key]
|
||||
});
|
||||
}
|
||||
|
||||
if (declar.init) {
|
||||
exprs.push(t.assignmentExpression("=", declar.id, declar.init));
|
||||
}
|
||||
});
|
||||
|
||||
ensureLastUndefined = true;
|
||||
continue;
|
||||
} else if (t.isIfStatement(node)) {
|
||||
var consequent = node.consequent ? convert([node.consequent]) : t.identifier("undefined");
|
||||
var alternate = node.alternate ? convert([node.alternate]) : t.identifier("undefined");
|
||||
if (!consequent || !alternate) return bailed = true;
|
||||
|
||||
exprs.push(t.conditionalExpression(node.test, consequent, alternate));
|
||||
} else if (t.isBlockStatement(node)) {
|
||||
exprs.push(convert(node.body));
|
||||
} else {
|
||||
// bailed, we can't understand this
|
||||
return bailed = true;
|
||||
}
|
||||
|
||||
ensureLastUndefined = false;
|
||||
}
|
||||
|
||||
if (ensureLastUndefined) {
|
||||
exprs.push(t.identifier("undefined"));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (exprs.length === 1) {
|
||||
return exprs[0];
|
||||
} else {
|
||||
return t.sequenceExpression(exprs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,8 +72,6 @@ export function getLastStatements(node: Object): Array<Object> {
|
||||
if (t.isIfStatement(node)) {
|
||||
add(node.consequent);
|
||||
add(node.alternate);
|
||||
} else if (t.isFor(node) || t.isWhile(node)) {
|
||||
add(node.body);
|
||||
} else if (t.isProgram(node) || t.isBlockStatement(node)) {
|
||||
add(node.body[node.body.length - 1]);
|
||||
} else if (node) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user