diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-03-28 16:42:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-28 16:42:39 +0800 |
commit | 65da9acce6bd2548e5ffc7f35527ff62ff3f2fdd (patch) | |
tree | a236ec345b4d7ea87a9baf112b672a85471fb075 | |
parent | 67d0237f73c3147855983edde137cd95a2cb1749 (diff) | |
download | tracifyjs-65da9acce6bd2548e5ffc7f35527ff62ff3f2fdd.tar.gz tracifyjs-65da9acce6bd2548e5ffc7f35527ff62ff3f2fdd.zip |
handle var within catch of the same name (#1711)
The following code prints `1`:
var a = 1;
!function(){
a = 4;
try{
throw 2;
} catch (a) {
var a = 3;
}
}();
console.log(a);
fixes #1708
-rw-r--r-- | lib/scope.js | 24 | ||||
-rw-r--r-- | test/compress/issue-1704.js | 172 |
2 files changed, 191 insertions, 5 deletions
diff --git a/lib/scope.js b/lib/scope.js index c2d0b552..025d4ca3 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -75,9 +75,16 @@ SymbolDef.prototype = { } else if (!this.mangled_name && !this.unmangleable(options)) { var s = this.scope; - if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda) + var sym = this.orig[0]; + if (!options.screw_ie8 && sym instanceof AST_SymbolLambda) s = s.parent_scope; - this.mangled_name = s.next_mangled(options, this); + var def; + if (options.screw_ie8 + && sym instanceof AST_SymbolCatch + && (def = s.parent_scope.find_variable(sym))) { + this.mangled_name = def.mangled_name || def.name; + } else + this.mangled_name = s.next_mangled(options, this); if (this.global && cache) { cache.set(this.name, this.mangled_name); } @@ -152,9 +159,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ (node.scope = defun.parent_scope).def_function(node); } else if (node instanceof AST_SymbolVar - || node instanceof AST_SymbolConst) { + || node instanceof AST_SymbolConst) { defun.def_variable(node); - if (defun !== scope) node.mark_enclosed(options); + if (defun !== scope) { + node.mark_enclosed(options); + var def = scope.find_variable(node); + if (node.thedef !== def) { + node.thedef = def; + node.reference(options); + } + } } else if (node instanceof AST_SymbolCatch) { scope.def_variable(node); @@ -278,7 +292,7 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) { } }); -AST_SymbolRef.DEFMETHOD("reference", function(options) { +AST_Symbol.DEFMETHOD("reference", function(options) { this.definition().references.push(this); this.mark_enclosed(options); }); diff --git a/test/compress/issue-1704.js b/test/compress/issue-1704.js index 3fa637fe..a73f7f99 100644 --- a/test/compress/issue-1704.js +++ b/test/compress/issue-1704.js @@ -173,3 +173,175 @@ mangle_catch_var_ie8_toplevel: { expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);' expect_stdout: "PASS" } + +mangle_catch_redef_1: { + options = { + screw_ie8: true, + toplevel: false, + } + mangle = { + screw_ie8: true, + toplevel: false, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_ie8: { + options = { + screw_ie8: false, + toplevel: false, + } + mangle = { + screw_ie8: false, + toplevel: false, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_toplevel: { + options = { + screw_ie8: true, + toplevel: true, + } + mangle = { + screw_ie8: true, + toplevel: true, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_ie8_toplevel: { + options = { + screw_ie8: false, + toplevel: true, + } + mangle = { + screw_ie8: false, + toplevel: true, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_redef_2: { + options = { + screw_ie8: true, + toplevel: false, + } + mangle = { + screw_ie8: true, + toplevel: false, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_ie8: { + options = { + screw_ie8: false, + toplevel: false, + } + mangle = { + screw_ie8: false, + toplevel: false, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_toplevel: { + options = { + screw_ie8: true, + toplevel: true, + } + mangle = { + screw_ie8: true, + toplevel: true, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_ie8_toplevel: { + options = { + screw_ie8: false, + toplevel: true, + } + mangle = { + screw_ie8: false, + toplevel: true, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "undefined" +} |