Skip to content

Commit

Permalink
unwind IIFE class patterns (#3373)
Browse files Browse the repository at this point in the history
fixes #2332
  • Loading branch information
alexlamsl committed Apr 21, 2019
1 parent 338dd14 commit f01cc1e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 25 deletions.
48 changes: 29 additions & 19 deletions lib/compress.js
Expand Up @@ -1287,7 +1287,9 @@ merge(Compressor.prototype, {
if (node instanceof AST_Try) return true;
if (node instanceof AST_With) return true;
if (replace_all) return false;
return node instanceof AST_SymbolRef && !node.is_declared(compressor);
return node instanceof AST_SymbolRef
&& !node.is_declared(compressor)
&& !(parent instanceof AST_Assign && parent.left === node);
}

function in_conditional(node, parent) {
Expand Down Expand Up @@ -5102,7 +5104,7 @@ merge(Compressor.prototype, {
})) {
return false;
}
} else if (line instanceof AST_EmptyStatement) {
} else if (line instanceof AST_Defun || line instanceof AST_EmptyStatement) {
continue;
} else if (stat) {
return false;
Expand All @@ -5113,16 +5115,15 @@ merge(Compressor.prototype, {
return return_value(stat);
}

function var_exists(catches, name) {
return catches[name] || identifier_atom[name] || scope.var_names()[name];
}

function can_inject_args(catches, safe_to_inject) {
for (var i = 0; i < fn.argnames.length; i++) {
var arg = fn.argnames[i];
if (arg.__unused) continue;
if (!safe_to_inject
|| catches[arg.name]
|| identifier_atom[arg.name]
|| scope.var_names()[arg.name]) {
return false;
}
if (!safe_to_inject || var_exists(catches, arg.name)) return false;
if (in_loop) in_loop.push(arg.definition());
}
return true;
Expand All @@ -5131,15 +5132,15 @@ merge(Compressor.prototype, {
function can_inject_vars(catches, safe_to_inject) {
for (var i = 0; i < fn.body.length; i++) {
var stat = fn.body[i];
if (stat instanceof AST_Defun) {
if (!safe_to_inject || var_exists(catches, stat.name.name)) return false;
continue;
}
if (!(stat instanceof AST_Var)) continue;
if (!safe_to_inject) return false;
for (var j = stat.definitions.length; --j >= 0;) {
var name = stat.definitions[j].name;
if (catches[name.name]
|| identifier_atom[name.name]
|| scope.var_names()[name.name]) {
return false;
}
if (var_exists(catches, name.name)) return false;
if (in_loop) in_loop.push(name.definition());
}
}
Expand Down Expand Up @@ -5243,12 +5244,21 @@ merge(Compressor.prototype, {
flatten_args(decls, expressions);
flatten_vars(decls, expressions);
expressions.push(value);
if (decls.length) {
i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
scope.body.splice(i, 0, make_node(AST_Var, fn, {
definitions: decls
}));
}
var args = fn.body.filter(function(stat) {
if (stat instanceof AST_Defun) {
var def = stat.name.definition();
scope.functions.set(def.name, def);
scope.variables.set(def.name, def);
scope.enclosed.push(def);
scope.var_names()[def.name] = true;
return true;
}
});
args.unshift(scope.body.indexOf(compressor.parent(level - 1)) + 1, 0);
if (decls.length) args.push(make_node(AST_Var, fn, {
definitions: decls
}));
[].splice.apply(scope.body, args);
return expressions;
}
});
Expand Down
21 changes: 21 additions & 0 deletions test/compress/collapse_vars.js
Expand Up @@ -6157,3 +6157,24 @@ sub_property: {
}
expect_stdout: "PASS"
}

assign_undeclared: {
options = {
collapse_vars: true,
toplevel: true,
unused: true,
}
input: {
var A = (console.log(42), function() {});
B = new A();
console.log(typeof B);
}
expect: {
B = new (console.log(42), function() {})();
console.log(typeof B);
}
expect_stdout: [
"42",
"object",
]
}
36 changes: 30 additions & 6 deletions test/compress/functions.js
Expand Up @@ -3003,12 +3003,10 @@ issue_3366: {
f();
}
expect: {
(function() {
function a() {}
(function() {
this && a && console.log("PASS");
})();
})();
void function() {
this && a && console.log("PASS");
}();
function a() {}
}
expect_stdout: "PASS"
}
Expand Down Expand Up @@ -3041,3 +3039,29 @@ issue_3371: {
}
expect_stdout: "function"
}

class_iife: {
options = {
inline: true,
sequences: true,
toplevel: true,
}
input: {
var A = function() {
function B() {}
B.prototype.m = function() {
console.log("PASS");
};
return B;
}();
new A().m();
}
expect: {
var A = (B.prototype.m = function() {
console.log("PASS");
}, B);
function B() {}
new A().m();
}
expect_stdout: "PASS"
}

0 comments on commit f01cc1e

Please sign in to comment.