aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Bazon <mihai@bazon.net>2012-08-18 12:29:57 +0300
committerMihai Bazon <mihai@bazon.net>2012-08-18 12:29:57 +0300
commit4488758d485b0b624d4858f764bdf08b10365d3b (patch)
tree7682c1a38dc4db87e02fcb4966bfb927d1884255
parentcd8ae5f712fa64ac2d6dff0c5028d8bc70d331ed (diff)
downloadtracifyjs-4488758d485b0b624d4858f764bdf08b10365d3b.tar.gz
tracifyjs-4488758d485b0b624d4858f764bdf08b10365d3b.zip
some fixes (need testing) in AST_If codegen
-rw-r--r--lib/output.js68
-rwxr-xr-xtmp/test-node.js (renamed from lib/node.js)17
2 files changed, 73 insertions, 12 deletions
diff --git a/lib/output.js b/lib/output.js
index 05a0447d..893ab05a 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -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();
+ });
+ };
+
})();
diff --git a/lib/node.js b/tmp/test-node.js
index ae2ec845..10b520ea 100755
--- a/lib/node.js
+++ b/tmp/test-node.js
@@ -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");
///