From aa7e8783f84d119f0226f20d019d6f81f325847f Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 12 May 2017 04:51:44 +0800 Subject: [PATCH] fix invalid transform on `const` (#1919) - preserve (re)assignment to `const` for runtime error - suppress `cascade` on `const`, as runtime behaviour is ill-defined --- lib/compress.js | 12 ++++++++- test/compress/collapse_vars.js | 46 ++++++++++++++++++++++++++++++++++ test/compress/drop-unused.js | 25 ++++++++++++++++++ test/compress/sequences.js | 24 ++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/lib/compress.js b/lib/compress.js index 8454a432..f9dcd0f3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -440,6 +440,14 @@ merge(Compressor.prototype, { return fixed(); }); + function is_reference_const(ref) { + if (!(ref instanceof AST_SymbolRef)) return false; + var orig = ref.definition().orig; + for (var i = orig.length; --i >= 0;) { + if (orig[i] instanceof AST_SymbolConst) return true; + } + } + function find_variable(compressor, name) { var scope, i = 0; while (scope = compressor.parent(i++)) { @@ -1909,6 +1917,7 @@ merge(Compressor.prototype, { && node instanceof AST_Assign && node.operator == "=" && node.left instanceof AST_SymbolRef + && !is_reference_const(node.left) && scope === self) { node.right.walk(tw); return true; @@ -3066,7 +3075,8 @@ merge(Compressor.prototype, { } if (left && !(left instanceof AST_SymbolRef - && left.definition().orig[0] instanceof AST_SymbolLambda)) { + && (left.definition().orig[0] instanceof AST_SymbolLambda + || is_reference_const(left)))) { var parent, field; var cdr = self.cdr; while (true) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 2264783d..53ae8f4e 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -1592,3 +1592,49 @@ var_side_effects_3: { } expect_stdout: true } + +reassign_const_1: { + options = { + collapse_vars: true, + } + input: { + function f() { + const a = 1; + a = 2; + return a; + } + console.log(f()); + } + expect: { + function f() { + const a = 1; + a = 2; + return a; + } + console.log(f()); + } + expect_stdout: true +} + +reassign_const_2: { + options = { + collapse_vars: true, + } + input: { + function f() { + const a = 1; + ++a; + return a; + } + console.log(f()); + } + expect: { + function f() { + const a = 1; + ++a; + return a; + } + console.log(f()); + } + expect_stdout: true +} diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 9d37dc7e..7a2f86a9 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -1064,3 +1064,28 @@ issue_1830_2: { } expect_stdout: "1" } + +reassign_const: { + options = { + cascade: true, + sequences: true, + side_effects: true, + unused: true, + } + input: { + function f() { + const a = 1; + a = 2; + return a; + } + console.log(f()); + } + expect: { + function f() { + const a = 1; + return a = 2, a; + } + console.log(f()); + } + expect_stdout: true +} diff --git a/test/compress/sequences.js b/test/compress/sequences.js index 699341c0..3bd0ca35 100644 --- a/test/compress/sequences.js +++ b/test/compress/sequences.js @@ -610,3 +610,27 @@ delete_seq_6: { } expect_stdout: true } + +reassign_const: { + options = { + cascade: true, + sequences: true, + side_effects: true, + } + input: { + function f() { + const a = 1; + a++; + return a; + } + console.log(f()); + } + expect: { + function f() { + const a = 1; + return a++, a; + } + console.log(f()); + } + expect_stdout: true +}