Handle nested if statements with alternates in printer
Previously we saw a bug that when we have nested if statements and an alternate then the generated code may confuse which if statement the alternate belongs to. e.g. ``` if (foo) if (bar) bar(); else baz(); ``` But this was handled by looking at the consequent and if it's an if we add a block. However we didn't handle situations where it's not an if but the last recursive statement is an if: ``` if (foo) while (bar) if (baz) baz(); else shoosh() ``` This handles it by recurring until we get the last statement.
This commit is contained in:
@@ -16,7 +16,7 @@ export function IfStatement(node: Object) {
|
||||
this.push(")");
|
||||
this.space();
|
||||
|
||||
let needsBlock = node.alternate && t.isIfStatement(node.consequent);
|
||||
let needsBlock = node.alternate && t.isIfStatement(getLastStatement(node.consequent));
|
||||
if (needsBlock) {
|
||||
this.push("{");
|
||||
this.newline();
|
||||
@@ -38,6 +38,12 @@ export function IfStatement(node: Object) {
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively get the last statement.
|
||||
function getLastStatement(statement) {
|
||||
if (!t.isStatement(statement.body)) return statement;
|
||||
return getLastStatement(statement.body);
|
||||
}
|
||||
|
||||
export function ForStatement(node: Object) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
|
||||
@@ -16,12 +16,32 @@ suite("generation", function () {
|
||||
assert.ok(t.VISITOR_KEYS[type], type + " should not exist");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("valid code", function() {
|
||||
|
||||
suite("programmatic generation", function() {
|
||||
test("numeric member expression", function() {
|
||||
// Should not generate `0.foo`
|
||||
var mem = t.memberExpression(t.numericLiteral(60702), t.identifier("foo"));
|
||||
new Function(generate.default(mem).code);
|
||||
});
|
||||
|
||||
test("nested if statements needs block", function() {
|
||||
var ifStatement = t.ifStatement(
|
||||
t.stringLiteral("top cond"),
|
||||
t.whileStatement(
|
||||
t.stringLiteral("while cond"),
|
||||
t.ifStatement(
|
||||
t.stringLiteral("nested"),
|
||||
t.expressionStatement(t.numericLiteral(1))
|
||||
)
|
||||
),
|
||||
t.expressionStatement(t.stringLiteral("alt"))
|
||||
);
|
||||
|
||||
var ast = parse(generate.default(ifStatement).code);
|
||||
assert.equal(ast.program.body[0].consequent.type, 'BlockStatement');
|
||||
});
|
||||
});
|
||||
|
||||
var suites = require("babel-helper-fixtures").default(__dirname + "/fixtures");
|
||||
|
||||
Reference in New Issue
Block a user