aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js42
1 files changed, 40 insertions, 2 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 96047291..f8f4d17f 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -184,11 +184,45 @@ function Compressor(options, false_by_default) {
} while (CHANGED);
return statements;
+ /// XXX: this function is UGLY and kinda wrong.
+ /// I think it would be cleaner if it operates backwards.
function handle_if_return(statements, compressor) {
- var in_lambda = compressor.self() instanceof AST_Lambda;
+ var self = compressor.self();
+ var in_lambda = self instanceof AST_Lambda;
var last = statements.length - 1;
return MAP(statements, function(stat, i){
if (stat instanceof AST_If
+ && stat.body instanceof AST_Continue
+ && !stat.alternative
+ && self === stat.body.target()) {
+ CHANGED = true;
+ if (i < last) {
+ var rest = statements.slice(i + 1);
+ var cond = stat.condition;
+ while (rest[0] instanceof AST_If
+ && rest[0].body instanceof AST_Continue
+ && self === rest[0].body.target()
+ && !rest[0].alternative) {
+ cond = make_node(AST_Binary, rest[0], {
+ operator: "||",
+ left: cond,
+ right: rest[0].condition
+ });
+ rest.shift();
+ }
+ return MAP.last(make_node(AST_If, stat, {
+ condition: cond.negate(compressor),
+ body: make_node(AST_BlockStatement, stat, {
+ body: rest
+ }).optimize(compressor)
+ }).optimize(compressor))
+ } else {
+ return make_node(AST_SimpleStatement, stat, {
+ body: stat.condition
+ }).optimize(compressor);
+ }
+ }
+ if (stat instanceof AST_If
&& stat.body instanceof AST_Return
&& !stat.alternative
&& in_lambda) {
@@ -199,6 +233,7 @@ function Compressor(options, false_by_default) {
var cond = stat.condition;
while (rest[0] instanceof AST_If
&& rest[0].body instanceof AST_Return
+ && !rest[0].body.value
&& !rest[0].alternative) {
cond = make_node(AST_Binary, rest[0], {
operator: "||",
@@ -645,7 +680,10 @@ function Compressor(options, false_by_default) {
(function(def){
def(AST_StatementBase, function(){ return null });
def(AST_Jump, function(){ return this });
- def(AST_BlockStatement, function(){ return this.body[this.body.length - 1].aborts() });
+ def(AST_BlockStatement, function(){
+ var n = this.body.length;
+ return n > 0 && this.body[n - 1].aborts();
+ });
})(function(node, func){
node.DEFMETHOD("aborts", func);
});