From: Alex Lam S.L Date: Tue, 19 Sep 2017 21:23:20 +0000 (+0800) Subject: suppress `collapse_vars` of `this` into "use strict" (#2326) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=00f509405b44882bab5d63d97caacb21691cdad6;p=UglifyJS.git suppress `collapse_vars` of `this` into "use strict" (#2326) fixes #2319 --- diff --git a/lib/ast.js b/lib/ast.js index 0918574d..9b243f16 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -134,11 +134,10 @@ var AST_Debugger = DEFNODE("Debugger", null, { $documentation: "Represents a debugger statement", }, AST_Statement); -var AST_Directive = DEFNODE("Directive", "value scope quote", { +var AST_Directive = DEFNODE("Directive", "value quote", { $documentation: "Represents a directive, like \"use strict\";", $propdoc: { value: "[string] The value of this directive as a plain string (it's not an AST_String!)", - scope: "[AST_Scope/S] The scope that this directive affects", quote: "[string] the original quote character" }, }, AST_Statement); @@ -299,10 +298,9 @@ var AST_With = DEFNODE("With", "expression", { /* -----[ scope and functions ]----- */ -var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { +var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", { $documentation: "Base class for all statements introducing a lexical scope", $propdoc: { - directives: "[string*/S] an array of directives declared in this scope", variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope", functions: "[Object/S] like `variables`, but only lists function declarations", uses_with: "[boolean/S] tells whether this scope uses the `with` statement", diff --git a/lib/compress.js b/lib/compress.js index 3164c5a0..9e516a89 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -842,6 +842,8 @@ merge(Compressor.prototype, { && !fn.uses_eval && (iife = compressor.parent()) instanceof AST_Call && iife.expression === fn) { + var fn_strict = compressor.has_directive("use strict"); + if (fn_strict && fn.body.indexOf(fn_strict) < 0) fn_strict = false; var names = Object.create(null); for (var i = fn.argnames.length; --i >= 0;) { var sym = fn.argnames[i]; @@ -859,7 +861,7 @@ merge(Compressor.prototype, { } arg = null; } - if (node instanceof AST_This && !tw.find_parent(AST_Scope)) { + if (node instanceof AST_This && (fn_strict || !tw.find_parent(AST_Scope))) { arg = null; return true; } diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 5e7e982e..ecd18610 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -2451,3 +2451,73 @@ issue_2313_2: { } expect_stdout: "0" } + +issue_2319_1: { + options = { + collapse_vars: true, + unused: true, + } + input: { + console.log(function(a) { + return a; + }(!function() { + return this; + }())); + } + expect: { + console.log(function(a) { + return !function() { + return this; + }(); + }()); + } + expect_stdout: "false" +} + +issue_2319_2: { + options = { + collapse_vars: true, + unused: true, + } + input: { + console.log(function(a) { + "use strict"; + return a; + }(!function() { + return this; + }())); + } + expect: { + console.log(function(a) { + "use strict"; + return a; + }(!function() { + return this; + }())); + } + expect_stdout: "false" +} + +issue_2319_3: { + options = { + collapse_vars: true, + unused: true, + } + input: { + "use strict"; + console.log(function(a) { + return a; + }(!function() { + return this; + }())); + } + expect: { + "use strict"; + console.log(function(a) { + return !function() { + return this; + }(); + }()); + } + expect_stdout: "true" +}