some fixes (need testing) in AST_If codegen

This commit is contained in:
Mihai Bazon
2012-08-18 12:29:57 +03:00
parent cd8ae5f712
commit 4488758d48
2 changed files with 73 additions and 12 deletions

View File

@@ -363,12 +363,15 @@ function OutputStream(options) {
/* -----[ statements ]----- */ /* -----[ statements ]----- */
function display_body(body, is_toplevel, output) { function display_body(body, is_toplevel, output) {
body.forEach(function(stmt){ var last = body.length - 1;
body.forEach(function(stmt, i){
if (!(stmt instanceof AST_EmptyStatement)) { if (!(stmt instanceof AST_EmptyStatement)) {
output.indent(); output.indent();
stmt.print(output); stmt.print(output);
output.newline(); if (!(i == last && is_toplevel)) {
if (is_toplevel) output.newline(); output.newline();
if (is_toplevel) output.newline();
}
} }
}); });
}; };
@@ -391,8 +394,10 @@ function OutputStream(options) {
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_BlockStatement, function(self, output){ DEFPRINT(AST_BlockStatement, function(self, output){
if (self.body.length > 0) output.with_block(function(){ var body = self.body;
display_body(self.body, false, output); //if (!(body instanceof Array)) body = [ body ];
if (body.length > 0) output.with_block(function(){
display_body(body, false, output);
}); });
else output.print("{}"); else output.print("{}");
}); });
@@ -526,6 +531,43 @@ function OutputStream(options) {
}); });
/* -----[ if ]----- */ /* -----[ if ]----- */
function make_then(self, output) {
// The squeezer replaces "block"-s that contain only a single
// statement with the statement itself; technically, the AST
// is correct, but this can create problems when we output an
// IF having an ELSE clause where the THEN clause ends in an
// IF *without* an ELSE block (then the outer ELSE would refer
// to the inner IF). This function checks for this case and
// adds the block brackets if needed.
if (!self.consequent)
return output.semicolon();
if (self.consequent instanceof AST_Do) {
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
// croaks with "syntax error" on code like this: if (foo)
// do ... while(cond); else ... we need block brackets
// around do/while
make_block(self.consequent, output);
return;
}
var b = self.consequent;
while (true) {
if (b instanceof AST_If) {
if (!b.alternative) {
make_block(self.consequent, output);
return;
}
b = b.alternative;
}
else if (b instanceof AST_While ||
b instanceof AST_Do ||
b instanceof AST_For ||
b instanceof AST_ForIn) {
b = b.body;
}
else break;
}
self.consequent.print(output);
};
DEFPRINT(AST_If, function(self, output){ DEFPRINT(AST_If, function(self, output){
output.print("if"); output.print("if");
output.space(); output.space();
@@ -533,12 +575,14 @@ function OutputStream(options) {
self.condition.print(output); self.condition.print(output);
}); });
output.space(); output.space();
self.consequent.print(output);
if (self.alternative) { if (self.alternative) {
make_then(self, output);
output.space(); output.space();
output.print("else"); output.print("else");
output.space(); output.space();
self.alternative.print(output); self.alternative.print(output);
} else {
self.consequent.print(output);
} }
}); });
@@ -849,4 +893,16 @@ function OutputStream(options) {
return best_of(a); return best_of(a);
}; };
function make_block(stmt, output) {
if (stmt instanceof AST_BlockStatement) {
stmt.print(output);
return;
}
output.with_block(function(){
output.indent();
stmt.print(output);
output.newline();
});
};
})(); })();

View File

@@ -7,14 +7,19 @@
var sys = require("util"); var sys = require("util");
function load_global(file) { function load_global(file) {
var code = fs.readFileSync(file, "utf8"); try {
return vm.runInThisContext(code, file); var code = fs.readFileSync(file, "utf8");
return vm.runInThisContext(code, file);
} catch(ex) {
sys.debug("ERROR in file: " + file + " / " + ex);
process.exit(1);
}
}; };
load_global("./utils.js"); load_global("../lib/utils.js");
load_global("./ast.js"); load_global("../lib/ast.js");
load_global("./parse.js"); load_global("../lib/parse.js");
load_global("./output.js"); load_global("../lib/output.js");
/// ///