From 65da9acce6bd2548e5ffc7f35527ff62ff3f2fdd Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 28 Mar 2017 16:42:39 +0800 Subject: [PATCH] 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 --- lib/scope.js | 24 +++-- 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" +} -- 2.34.1