Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7aba2dc5f2 | ||
|
|
12a6728c4e | ||
|
|
042c228c7b | ||
|
|
e2b00814a8 | ||
|
|
104d385ba9 | ||
|
|
fdbbef2991 |
@@ -7844,15 +7844,15 @@ Compressor.prototype.compress = function(node) {
|
||||
&& !consts.has(sym.name)
|
||||
&& self.find_variable(sym.name) === sym.definition();
|
||||
})) return node;
|
||||
node.definitions.forEach(function(def) {
|
||||
vars.set(def.name.name, def);
|
||||
node.definitions.forEach(function(defn) {
|
||||
vars.set(defn.name.name, defn);
|
||||
++vars_found;
|
||||
});
|
||||
var seq = node.to_assignments();
|
||||
if (p instanceof AST_ForEnumeration && p.init === node) {
|
||||
if (seq) return seq;
|
||||
var def = node.definitions[0].name;
|
||||
return make_node(AST_SymbolRef, def, def);
|
||||
var sym = node.definitions[0].name;
|
||||
return make_node(AST_SymbolRef, sym, sym);
|
||||
}
|
||||
if (p instanceof AST_For && p.init === node) return seq;
|
||||
if (!seq) return in_list ? List.skip : make_node(AST_EmptyStatement, node);
|
||||
@@ -7867,21 +7867,22 @@ Compressor.prototype.compress = function(node) {
|
||||
self.transform(tt);
|
||||
if (vars_found > 0) {
|
||||
// collect only vars which don't show up in self's arguments list
|
||||
var defs = [];
|
||||
var defns = [];
|
||||
if (self instanceof AST_Lambda) self.each_argname(function(argname) {
|
||||
vars.del(argname.name);
|
||||
});
|
||||
vars.each(function(def, name) {
|
||||
def = def.clone();
|
||||
def.value = null;
|
||||
defs.push(def);
|
||||
vars.set(name, def);
|
||||
vars.each(function(defn, name) {
|
||||
defn = defn.clone();
|
||||
defn.name = defn.name.clone();
|
||||
defn.value = null;
|
||||
defns.push(defn);
|
||||
vars.set(name, defn);
|
||||
defn.name.definition().orig.unshift(defn.name);
|
||||
});
|
||||
if (defs.length > 0) {
|
||||
if (defns.length > 0) {
|
||||
// try to merge in assignments
|
||||
insert_vars(self.body);
|
||||
defs = make_node(AST_Var, self, { definitions: defs });
|
||||
hoisted.push(defs);
|
||||
hoisted.push(make_node(AST_Var, self, { definitions: defns }));
|
||||
}
|
||||
}
|
||||
self.body = dirs.concat(hoisted, self.body);
|
||||
@@ -7895,13 +7896,13 @@ Compressor.prototype.compress = function(node) {
|
||||
&& expr.operator == "="
|
||||
&& (sym = expr.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name)) {
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
var defn = vars.get(sym.name);
|
||||
if (defn.value) break;
|
||||
var value = expr.right;
|
||||
if (value instanceof AST_Sequence) value = value.clone();
|
||||
def.value = value;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
defn.value = value;
|
||||
remove(defns, defn);
|
||||
defns.push(defn);
|
||||
body.shift();
|
||||
continue;
|
||||
}
|
||||
@@ -7910,11 +7911,11 @@ Compressor.prototype.compress = function(node) {
|
||||
&& assign.operator == "="
|
||||
&& (sym = assign.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name)) {
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
def.value = assign.right;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
var defn = vars.get(sym.name);
|
||||
if (defn.value) break;
|
||||
defn.value = assign.right;
|
||||
remove(defns, defn);
|
||||
defns.push(defn);
|
||||
stat.body = make_sequence(expr, expr.expressions.slice(1));
|
||||
continue;
|
||||
}
|
||||
@@ -9157,14 +9158,16 @@ Compressor.prototype.compress = function(node) {
|
||||
var cond = fuzzy_eval(compressor, self.condition);
|
||||
if (!cond) {
|
||||
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
||||
var body = [ make_node(AST_SimpleStatement, self.condition, { body: self.condition }) ];
|
||||
var body = [
|
||||
make_node(AST_SimpleStatement, self.condition, { body: self.condition }).transform(compressor),
|
||||
];
|
||||
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
||||
if (self.alternative) body.push(self.alternative);
|
||||
return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
|
||||
} else if (!(cond instanceof AST_Node)) {
|
||||
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
|
||||
var body = [
|
||||
make_node(AST_SimpleStatement, self.condition, { body: self.condition }),
|
||||
make_node(AST_SimpleStatement, self.condition, { body: self.condition }).transform(compressor),
|
||||
self.body,
|
||||
];
|
||||
if (self.alternative) extract_declarations_from_unreachable_code(compressor, self.alternative, body);
|
||||
@@ -9493,20 +9496,12 @@ Compressor.prototype.compress = function(node) {
|
||||
left: self.expression,
|
||||
right: exp,
|
||||
}),
|
||||
body: make_node(AST_BlockStatement, self, {
|
||||
body: statements,
|
||||
}),
|
||||
body: make_node(AST_BlockStatement, self, { body: statements }),
|
||||
alternative: null,
|
||||
}).optimize(compressor);
|
||||
if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, {
|
||||
body: exp,
|
||||
}));
|
||||
statements.unshift(make_node(AST_SimpleStatement, self.expression, {
|
||||
body:self.expression,
|
||||
}));
|
||||
return make_node(AST_BlockStatement, self, {
|
||||
body: statements,
|
||||
}).optimize(compressor);
|
||||
if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, { body: exp }));
|
||||
statements.unshift(make_node(AST_SimpleStatement, self.expression, { body: self.expression }));
|
||||
return make_node(AST_BlockStatement, self, { body: statements }).optimize(compressor);
|
||||
case 2:
|
||||
if (!member(default_branch, body) || !no_break(body[1])) break;
|
||||
var statements = body[0].body.slice();
|
||||
@@ -9524,14 +9519,10 @@ Compressor.prototype.compress = function(node) {
|
||||
left: self.expression,
|
||||
right: body[0].expression,
|
||||
}),
|
||||
body: make_node(AST_BlockStatement, body[0], {
|
||||
body: statements,
|
||||
}),
|
||||
body: make_node(AST_BlockStatement, body[0], { body: statements }),
|
||||
alternative: exclusive && alternative || null,
|
||||
});
|
||||
if (!exclusive && alternative) node = make_node(AST_BlockStatement, self, {
|
||||
body: [ node, alternative ],
|
||||
});
|
||||
if (!exclusive && alternative) node = make_node(AST_BlockStatement, self, { body: [ node, alternative ] });
|
||||
return node.optimize(compressor);
|
||||
}
|
||||
return self;
|
||||
@@ -10534,7 +10525,7 @@ Compressor.prototype.compress = function(node) {
|
||||
insert = scope.body.indexOf(child) + 1;
|
||||
if (!insert) return false;
|
||||
if (!safe_from_await_yield(fn, avoid_await_yield(scope))) return false;
|
||||
var safe_to_inject = exp !== fn || fn.parent_scope.resolve() === scope;
|
||||
var safe_to_inject = (exp !== fn || fn.parent_scope.resolve() === scope) && !scope.pinned();
|
||||
if (scope instanceof AST_Toplevel) {
|
||||
if (compressor.toplevel.vars) {
|
||||
defined.set("arguments", true);
|
||||
@@ -13262,6 +13253,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (!(fn instanceof AST_LambdaExpression)) return;
|
||||
if (fn.name) return;
|
||||
if (fn.uses_arguments) return;
|
||||
if (fn.pinned()) return;
|
||||
if (is_generator(fn)) return;
|
||||
var arrow = is_arrow(fn);
|
||||
if (arrow && fn.value) return;
|
||||
@@ -13277,6 +13269,7 @@ Compressor.prototype.compress = function(node) {
|
||||
scope = scope.parent_scope;
|
||||
}
|
||||
if (!member(scope, compressor.stack)) return;
|
||||
if (scope.pinned() && fn.variables.size() > (arrow ? 0 : 1)) return;
|
||||
if (scope instanceof AST_Toplevel) {
|
||||
if (fn.variables.size() > (arrow ? 0 : 1)) {
|
||||
if (!compressor.toplevel.vars) return;
|
||||
@@ -13348,6 +13341,7 @@ Compressor.prototype.compress = function(node) {
|
||||
def.single_use = false;
|
||||
if (!in_loop) return;
|
||||
if (def.references.length == def.replaced) return;
|
||||
if (def.orig.length == def.eliminated) return;
|
||||
if (def.orig.length == 1 && fn.functions.has(name)) return;
|
||||
if (!all(def.orig, function(sym) {
|
||||
if (sym instanceof AST_SymbolConst) return false;
|
||||
|
||||
@@ -226,7 +226,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
defun.def_variable(node);
|
||||
} else if (node instanceof AST_SymbolLambda) {
|
||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
if (options.ie) def.defun = defun.parent_scope.resolve();
|
||||
if (options.ie && node.name != "arguments") def.defun = defun.parent_scope.resolve();
|
||||
} else if (node instanceof AST_SymbolLet) {
|
||||
var def = scope.def_variable(node);
|
||||
if (exported) def.exported = true;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.15.2",
|
||||
"version": "3.15.3",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -82,14 +82,14 @@ ifs_3_should_warn: {
|
||||
"WARN: Boolean && always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Condition left of && always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Condition always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/conditionals.js:3,34]",
|
||||
"WARN: + in boolean context always true [test/compress/conditionals.js:10,19]",
|
||||
"WARN: Boolean || always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Condition left of || always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Condition always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/conditionals.js:12,15]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/conditionals.js:12,15]",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -3473,3 +3473,27 @@ issue_5314_2: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5370: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments({}) {
|
||||
return arguments;
|
||||
try {} catch (e) {
|
||||
var arguments;
|
||||
}
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments({}) {
|
||||
return arguments;
|
||||
var arguments;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1508,6 +1508,48 @@ unsafe_call_3: {
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
inline_eval_inner: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(typeof eval("arguments"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(typeof eval("arguments"));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
inline_eval_outer: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
A = 42;
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(A);
|
||||
console.log(eval("typeof a"));
|
||||
}
|
||||
expect: {
|
||||
A = 42;
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(A);
|
||||
console.log(eval("typeof a"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2616: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -8228,3 +8270,62 @@ issue_5366: {
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5376_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a;
|
||||
for (;42;)
|
||||
var b = function() {
|
||||
var c;
|
||||
throw new Error(c++);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
for (;;) {
|
||||
42;
|
||||
throw new Error(NaN);
|
||||
}
|
||||
}
|
||||
expect_stdout: Error("NaN")
|
||||
}
|
||||
|
||||
issue_5376_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a;
|
||||
for (;42;)
|
||||
var b = function() {
|
||||
var c;
|
||||
c++;
|
||||
throw new Error("PASS");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
for (;;) {
|
||||
0;
|
||||
throw new Error("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: Error("PASS")
|
||||
}
|
||||
|
||||
@@ -499,3 +499,34 @@ issue_5195: {
|
||||
}
|
||||
expect_stdout: "[object Object]"
|
||||
}
|
||||
|
||||
issue_5378: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2;
|
||||
while (a--)
|
||||
(function() {
|
||||
var b;
|
||||
var c;
|
||||
while (console.log(b));
|
||||
--b;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = 2;
|
||||
while (a--) {
|
||||
b = void 0;
|
||||
var b, c;
|
||||
while (console.log(b));
|
||||
--b;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ reduce_vars: {
|
||||
C: 0,
|
||||
},
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
|
||||
@@ -1299,3 +1299,27 @@ issue_5360: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5370: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments(...a) {
|
||||
return arguments;
|
||||
try {} catch (e) {
|
||||
var arguments;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments(...a) {
|
||||
return arguments;
|
||||
var arguments;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1329,7 +1329,7 @@ issue_3490_2: {
|
||||
expect: {
|
||||
var b = 42, c = "FAIL";
|
||||
var a;
|
||||
for (c = "PASS", b; "" == typeof d;);
|
||||
for (c = "PASS"; "" == typeof d;);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
|
||||
Reference in New Issue
Block a user