diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-03-15 21:39:23 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-03-17 17:56:17 -0700 |
commit | c4fc4453aacc8c1933e9cd256c04890978095003 (patch) | |
tree | 18b9f7065863fa8bd32abad2ae2454471b2058f6 /tools | |
parent | 6c31546ced32fd968ae50da7803964c9195ebd62 (diff) |
simplify nested ifs with identical elses
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js-optimizer.js | 18 | ||||
-rw-r--r-- | tools/test-js-optimizer-si-output.js | 29 | ||||
-rw-r--r-- | tools/test-js-optimizer-si.js | 33 |
3 files changed, 77 insertions, 3 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index bb6acf73..4b63ab9b 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -303,6 +303,16 @@ function removeAllEmptySubNodes(ast) { traverse(ast, removeEmptySubNodes); } +function astCompare(x, y) { + if (!Array.isArray(x)) return x === y; + if (!Array.isArray(y)) return false; + if (x.length !== y.length) return false; + for (var i = 0; i < x.length; i++) { + if (!astCompare(x[i], y[i])) return false; + } + return true; +} + // Passes // Dump the AST. Useful for debugging. For example, @@ -830,14 +840,14 @@ function simplifyExpressions(ast) { function simplifyIfs(ast) { traverse(ast, function(node, type) { // simplify if (x) { if (y) { .. } } to if (x ? y : 0) { .. } - if (type === 'if' && !node[3]) { + if (type === 'if') { var body = node[2]; // recurse to handle chains while (body[0] === 'block') { var stats = body[1]; if (stats.length > 1) { var last = stats[stats.length-1]; - if (last[0] === 'if' && !last[3]) { + if (last[0] === 'if') { // try to commaify - turn everything between the ifs into a comma operator inside the second if var ok = true; for (var i = 0; i < stats.length-1; i++) { @@ -857,7 +867,9 @@ function simplifyIfs(ast) { } if (stats.length !== 1) break; var singleton = stats[0]; - if (singleton[0] === 'if' && !singleton[3]) { + // we can handle elses, but must be fully identical + if (!astCompare(node[3], singleton[3])) break; + if (singleton[0] === 'if') { node[1] = ['conditional', node[1], singleton[1], ['num', 0]]; body = node[2] = singleton[2]; } else { diff --git a/tools/test-js-optimizer-si-output.js b/tools/test-js-optimizer-si-output.js index bd36ef10..8b93803d 100644 --- a/tools/test-js-optimizer-si-output.js +++ b/tools/test-js-optimizer-si-output.js @@ -66,5 +66,34 @@ function a() { g(); } } + andNowForElses(); + if (x ? y : 0) { + f(); + } else { + label = 5; + } + if (x) { + if (y) { + f(); + } else { + label = 5; + } + } else { + label = 6; + } + if (x) { + if (y) { + f(); + } else { + label = 5; + } + } + if (x) { + if (y) { + f(); + } + } else { + label = 5; + } } diff --git a/tools/test-js-optimizer-si.js b/tools/test-js-optimizer-si.js index 5f6b334f..6952b183 100644 --- a/tools/test-js-optimizer-si.js +++ b/tools/test-js-optimizer-si.js @@ -84,5 +84,38 @@ function a() { g(); } } + andNowForElses(); + if (x) { + if (y) { + f(); + } else { + label = 5; + } + } else { + label = 5; + } + if (x) { + if (y) { + f(); + } else { + label = 5; + } + } else { + label = 6; + } + if (x) { + if (y) { + f(); + } else { + label = 5; + } + } + if (x) { + if (y) { + f(); + } + } else { + label = 5; + } } |