From ec0440f26492ff548a670605f232de8e14a93390 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 28 Feb 2021 23:13:49 +0000 Subject: [PATCH] fix corner cases with `import` (#4709) fixes #4708 --- lib/compress.js | 11 +++++++++++ test/compress/imports.js | 35 +++++++++++++++++++++++++++++++++++ test/sandbox.js | 2 +- test/ufuzz/index.js | 24 ++++++++++++++++++++---- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index ba7ab4a0..fb6d16f9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1127,6 +1127,9 @@ merge(Compressor.prototype, { def(AST_SymbolCatch, function() { this.definition().fixed = false; }); + def(AST_SymbolImport, function() { + this.definition().fixed = false; + }); def(AST_SymbolRef, function(tw, descend, compressor) { var d = this.definition(); push_ref(d, this); @@ -5836,6 +5839,14 @@ merge(Compressor.prototype, { assignments.add(def.id, node); return true; } + if (node instanceof AST_SymbolImport) { + var def = node.definition(); + if (!(def.id in in_use_ids) && (!drop_vars || !is_safe_lexical(def))) { + in_use_ids[def.id] = true; + in_use.push(def); + } + return true; + } } else if (node instanceof AST_This && scope instanceof AST_DefClass) { var def = scope.name.definition(); if (!(def.id in in_use_ids)) { diff --git a/test/compress/imports.js b/test/compress/imports.js index 558dd6a8..50b3fb69 100644 --- a/test/compress/imports.js +++ b/test/compress/imports.js @@ -165,3 +165,38 @@ forbid_merge: { f(); } } + +issue_4708_1: { + options = { + imports: true, + toplevel: true, + unused: true, + } + input: { + var a; + import a from "foo"; + } + expect: { + var a; + import a from "foo"; + } +} + +issue_4708_2: { + options = { + imports: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var a; + console.log(a); + import a from "foo"; + } + expect: { + var a; + console.log(a); + import a from "foo"; + } +} diff --git a/test/sandbox.js b/test/sandbox.js index b2b5e00c..bdce4188 100644 --- a/test/sandbox.js +++ b/test/sandbox.js @@ -61,7 +61,7 @@ exports.patch_module_statements = function(code) { symbols = symbols.replace(/[{}]/g, "").trim().replace(/\s*,\s*/g, ","); symbols = symbols.replace(/\*/, '"*"').replace(/\bas\s+(?!$|,|as\s)/g, ":"); imports.push([ - "var {", + "const {", symbols, "} = new Proxy(Object.create(null), { get(_, value) { return { value }; } });", ].join("")); diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index b066e2fa..f38cdd96 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -1020,22 +1020,30 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}"; case STMT_VAR: if (SUPPORT.destructuring && stmtDepth == 1 && rng(5) == 0) { - unique_vars.push("c"); - var s = rng(2) ? " " + createVarName(MANDATORY) : ""; + unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity"); + var s = ""; + if (rng(2)) { + var name = createVarName(MANDATORY); + block_vars.push(name); + s += " " + name; + } if (rng(10)) { if (s) s += ","; if (rng(2)) { - s += " * as " + createVarName(MANDATORY); + var name = createVarName(MANDATORY); + block_vars.push(name); + s += " * as " + name; } else { var names = []; for (var i = rng(4); --i >= 0;) { var name = createVarName(MANDATORY); + block_vars.push(name); names.push(rng(2) ? getDotKey() + " as " + name : name); } s += " { " + names.join(", ") + " }"; } } - unique_vars.pop(); + unique_vars.length -= 6; if (s) s += " from"; return "import" + s + ' "path/to/module.js";'; } else if (SUPPORT.destructuring && rng(20) == 0) { @@ -2217,6 +2225,10 @@ function is_error_recursion(ex) { return ex.name == "RangeError" && /Invalid string length|Maximum call stack size exceeded/.test(ex.message); } +function is_error_redeclaration(ex) { + return ex.name == "SyntaxError" && /already been declared|redeclaration/.test(ex.message); +} + function is_error_destructuring(ex) { return ex.name == "TypeError" && /^Cannot destructure /.test(ex.message); } @@ -2409,6 +2421,10 @@ for (var round = 1; round <= num_iterations; round++) { ok = sandbox.same_stdout(original_strict, uglify_strict); } } + // ignore difference in error message caused by `import` symbol redeclaration + if (!ok && errored && /\bimport\b/.test(original_code)) { + if (is_error_redeclaration(uglify_result) && is_error_redeclaration(original_result)) ok = true; + } // ignore difference in error message caused by `in` if (!ok && errored && is_error_in(uglify_result) && is_error_in(original_result)) ok = true; // ignore difference in error message caused by spread syntax -- 2.34.1