aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-05-25 23:21:52 +0100
committerGitHub <noreply@github.com>2021-05-26 06:21:52 +0800
commit7caab39e261f1787f1a40fca3e7b6fd6ab21d824 (patch)
tree6a6baf28ee507a5474d23983d857147092dc5c7b
parenteff45eac0ee284a113d1b587263fcef8e397daa3 (diff)
downloadtracifyjs-7caab39e261f1787f1a40fca3e7b6fd6ab21d824.tar.gz
tracifyjs-7caab39e261f1787f1a40fca3e7b6fd6ab21d824.zip
fix corner case in `mangle` (#4966)
fixes #4965
-rw-r--r--README.md13
-rw-r--r--lib/scope.js17
-rw-r--r--test/compress/const.js84
3 files changed, 94 insertions, 20 deletions
diff --git a/README.md b/README.md
index 760fac53..06b16551 100644
--- a/README.md
+++ b/README.md
@@ -1341,3 +1341,16 @@ To allow for better optimizations, the compiler makes various assumptions:
// Actual: "FAIL"
```
UglifyJS may modify the input which in turn may suppress those errors.
+- Earlier versions of JavaScript will throw `TypeError` with the following:
+ ```javascript
+ (function() {
+ {
+ const a = "foo";
+ }
+ {
+ const a = "bar";
+ }
+ })();
+ // TypeError: const 'a' has already been declared
+ ```
+ UglifyJS may modify the input which in turn may suppress those errors.
diff --git a/lib/scope.js b/lib/scope.js
index c74c494a..3de59b99 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -87,7 +87,7 @@ SymbolDef.prototype = {
var def = scope.variables.get(name)
|| scope instanceof AST_Toplevel && scope.globals.get(name)
|| self.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
- return def.name == name && def !== self;
+ return def.name == name;
}, scope.enclosed);
if (def && def !== self) return def.redefined() || def;
},
@@ -123,7 +123,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 1: setup scope chaining and handle definitions
var self = this;
- var const_names = null;
var defun = null;
var exported = false;
var next_def_id = 0;
@@ -202,7 +201,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
} else if (node instanceof AST_SymbolConst) {
var def = scope.def_variable(node);
def.defun = defun;
- const_names.add(def.name, def);
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolDefun) {
var def = defun.def_function(node, tw.parent());
@@ -225,21 +223,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
function walk_scope(descend) {
node.init_vars(scope);
- var save_names = const_names;
var save_defun = defun;
var save_scope = scope;
- if (node instanceof AST_Scope) {
- const_names = new Dictionary();
- defun = node;
- }
+ if (node instanceof AST_Scope) defun = node;
scope = node;
descend();
- if (node instanceof AST_Scope) const_names.each(function(defs, name) {
- if (defs.length > 1 && !node.variables.has(name)) push_uniq(node.enclosed, defs[0]);
- });
scope = save_scope;
defun = save_defun;
- const_names = save_names;
}
function entangle(defun, scope) {
@@ -680,9 +670,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
if (def.scope.parent_scope.find_variable(sym.name)) return false;
redef = scope.def_variable(sym);
scope.to_mangle.push(redef);
- } else if (redef.mangled_name) {
- names_in_use(def.scope, options)[redef.mangled_name] = true;
- return false;
}
redefined.push(def);
def.references.forEach(reference);
diff --git a/test/compress/const.js b/test/compress/const.js
index 58c1a304..6a064b41 100644
--- a/test/compress/const.js
+++ b/test/compress/const.js
@@ -1539,6 +1539,7 @@ issue_4848: {
issue_4954_1: {
rename = true
input: {
+ "use strict";
(function() {
{
const a = "foo";
@@ -1551,18 +1552,23 @@ issue_4954_1: {
})();
}
expect: {
+ "use strict";
(function() {
{
const a = "foo";
console.log(a);
}
{
- const a = "bar";
- console.log(a);
+ const b = "bar";
+ console.log(b);
}
})();
}
- expect_stdout: true
+ expect_stdout: [
+ "foo",
+ "bar",
+ ]
+ node_version: ">=4"
}
issue_4954_2: {
@@ -1610,11 +1616,79 @@ issue_4960: {
{
const o = console.log("PASS");
}
- try {} catch (c) {
- const o = console.log("FAIL");
+ try {} catch (o) {
+ const c = console.log("FAIL");
}
})();
}
expect_stdout: "PASS"
node_version: ">=4"
}
+
+issue_4965_1: {
+ mangle = {}
+ input: {
+ "use strict";
+ try {
+ c;
+ } catch (a) {
+ {
+ const a = 1;
+ }
+ {
+ const a = console.log(typeof c);
+ }
+ }
+ }
+ expect: {
+ "use strict";
+ try {
+ c;
+ } catch (t) {
+ {
+ const c = 1;
+ }
+ {
+ const t = console.log(typeof c);
+ }
+ }
+ }
+ expect_stdout: "undefined"
+ node_version: ">=4"
+}
+
+issue_4965_2: {
+ mangle = {}
+ input: {
+ "use strict";
+ try {
+ throw 1;
+ } catch (e) {
+ try {
+ {
+ const e = 2;
+ }
+ } finally {
+ const e = 3;
+ console.log(typeof t);
+ }
+ }
+ }
+ expect: {
+ "use strict";
+ try {
+ throw 1;
+ } catch (o) {
+ try {
+ {
+ const t = 2;
+ }
+ } finally {
+ const o = 3;
+ console.log(typeof t);
+ }
+ }
+ }
+ expect_stdout: "undefined"
+ node_version: ">=4"
+}