Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d758a216b | ||
|
|
af13f8dd2c | ||
|
|
88423f2574 | ||
|
|
ee632a5519 | ||
|
|
dfe47bcc42 | ||
|
|
6d3dcaa59e | ||
|
|
1bc0df1569 | ||
|
|
a98ba994bd | ||
|
|
cd671221c5 | ||
|
|
bce3919748 | ||
|
|
61b66e83f1 | ||
|
|
a5db8cd14c | ||
|
|
2021c2fa3e | ||
|
|
484d3fd8c7 | ||
|
|
3bf8699f95 |
14
lib/ast.js
14
lib/ast.js
@@ -120,6 +120,20 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
ctor.prototype._validate.call(this);
|
||||
} while (ctor = ctor.BASE);
|
||||
},
|
||||
validate_ast: function() {
|
||||
var marker = {};
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node.validate_visited === marker) {
|
||||
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
||||
type: "AST_" + node.TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
}));
|
||||
}
|
||||
node.validate_visited = marker;
|
||||
}));
|
||||
},
|
||||
}, null);
|
||||
|
||||
(AST_Node.log_function = function(fn, verbose) {
|
||||
|
||||
@@ -587,7 +587,10 @@ merge(Compressor.prototype, {
|
||||
d.assignments++;
|
||||
var fixed = d.fixed;
|
||||
var value = eq ? node.right : node;
|
||||
if (is_modified(compressor, tw, node, value, 0)) return;
|
||||
if (is_modified(compressor, tw, node, value, 0)) {
|
||||
d.fixed = false;
|
||||
return;
|
||||
}
|
||||
var safe = eq || safe_to_read(tw, d);
|
||||
node.right.walk(tw);
|
||||
if (safe && safe_to_assign(tw, d)) {
|
||||
@@ -600,6 +603,7 @@ merge(Compressor.prototype, {
|
||||
return node.right;
|
||||
};
|
||||
} else {
|
||||
if (d.single_use) d.single_use = false;
|
||||
sym.fixed = d.fixed = function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
@@ -896,6 +900,7 @@ merge(Compressor.prototype, {
|
||||
if (safe_to_read(tw, d) && safe_to_assign(tw, d)) {
|
||||
push_ref(d, exp);
|
||||
mark(tw, d);
|
||||
if (d.single_use) d.single_use = false;
|
||||
d.fixed = function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
@@ -1197,7 +1202,9 @@ merge(Compressor.prototype, {
|
||||
function find_loop_scope_try() {
|
||||
var node = compressor.self(), level = 0;
|
||||
do {
|
||||
if (node instanceof AST_Catch || node instanceof AST_Finally) {
|
||||
if (node instanceof AST_Catch) {
|
||||
if (!compressor.parent(level).bfinally) level++;
|
||||
} else if (node instanceof AST_Finally) {
|
||||
level++;
|
||||
} else if (node instanceof AST_IterationStatement) {
|
||||
in_loop = true;
|
||||
@@ -3065,7 +3072,7 @@ merge(Compressor.prototype, {
|
||||
|
||||
(function(def) {
|
||||
function to_node(value, orig) {
|
||||
if (value instanceof AST_Node) return make_node(value.CTOR, orig, value);
|
||||
if (value instanceof AST_Node) return value.clone(true);
|
||||
if (Array.isArray(value)) return make_node(AST_Array, orig, {
|
||||
elements: value.map(function(value) {
|
||||
return to_node(value, orig);
|
||||
@@ -4454,8 +4461,18 @@ merge(Compressor.prototype, {
|
||||
var sym = def.name.definition();
|
||||
if (!drop_vars || sym.id in in_use_ids) {
|
||||
if (def.value && indexOf_assign(sym, def) < 0) {
|
||||
def.value = def.value.drop_side_effect_free(compressor);
|
||||
if (def.value) def.value.tail_node().write_only = false;
|
||||
var write_only = def.value.write_only;
|
||||
var value = def.value.drop_side_effect_free(compressor);
|
||||
if (def.value !== value) {
|
||||
def.value = value && make_sequence(def.value, [
|
||||
value,
|
||||
make_node(AST_Number, def.value, {
|
||||
value: 0
|
||||
}),
|
||||
]);
|
||||
} else if (def.value.write_only !== write_only) {
|
||||
def.value.write_only = write_only;
|
||||
}
|
||||
}
|
||||
var old_def, var_defs = var_defs_by_id.get(sym.id);
|
||||
if (!def.value) {
|
||||
@@ -5063,6 +5080,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}));
|
||||
self.transform(new TreeTransformer(function(node, descend) {
|
||||
if (node instanceof AST_Binary) return replace("right");
|
||||
if (node instanceof AST_PropAccess) {
|
||||
if (!(node.expression instanceof AST_SymbolRef)) return;
|
||||
var defs = defs_by_id[node.expression.definition().id];
|
||||
@@ -5078,10 +5096,15 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
if (node instanceof AST_Unary) {
|
||||
if (unary_side_effects[node.operator]) return;
|
||||
if (!(node.expression instanceof AST_SymbolRef)) return;
|
||||
if (!(node.expression.definition().id in defs_by_id)) return;
|
||||
return replace("expression");
|
||||
}
|
||||
|
||||
function replace(prop) {
|
||||
var sym = node[prop];
|
||||
if (!(sym instanceof AST_SymbolRef)) return;
|
||||
if (!(sym.definition().id in defs_by_id)) return;
|
||||
var opt = node.clone();
|
||||
opt.expression = make_node(AST_Object, node, {
|
||||
opt[prop] = make_node(AST_Object, sym, {
|
||||
properties: []
|
||||
});
|
||||
return opt;
|
||||
@@ -5303,10 +5326,7 @@ merge(Compressor.prototype, {
|
||||
return make_sequence(this, [ expression, property ]);
|
||||
});
|
||||
def(AST_SymbolRef, function(compressor) {
|
||||
if (!this.is_declared(compressor)) return this;
|
||||
var def = this.definition();
|
||||
if (member(this, def.references)) def.replaced++;
|
||||
return null;
|
||||
return this.is_declared(compressor) ? null : this;
|
||||
});
|
||||
def(AST_This, return_null);
|
||||
def(AST_Unary, function(compressor, first_in_statement) {
|
||||
@@ -5314,10 +5334,7 @@ merge(Compressor.prototype, {
|
||||
this.write_only = !this.expression.has_side_effects(compressor);
|
||||
return this;
|
||||
}
|
||||
if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) {
|
||||
this.expression.definition().replaced++;
|
||||
return null;
|
||||
}
|
||||
if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) return null;
|
||||
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (first_in_statement && expression && is_iife_call(expression)) {
|
||||
if (expression === this.expression && this.operator == "!") return this;
|
||||
@@ -6415,16 +6432,11 @@ merge(Compressor.prototype, {
|
||||
|
||||
function return_value(stat) {
|
||||
if (!stat) return make_node(AST_Undefined, self);
|
||||
if (stat instanceof AST_Return) {
|
||||
if (!stat.value) return make_node(AST_Undefined, self);
|
||||
return stat.value.clone(true);
|
||||
}
|
||||
if (stat instanceof AST_SimpleStatement) {
|
||||
return make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body
|
||||
});
|
||||
}
|
||||
if (stat instanceof AST_Return) return stat.value || make_node(AST_Undefined, self);
|
||||
if (stat instanceof AST_SimpleStatement) return make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body
|
||||
});
|
||||
}
|
||||
|
||||
function can_flatten_body(stat) {
|
||||
@@ -7630,6 +7642,8 @@ merge(Compressor.prototype, {
|
||||
single_use = false;
|
||||
} else if (recursive_ref(compressor, def)) {
|
||||
single_use = false;
|
||||
} else if (compressor.option("ie8") && fixed.name && def !== fixed.name.definition()) {
|
||||
single_use = false;
|
||||
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
|
||||
single_use = fixed.is_constant_expression(self.scope);
|
||||
if (single_use == "f") {
|
||||
@@ -7638,8 +7652,6 @@ merge(Compressor.prototype, {
|
||||
scope.inlined = true;
|
||||
} while (scope = scope.parent_scope);
|
||||
}
|
||||
} else if (compressor.option("ie8") && fixed.name && def !== fixed.name.definition()) {
|
||||
single_use = false;
|
||||
}
|
||||
if (single_use) fixed.parent_scope = self.scope;
|
||||
} else if (!fixed || !fixed.is_constant_expression()) {
|
||||
|
||||
@@ -178,13 +178,17 @@ function minify(files, options) {
|
||||
toplevel = toplevel[action](option);
|
||||
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
||||
});
|
||||
if (options.validate) toplevel.validate_ast();
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
if (options.compress) {
|
||||
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
if (options.validate) toplevel.validate_ast();
|
||||
}
|
||||
if (timings) timings.scope = Date.now();
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
|
||||
@@ -230,6 +230,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
} else {
|
||||
new_def = scope.def_variable(node);
|
||||
}
|
||||
old_def.defun = new_def.scope;
|
||||
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||
node.thedef = new_def;
|
||||
node.reference(options);
|
||||
|
||||
@@ -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.10.0",
|
||||
"version": "3.10.1",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -269,6 +269,7 @@ function test_case(test) {
|
||||
quote_style: 3,
|
||||
});
|
||||
try {
|
||||
input.validate_ast();
|
||||
U.parse(input_code);
|
||||
} catch (ex) {
|
||||
log([
|
||||
@@ -315,8 +316,8 @@ function test_case(test) {
|
||||
output = U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
}
|
||||
output = make_code(output, output_options);
|
||||
if (expect != output) {
|
||||
var output_code = make_code(output, output_options);
|
||||
if (expect != output_code) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
@@ -329,14 +330,15 @@ function test_case(test) {
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
output: output_code,
|
||||
expected: expect
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// expect == output
|
||||
try {
|
||||
U.parse(output);
|
||||
output.validate_ast();
|
||||
U.parse(output_code);
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
@@ -350,7 +352,7 @@ function test_case(test) {
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
output: output_code,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
@@ -409,7 +411,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = run_code(output, toplevel);
|
||||
actual = run_code(output_code, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
|
||||
@@ -8280,3 +8280,40 @@ issue_3976: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4012: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
try {
|
||||
throw 2;
|
||||
} catch (b) {
|
||||
a = "PASS";
|
||||
if (--b)
|
||||
return;
|
||||
if (3);
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
try {
|
||||
throw 2;
|
||||
} catch (b) {
|
||||
a = "PASS";
|
||||
if (--b)
|
||||
return;
|
||||
if (3);
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1729,7 +1729,7 @@ chained_3: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
var c = 2;
|
||||
var c = b;
|
||||
b++;
|
||||
return c;
|
||||
}(0, 2));
|
||||
@@ -2718,7 +2718,7 @@ issue_3962_1: {
|
||||
0..toString();
|
||||
} while (0);
|
||||
if (c) console.log("PASS");
|
||||
})((a--, 1));
|
||||
}((a--, 1)), 0);
|
||||
void 0;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -2751,7 +2751,7 @@ issue_3962_2: {
|
||||
0..toString();
|
||||
} while (0);
|
||||
if (c) console.log("PASS");
|
||||
})((a--, 1));
|
||||
}((a--, 1)), 0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -2789,3 +2789,62 @@ issue_3986: {
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_4017: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
console.log(function f() {
|
||||
var b = c &= 0;
|
||||
var c = a++ + (A = a);
|
||||
var d = c && c[f];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
console.log(function() {
|
||||
c &= 0;
|
||||
var c = (a++, A = a, 0);
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4025: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 0, c = 0, d = a++;
|
||||
try {
|
||||
var e = console.log(c), f = b;
|
||||
} finally {
|
||||
var d = b = 1, d = c + 1;
|
||||
c = 0;
|
||||
}
|
||||
console.log(a, b, d);
|
||||
}
|
||||
expect: {
|
||||
var d, c = 0;
|
||||
try {
|
||||
console.log(c);
|
||||
} finally {
|
||||
d = c + 1;
|
||||
c = 0;
|
||||
}
|
||||
console.log(1, 1, d);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
"1 1 1",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4747,3 +4747,34 @@ issue_3929: {
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_4006: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function() {
|
||||
(function(b, c) {
|
||||
for (var k in console.log(c), 0)
|
||||
return b += 0;
|
||||
})(0, --a);
|
||||
return a ? 0 : --a;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(function(c) {
|
||||
for (var k in console.log(c), 0)
|
||||
return;
|
||||
})(--a), a || --a;
|
||||
}
|
||||
expect_stdout: "-1"
|
||||
}
|
||||
|
||||
@@ -12,6 +12,20 @@ must_replace: {
|
||||
}
|
||||
}
|
||||
|
||||
repeated_nodes: {
|
||||
options = {
|
||||
global_defs: {
|
||||
"@N": "rand()",
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(N, N);
|
||||
}
|
||||
expect: {
|
||||
console.log(rand(), rand());
|
||||
}
|
||||
}
|
||||
|
||||
keyword: {
|
||||
options = {
|
||||
global_defs: {
|
||||
|
||||
@@ -1016,3 +1016,28 @@ issue_3945_2: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4023: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = function() {
|
||||
return { p: 0 };
|
||||
}();
|
||||
return console.log("undefined" != typeof a);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
console.log(void 0 !== {});
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
@@ -2544,12 +2544,12 @@ issue_3999: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function f() {
|
||||
for (var c = 0; c < 2; c++)
|
||||
for (var o = 0; o < 2; o++)
|
||||
try {
|
||||
f[0];
|
||||
} catch (f) {
|
||||
var f = 0;
|
||||
console.log(c);
|
||||
console.log(o);
|
||||
}
|
||||
})();
|
||||
})(typeof f);
|
||||
@@ -2593,3 +2593,124 @@ issue_4001: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4015: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var n, a = 0, b;
|
||||
function f() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (b) {
|
||||
(function g() {
|
||||
(function b() {
|
||||
a++;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var n, o = 0, c;
|
||||
function t() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (c) {
|
||||
(function n() {
|
||||
(function c() {
|
||||
o++;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
t();
|
||||
console.log(o);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_4019: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
try {
|
||||
console.log("FAIL");
|
||||
} catch (b) {}
|
||||
}, a = (console.log(a.length), ++a);
|
||||
}
|
||||
expect: {
|
||||
var o = function() {
|
||||
try {
|
||||
console.log("FAIL");
|
||||
} catch (o) {}
|
||||
}, o = (console.log(o.length), ++o);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_4028: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
try {
|
||||
A;
|
||||
} catch (e) {}
|
||||
}
|
||||
var b = a += a;
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
try {
|
||||
A;
|
||||
} catch (a) {}
|
||||
}
|
||||
var b = a += a;
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect_stdout: "string"
|
||||
}
|
||||
|
||||
issue_2737: {
|
||||
options = {
|
||||
ie8: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
a();
|
||||
})(function f() {
|
||||
console.log(typeof f);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
a();
|
||||
})(function f() {
|
||||
console.log(typeof f);
|
||||
});
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
@@ -7383,3 +7383,26 @@ issue_3974: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4030: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
{
|
||||
delete (a = "PASS");
|
||||
A = "PASS";
|
||||
}
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "PASS";
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ operator_in: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3983: {
|
||||
issue_3983_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
@@ -323,7 +323,71 @@ issue_3983: {
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
g();
|
||||
function g() {}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3983_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f() {
|
||||
g && g();
|
||||
}
|
||||
f();
|
||||
function g() {
|
||||
0 ? a : 0;
|
||||
}
|
||||
var b = a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4008: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f(b, b) {
|
||||
console.log(b);
|
||||
}
|
||||
f && f(a && a[a]);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
function f(b, b) {
|
||||
console.log(b);
|
||||
}
|
||||
f(a[a]);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS.push(" in ");
|
||||
|
||||
var ASSIGNMENTS = [
|
||||
@@ -1136,18 +1137,6 @@ function log(options) {
|
||||
errorln(original_result);
|
||||
errorln("uglified result:");
|
||||
errorln(uglify_result);
|
||||
errorln("//-------------------------------------------------------------");
|
||||
var reduced = reduce_test(original_code, JSON.parse(options), {
|
||||
verbose: false,
|
||||
}).code;
|
||||
if (reduced) {
|
||||
errorln();
|
||||
errorln("// reduced test case (output will differ)");
|
||||
errorln();
|
||||
errorln(reduced);
|
||||
errorln();
|
||||
errorln("//-------------------------------------------------------------");
|
||||
}
|
||||
} else {
|
||||
errorln("// !!! uglify failed !!!");
|
||||
errorln(uglify_code);
|
||||
@@ -1158,6 +1147,20 @@ function log(options) {
|
||||
errorln(original_result);
|
||||
}
|
||||
}
|
||||
errorln("//-------------------------------------------------------------");
|
||||
var reduce_options = JSON.parse(options);
|
||||
reduce_options.validate = true;
|
||||
var reduced = reduce_test(original_code, reduce_options, {
|
||||
verbose: false,
|
||||
}).code;
|
||||
if (reduced) {
|
||||
errorln();
|
||||
errorln("// reduced test case (output will differ)");
|
||||
errorln();
|
||||
errorln(reduced);
|
||||
errorln();
|
||||
errorln("//-------------------------------------------------------------");
|
||||
}
|
||||
errorln("minify(options):");
|
||||
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
||||
errorln();
|
||||
@@ -1231,7 +1234,7 @@ function patch_try_catch(orig, toplevel) {
|
||||
if (typeof result != "object" || typeof result.name != "string" || typeof result.message != "string") {
|
||||
if (!stack.filled && match[1]) stack.push({
|
||||
code: code,
|
||||
index: index,
|
||||
index: index && index - 1,
|
||||
offset: offset,
|
||||
tries: JSON.parse(JSON.stringify(tries)),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user