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 ]----- */
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)) {
output.indent();
stmt.print(output);
output.newline();
if (is_toplevel) output.newline();
if (!(i == last && is_toplevel)) {
output.newline();
if (is_toplevel) output.newline();
}
}
});
};
@@ -391,8 +394,10 @@ function OutputStream(options) {
output.semicolon();
});
DEFPRINT(AST_BlockStatement, function(self, output){
if (self.body.length > 0) output.with_block(function(){
display_body(self.body, false, output);
var body = self.body;
//if (!(body instanceof Array)) body = [ body ];
if (body.length > 0) output.with_block(function(){
display_body(body, false, output);
});
else output.print("{}");
});
@@ -526,6 +531,43 @@ function OutputStream(options) {
});
/* -----[ 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){
output.print("if");
output.space();
@@ -533,12 +575,14 @@ function OutputStream(options) {
self.condition.print(output);
});
output.space();
self.consequent.print(output);
if (self.alternative) {
make_then(self, output);
output.space();
output.print("else");
output.space();
self.alternative.print(output);
} else {
self.consequent.print(output);
}
});
@@ -849,4 +893,16 @@ function OutputStream(options) {
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");
function load_global(file) {
var code = fs.readFileSync(file, "utf8");
return vm.runInThisContext(code, file);
try {
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("./ast.js");
load_global("./parse.js");
load_global("./output.js");
load_global("../lib/utils.js");
load_global("../lib/ast.js");
load_global("../lib/parse.js");
load_global("../lib/output.js");
///