Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9707ccdc9f | ||
|
|
cb8f3a2a31 | ||
|
|
8b3259e0c2 | ||
|
|
b66f47b8dd | ||
|
|
8d2e6f333e | ||
|
|
b3ef5e514d | ||
|
|
627f5fb41e | ||
|
|
d90777b724 | ||
|
|
e49297e5eb | ||
|
|
ebd82b3fb6 | ||
|
|
d074aa6e27 | ||
|
|
b052f62710 | ||
|
|
d4ac84b255 | ||
|
|
e250396d7e | ||
|
|
c6fa39b482 | ||
|
|
9aae4f2424 | ||
|
|
008c236137 | ||
|
|
b1c0664066 | ||
|
|
ea999b0e92 | ||
|
|
ce7e220de4 | ||
|
|
2bdaca10ae | ||
|
|
aa0029204e | ||
|
|
f352bcec3a | ||
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a |
@@ -19,6 +19,7 @@ env:
|
|||||||
- NODEJS_VER=node/4
|
- NODEJS_VER=node/4
|
||||||
- NODEJS_VER=node/6
|
- NODEJS_VER=node/6
|
||||||
- NODEJS_VER=node/8
|
- NODEJS_VER=node/8
|
||||||
|
- NODEJS_VER=node/10
|
||||||
- NODEJS_VER=node/latest
|
- NODEJS_VER=node/latest
|
||||||
before_install:
|
before_install:
|
||||||
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
|
|||||||
@@ -664,7 +664,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
||||||
compressor from discarding function names. Useful for code relying on
|
compressor from discarding function names. Useful for code relying on
|
||||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
|
||||||
|
|
||||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
||||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ environment:
|
|||||||
- NODEJS_VER: node/4
|
- NODEJS_VER: node/4
|
||||||
- NODEJS_VER: node/6
|
- NODEJS_VER: node/6
|
||||||
- NODEJS_VER: node/8
|
- NODEJS_VER: node/8
|
||||||
|
- NODEJS_VER: node/10
|
||||||
- NODEJS_VER: node/latest
|
- NODEJS_VER: node/latest
|
||||||
install:
|
install:
|
||||||
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git %LOCALAPPDATA%\nvs
|
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git %LOCALAPPDATA%\nvs
|
||||||
|
|||||||
17
bin/uglifyjs
17
bin/uglifyjs
@@ -56,6 +56,11 @@ program.option("--wrap <name>", "Embed everything as a function with “exports
|
|||||||
program.arguments("[files...]").parseArgv(process.argv);
|
program.arguments("[files...]").parseArgv(process.argv);
|
||||||
if (program.configFile) {
|
if (program.configFile) {
|
||||||
options = JSON.parse(read_file(program.configFile));
|
options = JSON.parse(read_file(program.configFile));
|
||||||
|
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
|
||||||
|
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
|
||||||
|
expression: true
|
||||||
|
}).getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||||
fatal("ERROR: cannot write source map to STDOUT");
|
fatal("ERROR: cannot write source map to STDOUT");
|
||||||
@@ -337,17 +342,9 @@ function parse_js(flag) {
|
|||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
try {
|
try {
|
||||||
UglifyJS.minify(value, {
|
UglifyJS.parse(value, {
|
||||||
parse: {
|
|
||||||
expression: true
|
expression: true
|
||||||
},
|
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
ast: true,
|
|
||||||
code: false
|
|
||||||
}
|
|
||||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
var name = node.left.print_to_string();
|
var name = node.left.print_to_string();
|
||||||
var value = node.right;
|
var value = node.right;
|
||||||
|
|||||||
346
lib/compress.js
346
lib/compress.js
@@ -106,10 +106,16 @@ function Compressor(options, false_by_default) {
|
|||||||
var pure_funcs = this.options["pure_funcs"];
|
var pure_funcs = this.options["pure_funcs"];
|
||||||
if (typeof pure_funcs == "function") {
|
if (typeof pure_funcs == "function") {
|
||||||
this.pure_funcs = pure_funcs;
|
this.pure_funcs = pure_funcs;
|
||||||
} else {
|
} else if (typeof pure_funcs == "string") {
|
||||||
this.pure_funcs = pure_funcs ? function(node) {
|
this.pure_funcs = function(node) {
|
||||||
|
return pure_funcs !== node.expression.print_to_string();
|
||||||
|
};
|
||||||
|
} else if (Array.isArray(pure_funcs)) {
|
||||||
|
this.pure_funcs = function(node) {
|
||||||
return pure_funcs.indexOf(node.expression.print_to_string()) < 0;
|
return pure_funcs.indexOf(node.expression.print_to_string()) < 0;
|
||||||
} : return_true;
|
};
|
||||||
|
} else {
|
||||||
|
this.pure_funcs = return_true;
|
||||||
}
|
}
|
||||||
var top_retain = this.options["top_retain"];
|
var top_retain = this.options["top_retain"];
|
||||||
if (top_retain instanceof RegExp) {
|
if (top_retain instanceof RegExp) {
|
||||||
@@ -450,8 +456,7 @@ merge(Compressor.prototype, {
|
|||||||
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
||||||
}
|
}
|
||||||
return all(def.orig, function(sym) {
|
return all(def.orig, function(sym) {
|
||||||
return !(sym instanceof AST_SymbolDefun
|
return !(sym instanceof AST_SymbolDefun || sym instanceof AST_SymbolLambda);
|
||||||
|| sym instanceof AST_SymbolLambda);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,6 +503,15 @@ merge(Compressor.prototype, {
|
|||||||
d.direct_access = true;
|
d.direct_access = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mark_assignment_to_arguments(node) {
|
||||||
|
if (!(node instanceof AST_Sub)) return;
|
||||||
|
var expr = node.expression;
|
||||||
|
var prop = node.property;
|
||||||
|
if (expr instanceof AST_SymbolRef && expr.name == "arguments" && prop instanceof AST_Number) {
|
||||||
|
expr.definition().reassigned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var suppressor = new TreeWalker(function(node) {
|
var suppressor = new TreeWalker(function(node) {
|
||||||
if (!(node instanceof AST_Symbol)) return;
|
if (!(node instanceof AST_Symbol)) return;
|
||||||
var d = node.definition();
|
var d = node.definition();
|
||||||
@@ -516,7 +530,10 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Assign, function(tw, descend, compressor) {
|
def(AST_Assign, function(tw, descend, compressor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
var sym = node.left;
|
var sym = node.left;
|
||||||
if (!(sym instanceof AST_SymbolRef)) return;
|
if (!(sym instanceof AST_SymbolRef)) {
|
||||||
|
mark_assignment_to_arguments(sym);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var d = sym.definition();
|
var d = sym.definition();
|
||||||
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
@@ -759,7 +776,10 @@ merge(Compressor.prototype, {
|
|||||||
var node = this;
|
var node = this;
|
||||||
if (node.operator != "++" && node.operator != "--") return;
|
if (node.operator != "++" && node.operator != "--") return;
|
||||||
var exp = node.expression;
|
var exp = node.expression;
|
||||||
if (!(exp instanceof AST_SymbolRef)) return;
|
if (!(exp instanceof AST_SymbolRef)) {
|
||||||
|
mark_assignment_to_arguments(exp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var d = exp.definition();
|
var d = exp.definition();
|
||||||
var safe = safe_to_assign(tw, d, exp.scope, true);
|
var safe = safe_to_assign(tw, d, exp.scope, true);
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
@@ -1482,14 +1502,26 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function get_rhs(expr) {
|
function get_rhs(expr) {
|
||||||
if (!(candidate instanceof AST_Assign && candidate.operator == "=")) return;
|
return candidate instanceof AST_Assign && candidate.operator == "=" && candidate.right;
|
||||||
return candidate.right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_rvalue(expr) {
|
function get_rvalue(expr) {
|
||||||
return expr[expr instanceof AST_Assign ? "right" : "value"];
|
return expr[expr instanceof AST_Assign ? "right" : "value"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function invariant(expr) {
|
||||||
|
if (expr instanceof AST_Array) return false;
|
||||||
|
if (expr instanceof AST_Binary && lazy_op[expr.operator]) {
|
||||||
|
return invariant(expr.left) && invariant(expr.right);
|
||||||
|
}
|
||||||
|
if (expr instanceof AST_Call) return false;
|
||||||
|
if (expr instanceof AST_Conditional) {
|
||||||
|
return invariant(expr.consequent) && invariant(expr.alternative);
|
||||||
|
}
|
||||||
|
if (expr instanceof AST_Object) return false;
|
||||||
|
return !expr.has_side_effects(compressor);
|
||||||
|
}
|
||||||
|
|
||||||
function foldable(expr) {
|
function foldable(expr) {
|
||||||
if (expr instanceof AST_SymbolRef) {
|
if (expr instanceof AST_SymbolRef) {
|
||||||
var value = expr.evaluate(compressor);
|
var value = expr.evaluate(compressor);
|
||||||
@@ -1502,7 +1534,7 @@ merge(Compressor.prototype, {
|
|||||||
return rhs_fuzzy_match(expr.evaluate(compressor), rhs_exact_match);
|
return rhs_fuzzy_match(expr.evaluate(compressor), rhs_exact_match);
|
||||||
}
|
}
|
||||||
if (!(lhs instanceof AST_SymbolRef)) return false;
|
if (!(lhs instanceof AST_SymbolRef)) return false;
|
||||||
if (expr.has_side_effects(compressor)) return false;
|
if (!invariant(expr)) return false;
|
||||||
var circular;
|
var circular;
|
||||||
var def = lhs.definition();
|
var def = lhs.definition();
|
||||||
expr.walk(new TreeWalker(function(node) {
|
expr.walk(new TreeWalker(function(node) {
|
||||||
@@ -1559,13 +1591,19 @@ merge(Compressor.prototype, {
|
|||||||
var found = false;
|
var found = false;
|
||||||
return statements[stat_index].transform(new TreeTransformer(function(node, descend, in_list) {
|
return statements[stat_index].transform(new TreeTransformer(function(node, descend, in_list) {
|
||||||
if (found) return node;
|
if (found) return node;
|
||||||
if (node === expr || node.body === expr) {
|
if (node !== expr && node.body !== expr) return;
|
||||||
found = true;
|
|
||||||
if (node instanceof AST_VarDef) {
|
if (node instanceof AST_VarDef) {
|
||||||
|
found = true;
|
||||||
node.value = null;
|
node.value = null;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return in_list ? MAP.skip : null;
|
if (in_list) {
|
||||||
|
found = true;
|
||||||
|
return MAP.skip;
|
||||||
|
}
|
||||||
|
if (!this.parent()) {
|
||||||
|
found = true;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}, function(node) {
|
}, function(node) {
|
||||||
if (node instanceof AST_Sequence) switch (node.expressions.length) {
|
if (node instanceof AST_Sequence) switch (node.expressions.length) {
|
||||||
@@ -1605,7 +1643,7 @@ merge(Compressor.prototype, {
|
|||||||
function symbol_in_lvalues(sym, parent) {
|
function symbol_in_lvalues(sym, parent) {
|
||||||
var lvalue = lvalues[sym.name];
|
var lvalue = lvalues[sym.name];
|
||||||
if (!lvalue) return;
|
if (!lvalue) return;
|
||||||
if (lvalue !== lhs) return !(parent instanceof AST_Call);
|
if (lvalue !== lhs) return !(parent instanceof AST_Call && parent.expression === sym);
|
||||||
scan_rhs = false;
|
scan_rhs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1699,6 +1737,19 @@ merge(Compressor.prototype, {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
|
||||||
|
var negated = stat.condition.negate(compressor);
|
||||||
|
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
|
||||||
|
CHANGED = true;
|
||||||
|
stat = stat.clone();
|
||||||
|
stat.condition = negated;
|
||||||
|
statements[j] = stat.body;
|
||||||
|
stat.body = next;
|
||||||
|
statements[i] = stat.transform(compressor);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ab = aborts(stat.alternative);
|
var ab = aborts(stat.alternative);
|
||||||
if (can_merge_flow(ab)) {
|
if (can_merge_flow(ab)) {
|
||||||
if (ab.label) {
|
if (ab.label) {
|
||||||
@@ -2676,19 +2727,25 @@ merge(Compressor.prototype, {
|
|||||||
return typeof function(){};
|
return typeof function(){};
|
||||||
}
|
}
|
||||||
if (!non_converting_unary[this.operator]) depth++;
|
if (!non_converting_unary[this.operator]) depth++;
|
||||||
e = e._eval(compressor, cached, depth);
|
var v = e._eval(compressor, cached, depth);
|
||||||
if (e === this.expression) return this;
|
if (v === this.expression) return this;
|
||||||
switch (this.operator) {
|
switch (this.operator) {
|
||||||
case "!": return !e;
|
case "!": return !v;
|
||||||
case "typeof":
|
case "typeof":
|
||||||
// typeof <RegExp> returns "object" or "function" on different platforms
|
// typeof <RegExp> returns "object" or "function" on different platforms
|
||||||
// so cannot evaluate reliably
|
// so cannot evaluate reliably
|
||||||
if (e instanceof RegExp) return this;
|
if (v instanceof RegExp) return this;
|
||||||
return typeof e;
|
return typeof v;
|
||||||
case "void": return void e;
|
case "void": return void v;
|
||||||
case "~": return ~e;
|
case "~": return ~v;
|
||||||
case "-": return -e;
|
case "-": return -v;
|
||||||
case "+": return +e;
|
case "+": return +v;
|
||||||
|
case "++":
|
||||||
|
case "--":
|
||||||
|
if (e instanceof AST_SymbolRef) {
|
||||||
|
var refs = e.definition().references;
|
||||||
|
if (refs[refs.length - 1] === e) return v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
@@ -2968,19 +3025,21 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
// determine if expression has side effects
|
// determine if expression has side effects
|
||||||
(function(def) {
|
(function(def) {
|
||||||
def(AST_Node, return_true);
|
|
||||||
|
|
||||||
def(AST_EmptyStatement, return_false);
|
|
||||||
def(AST_Constant, return_false);
|
|
||||||
def(AST_This, return_false);
|
|
||||||
|
|
||||||
function any(list, compressor) {
|
function any(list, compressor) {
|
||||||
for (var i = list.length; --i >= 0;)
|
for (var i = list.length; --i >= 0;)
|
||||||
if (list[i].has_side_effects(compressor))
|
if (list[i].has_side_effects(compressor))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
def(AST_Node, return_true);
|
||||||
|
def(AST_Array, function(compressor) {
|
||||||
|
return any(this.elements, compressor);
|
||||||
|
});
|
||||||
|
def(AST_Assign, return_true);
|
||||||
|
def(AST_Binary, function(compressor) {
|
||||||
|
return this.left.has_side_effects(compressor)
|
||||||
|
|| this.right.has_side_effects(compressor);
|
||||||
|
});
|
||||||
def(AST_Block, function(compressor) {
|
def(AST_Block, function(compressor) {
|
||||||
return any(this.body, compressor);
|
return any(this.body, compressor);
|
||||||
});
|
});
|
||||||
@@ -2992,19 +3051,24 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return any(this.args, compressor);
|
return any(this.args, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Switch, function(compressor) {
|
|
||||||
return this.expression.has_side_effects(compressor)
|
|
||||||
|| any(this.body, compressor);
|
|
||||||
});
|
|
||||||
def(AST_Case, function(compressor) {
|
def(AST_Case, function(compressor) {
|
||||||
return this.expression.has_side_effects(compressor)
|
return this.expression.has_side_effects(compressor)
|
||||||
|| any(this.body, compressor);
|
|| any(this.body, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Try, function(compressor) {
|
def(AST_Conditional, function(compressor) {
|
||||||
return any(this.body, compressor)
|
return this.condition.has_side_effects(compressor)
|
||||||
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
|| this.consequent.has_side_effects(compressor)
|
||||||
|| this.bfinally && this.bfinally.has_side_effects(compressor);
|
|| this.alternative.has_side_effects(compressor);
|
||||||
});
|
});
|
||||||
|
def(AST_Constant, return_false);
|
||||||
|
def(AST_Definitions, function(compressor) {
|
||||||
|
return any(this.definitions, compressor);
|
||||||
|
});
|
||||||
|
def(AST_Dot, function(compressor) {
|
||||||
|
return this.expression.may_throw_on_access(compressor)
|
||||||
|
|| this.expression.has_side_effects(compressor);
|
||||||
|
});
|
||||||
|
def(AST_EmptyStatement, return_false);
|
||||||
def(AST_If, function(compressor) {
|
def(AST_If, function(compressor) {
|
||||||
return this.condition.has_side_effects(compressor)
|
return this.condition.has_side_effects(compressor)
|
||||||
|| this.body && this.body.has_side_effects(compressor)
|
|| this.body && this.body.has_side_effects(compressor)
|
||||||
@@ -3013,41 +3077,13 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_LabeledStatement, function(compressor) {
|
def(AST_LabeledStatement, function(compressor) {
|
||||||
return this.body.has_side_effects(compressor);
|
return this.body.has_side_effects(compressor);
|
||||||
});
|
});
|
||||||
def(AST_SimpleStatement, function(compressor) {
|
|
||||||
return this.body.has_side_effects(compressor);
|
|
||||||
});
|
|
||||||
def(AST_Lambda, return_false);
|
def(AST_Lambda, return_false);
|
||||||
def(AST_Binary, function(compressor) {
|
|
||||||
return this.left.has_side_effects(compressor)
|
|
||||||
|| this.right.has_side_effects(compressor);
|
|
||||||
});
|
|
||||||
def(AST_Assign, return_true);
|
|
||||||
def(AST_Conditional, function(compressor) {
|
|
||||||
return this.condition.has_side_effects(compressor)
|
|
||||||
|| this.consequent.has_side_effects(compressor)
|
|
||||||
|| this.alternative.has_side_effects(compressor);
|
|
||||||
});
|
|
||||||
def(AST_Unary, function(compressor) {
|
|
||||||
return unary_side_effects[this.operator]
|
|
||||||
|| this.expression.has_side_effects(compressor);
|
|
||||||
});
|
|
||||||
def(AST_SymbolRef, function(compressor) {
|
|
||||||
return !this.is_declared(compressor);
|
|
||||||
});
|
|
||||||
def(AST_SymbolDeclaration, return_false);
|
|
||||||
def(AST_Object, function(compressor) {
|
def(AST_Object, function(compressor) {
|
||||||
return any(this.properties, compressor);
|
return any(this.properties, compressor);
|
||||||
});
|
});
|
||||||
def(AST_ObjectProperty, function(compressor) {
|
def(AST_ObjectProperty, function(compressor) {
|
||||||
return this.value.has_side_effects(compressor);
|
return this.value.has_side_effects(compressor);
|
||||||
});
|
});
|
||||||
def(AST_Array, function(compressor) {
|
|
||||||
return any(this.elements, compressor);
|
|
||||||
});
|
|
||||||
def(AST_Dot, function(compressor) {
|
|
||||||
return this.expression.may_throw_on_access(compressor)
|
|
||||||
|| this.expression.has_side_effects(compressor);
|
|
||||||
});
|
|
||||||
def(AST_Sub, function(compressor) {
|
def(AST_Sub, function(compressor) {
|
||||||
return this.expression.may_throw_on_access(compressor)
|
return this.expression.may_throw_on_access(compressor)
|
||||||
|| this.expression.has_side_effects(compressor)
|
|| this.expression.has_side_effects(compressor)
|
||||||
@@ -3056,8 +3092,26 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Sequence, function(compressor) {
|
def(AST_Sequence, function(compressor) {
|
||||||
return any(this.expressions, compressor);
|
return any(this.expressions, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Definitions, function(compressor) {
|
def(AST_SimpleStatement, function(compressor) {
|
||||||
return any(this.definitions, compressor);
|
return this.body.has_side_effects(compressor);
|
||||||
|
});
|
||||||
|
def(AST_Switch, function(compressor) {
|
||||||
|
return this.expression.has_side_effects(compressor)
|
||||||
|
|| any(this.body, compressor);
|
||||||
|
});
|
||||||
|
def(AST_SymbolDeclaration, return_false);
|
||||||
|
def(AST_SymbolRef, function(compressor) {
|
||||||
|
return !this.is_declared(compressor);
|
||||||
|
});
|
||||||
|
def(AST_This, return_false);
|
||||||
|
def(AST_Try, function(compressor) {
|
||||||
|
return any(this.body, compressor)
|
||||||
|
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
||||||
|
|| this.bfinally && this.bfinally.has_side_effects(compressor);
|
||||||
|
});
|
||||||
|
def(AST_Unary, function(compressor) {
|
||||||
|
return unary_side_effects[this.operator]
|
||||||
|
|| this.expression.has_side_effects(compressor);
|
||||||
});
|
});
|
||||||
def(AST_VarDef, function(compressor) {
|
def(AST_VarDef, function(compressor) {
|
||||||
return this.value;
|
return this.value;
|
||||||
@@ -3316,13 +3370,14 @@ merge(Compressor.prototype, {
|
|||||||
} else if (node instanceof AST_Unary && node.write_only) {
|
} else if (node instanceof AST_Unary && node.write_only) {
|
||||||
sym = node.expression;
|
sym = node.expression;
|
||||||
}
|
}
|
||||||
if (/strict/.test(compressor.option("pure_getters"))) {
|
if (!/strict/.test(compressor.option("pure_getters"))) return sym instanceof AST_SymbolRef && sym;
|
||||||
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||||
sym = sym.expression;
|
sym = sym.expression;
|
||||||
}
|
}
|
||||||
}
|
return sym instanceof AST_SymbolRef && all(sym.definition().orig, function(sym) {
|
||||||
return sym;
|
return !(sym instanceof AST_SymbolLambda);
|
||||||
|
}) && sym;
|
||||||
};
|
};
|
||||||
var in_use = [];
|
var in_use = [];
|
||||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||||
@@ -3417,7 +3472,7 @@ merge(Compressor.prototype, {
|
|||||||
var parent = tt.parent();
|
var parent = tt.parent();
|
||||||
if (drop_vars) {
|
if (drop_vars) {
|
||||||
var props = [], sym = assign_as_unused(node, props);
|
var props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef) {
|
if (sym) {
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
var in_use = def.id in in_use_ids;
|
var in_use = def.id in in_use_ids;
|
||||||
var value = null;
|
var value = null;
|
||||||
@@ -3616,8 +3671,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function scan_ref_scoped(node, descend) {
|
function scan_ref_scoped(node, descend) {
|
||||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef
|
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||||
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
|
|
||||||
props.forEach(function(prop) {
|
props.forEach(function(prop) {
|
||||||
prop.walk(tw);
|
prop.walk(tw);
|
||||||
});
|
});
|
||||||
@@ -5730,38 +5784,34 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var parent = compressor.parent();
|
var parent = compressor.parent();
|
||||||
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
||||||
var d = self.definition();
|
var def = self.definition();
|
||||||
var fixed = self.fixed_value();
|
var fixed = self.fixed_value();
|
||||||
var single_use = d.single_use
|
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
||||||
&& !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
|
||||||
if (single_use && fixed instanceof AST_Lambda) {
|
if (single_use && fixed instanceof AST_Lambda) {
|
||||||
if (d.scope !== self.scope
|
if (def.scope !== self.scope
|
||||||
&& (!compressor.option("reduce_funcs")
|
&& (!compressor.option("reduce_funcs") || def.escaped == 1 || fixed.inlined)) {
|
||||||
|| d.escaped == 1
|
|
||||||
|| fixed.inlined)) {
|
|
||||||
single_use = false;
|
single_use = false;
|
||||||
} else if (recursive_ref(compressor, d)) {
|
} else if (recursive_ref(compressor, def)) {
|
||||||
single_use = false;
|
single_use = false;
|
||||||
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
|
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
|
||||||
single_use = fixed.is_constant_expression(self.scope);
|
single_use = fixed.is_constant_expression(self.scope);
|
||||||
if (single_use == "f") {
|
if (single_use == "f") {
|
||||||
var scope = self.scope;
|
var scope = self.scope;
|
||||||
do {
|
do if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
||||||
if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
|
||||||
scope.inlined = true;
|
scope.inlined = true;
|
||||||
}
|
|
||||||
} while (scope = scope.parent_scope);
|
} while (scope = scope.parent_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (single_use && fixed) {
|
if (single_use && fixed) {
|
||||||
if (fixed instanceof AST_Defun) {
|
def.single_use = false;
|
||||||
fixed._squeezed = true;
|
fixed._squeezed = true;
|
||||||
|
if (fixed instanceof AST_Defun) {
|
||||||
fixed = make_node(AST_Function, fixed, fixed);
|
fixed = make_node(AST_Function, fixed, fixed);
|
||||||
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
||||||
}
|
}
|
||||||
var value;
|
var value;
|
||||||
if (d.recursive_refs > 0) {
|
if (def.recursive_refs > 0) {
|
||||||
value = fixed.clone(true);
|
value = fixed.clone(true);
|
||||||
var defun_def = value.name.definition();
|
var defun_def = value.name.definition();
|
||||||
var lambda_def = value.variables.get(value.name.name);
|
var lambda_def = value.variables.get(value.name.name);
|
||||||
@@ -5773,9 +5823,21 @@ merge(Compressor.prototype, {
|
|||||||
lambda_def = value.def_function(name);
|
lambda_def = value.def_function(name);
|
||||||
}
|
}
|
||||||
value.walk(new TreeWalker(function(node) {
|
value.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
|
if (!(node instanceof AST_SymbolRef)) return;
|
||||||
|
var def = node.definition();
|
||||||
|
if (def === defun_def) {
|
||||||
node.thedef = lambda_def;
|
node.thedef = lambda_def;
|
||||||
lambda_def.references.push(node);
|
lambda_def.references.push(node);
|
||||||
|
} else {
|
||||||
|
def.single_use = false;
|
||||||
|
var fn = node.fixed_value();
|
||||||
|
if (!(fn instanceof AST_Lambda)) return;
|
||||||
|
if (!fn.name) return;
|
||||||
|
if (fixed.variables.get(fn.name.name) !== fn.name.definition()) return;
|
||||||
|
fn.name = fn.name.clone();
|
||||||
|
var value_def = value.variables.get(fn.name.name) || value.def_function(fn.name);
|
||||||
|
node.thedef = value_def;
|
||||||
|
value_def.references.push(node);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
@@ -5784,12 +5846,11 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (fixed && d.should_replace === undefined) {
|
if (fixed && def.should_replace === undefined) {
|
||||||
var init;
|
var init;
|
||||||
if (fixed instanceof AST_This) {
|
if (fixed instanceof AST_This) {
|
||||||
if (!(d.orig[0] instanceof AST_SymbolFunarg)
|
if (!(def.orig[0] instanceof AST_SymbolFunarg) && all(def.references, function(ref) {
|
||||||
&& all(d.references, function(ref) {
|
return def.scope === ref.scope;
|
||||||
return d.scope === ref.scope;
|
|
||||||
})) {
|
})) {
|
||||||
init = fixed;
|
init = fixed;
|
||||||
}
|
}
|
||||||
@@ -5814,18 +5875,18 @@ merge(Compressor.prototype, {
|
|||||||
return result === init || result === fixed ? result.clone(true) : result;
|
return result === init || result === fixed ? result.clone(true) : result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var name_length = d.name.length;
|
var name_length = def.name.length;
|
||||||
var overhead = 0;
|
var overhead = 0;
|
||||||
if (compressor.option("unused") && !compressor.exposed(d)) {
|
if (compressor.option("unused") && !compressor.exposed(def)) {
|
||||||
overhead = (name_length + 2 + value_length) / (d.references.length - d.assignments);
|
overhead = (name_length + 2 + value_length) / (def.references.length - def.assignments);
|
||||||
}
|
}
|
||||||
d.should_replace = value_length <= name_length + overhead ? fn : false;
|
def.should_replace = value_length <= name_length + overhead ? fn : false;
|
||||||
} else {
|
} else {
|
||||||
d.should_replace = false;
|
def.should_replace = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d.should_replace) {
|
if (def.should_replace) {
|
||||||
return d.should_replace();
|
return def.should_replace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -6027,23 +6088,29 @@ merge(Compressor.prototype, {
|
|||||||
// |
|
// |
|
||||||
// v
|
// v
|
||||||
// exp = foo ? something : something_else;
|
// exp = foo ? something : something_else;
|
||||||
if (consequent instanceof AST_Assign
|
var seq_tail = consequent.tail_node();
|
||||||
&& alternative instanceof AST_Assign
|
if (seq_tail instanceof AST_Assign) {
|
||||||
&& consequent.operator == alternative.operator
|
var is_eq = seq_tail.operator == "=";
|
||||||
&& consequent.left.equivalent_to(alternative.left)
|
var alt_tail = is_eq ? alternative.tail_node() : alternative;
|
||||||
&& (!self.condition.has_side_effects(compressor)
|
if ((is_eq || consequent === seq_tail)
|
||||||
|| consequent.operator == "="
|
&& alt_tail instanceof AST_Assign
|
||||||
&& !consequent.left.has_side_effects(compressor))) {
|
&& seq_tail.operator == alt_tail.operator
|
||||||
|
&& seq_tail.left.equivalent_to(alt_tail.left)
|
||||||
|
&& (is_eq && !seq_tail.left.has_side_effects(compressor)
|
||||||
|
|| !condition.has_side_effects(compressor)
|
||||||
|
&& can_shift_lhs_of_tail(consequent)
|
||||||
|
&& can_shift_lhs_of_tail(alternative))) {
|
||||||
return make_node(AST_Assign, self, {
|
return make_node(AST_Assign, self, {
|
||||||
operator: consequent.operator,
|
operator: seq_tail.operator,
|
||||||
left: consequent.left,
|
left: seq_tail.left,
|
||||||
right: make_node(AST_Conditional, self, {
|
right: make_node(AST_Conditional, self, {
|
||||||
condition: self.condition,
|
condition: condition,
|
||||||
consequent: consequent.right,
|
consequent: pop_lhs(consequent),
|
||||||
alternative: alternative.right
|
alternative: pop_lhs(alternative)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// x ? y(a) : y(b) --> y(x ? a : b)
|
// x ? y(a) : y(b) --> y(x ? a : b)
|
||||||
var arg_index;
|
var arg_index;
|
||||||
if (consequent instanceof AST_Call
|
if (consequent instanceof AST_Call
|
||||||
@@ -6051,12 +6118,12 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.args.length > 0
|
&& consequent.args.length > 0
|
||||||
&& consequent.args.length == alternative.args.length
|
&& consequent.args.length == alternative.args.length
|
||||||
&& consequent.expression.equivalent_to(alternative.expression)
|
&& consequent.expression.equivalent_to(alternative.expression)
|
||||||
&& !self.condition.has_side_effects(compressor)
|
&& !condition.has_side_effects(compressor)
|
||||||
&& !consequent.expression.has_side_effects(compressor)
|
&& !consequent.expression.has_side_effects(compressor)
|
||||||
&& typeof (arg_index = single_arg_diff()) == "number") {
|
&& typeof (arg_index = single_arg_diff()) == "number") {
|
||||||
var node = consequent.clone();
|
var node = consequent.clone();
|
||||||
node.args[arg_index] = make_node(AST_Conditional, self, {
|
node.args[arg_index] = make_node(AST_Conditional, self, {
|
||||||
condition: self.condition,
|
condition: condition,
|
||||||
consequent: consequent.args[arg_index],
|
consequent: consequent.args[arg_index],
|
||||||
alternative: alternative.args[arg_index]
|
alternative: alternative.args[arg_index]
|
||||||
});
|
});
|
||||||
@@ -6067,7 +6134,7 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.alternative.equivalent_to(alternative)) {
|
&& consequent.alternative.equivalent_to(alternative)) {
|
||||||
return make_node(AST_Conditional, self, {
|
return make_node(AST_Conditional, self, {
|
||||||
condition: make_node(AST_Binary, self, {
|
condition: make_node(AST_Binary, self, {
|
||||||
left: self.condition,
|
left: condition,
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
right: consequent.condition
|
right: consequent.condition
|
||||||
}),
|
}),
|
||||||
@@ -6078,7 +6145,7 @@ merge(Compressor.prototype, {
|
|||||||
// x ? y : y --> x, y
|
// x ? y : y --> x, y
|
||||||
if (consequent.equivalent_to(alternative)) {
|
if (consequent.equivalent_to(alternative)) {
|
||||||
return make_sequence(self, [
|
return make_sequence(self, [
|
||||||
self.condition,
|
condition,
|
||||||
consequent
|
consequent
|
||||||
]).optimize(compressor);
|
]).optimize(compressor);
|
||||||
}
|
}
|
||||||
@@ -6087,7 +6154,7 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
||||||
return make_sequence(self, [
|
return make_sequence(self, [
|
||||||
make_node(AST_Conditional, self, {
|
make_node(AST_Conditional, self, {
|
||||||
condition: self.condition,
|
condition: condition,
|
||||||
consequent: pop_seq(consequent),
|
consequent: pop_seq(consequent),
|
||||||
alternative: pop_seq(alternative)
|
alternative: pop_seq(alternative)
|
||||||
}),
|
}),
|
||||||
@@ -6102,7 +6169,7 @@ merge(Compressor.prototype, {
|
|||||||
operator: "||",
|
operator: "||",
|
||||||
left: make_node(AST_Binary, self, {
|
left: make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: self.condition,
|
left: condition,
|
||||||
right: consequent.left
|
right: consequent.left
|
||||||
}),
|
}),
|
||||||
right: alternative
|
right: alternative
|
||||||
@@ -6112,24 +6179,24 @@ merge(Compressor.prototype, {
|
|||||||
if (is_true(self.consequent)) {
|
if (is_true(self.consequent)) {
|
||||||
if (is_false(self.alternative)) {
|
if (is_false(self.alternative)) {
|
||||||
// c ? true : false ---> !!c
|
// c ? true : false ---> !!c
|
||||||
return booleanize(self.condition);
|
return booleanize(condition);
|
||||||
}
|
}
|
||||||
// c ? true : x ---> !!c || x
|
// c ? true : x ---> !!c || x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "||",
|
operator: "||",
|
||||||
left: booleanize(self.condition),
|
left: booleanize(condition),
|
||||||
right: self.alternative
|
right: self.alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (is_false(self.consequent)) {
|
if (is_false(self.consequent)) {
|
||||||
if (is_true(self.alternative)) {
|
if (is_true(self.alternative)) {
|
||||||
// c ? false : true ---> !c
|
// c ? false : true ---> !c
|
||||||
return booleanize(self.condition.negate(compressor));
|
return booleanize(condition.negate(compressor));
|
||||||
}
|
}
|
||||||
// c ? false : x ---> !c && x
|
// c ? false : x ---> !c && x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: booleanize(self.condition.negate(compressor)),
|
left: booleanize(condition.negate(compressor)),
|
||||||
right: self.alternative
|
right: self.alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6137,7 +6204,7 @@ merge(Compressor.prototype, {
|
|||||||
// c ? x : true ---> !c || x
|
// c ? x : true ---> !c || x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "||",
|
operator: "||",
|
||||||
left: booleanize(self.condition.negate(compressor)),
|
left: booleanize(condition.negate(compressor)),
|
||||||
right: self.consequent
|
right: self.consequent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6145,7 +6212,7 @@ merge(Compressor.prototype, {
|
|||||||
// c ? x : false ---> !!c && x
|
// c ? x : false ---> !!c && x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: booleanize(self.condition),
|
left: booleanize(condition),
|
||||||
right: self.consequent
|
right: self.consequent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6197,6 +6264,26 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function can_shift_lhs_of_tail(node) {
|
||||||
|
if (node === node.tail_node()) return true;
|
||||||
|
var exprs = node.expressions;
|
||||||
|
for (var i = exprs.length - 1; --i >= 0;) {
|
||||||
|
var expr = exprs[i];
|
||||||
|
if (!(expr instanceof AST_Assign) && expr.has_side_effects(compressor)
|
||||||
|
|| expr.operator != "="
|
||||||
|
|| expr.left.has_side_effects(compressor)
|
||||||
|
|| expr.right.has_side_effects(compressor)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pop_lhs(node) {
|
||||||
|
if (!(node instanceof AST_Sequence)) return node.right;
|
||||||
|
var exprs = node.expressions.slice();
|
||||||
|
exprs.push(exprs.pop().right);
|
||||||
|
return make_sequence(node, exprs);
|
||||||
|
}
|
||||||
|
|
||||||
function pop_seq(node) {
|
function pop_seq(node) {
|
||||||
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
|
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
|
||||||
value: 0
|
value: 0
|
||||||
@@ -6273,13 +6360,16 @@ merge(Compressor.prototype, {
|
|||||||
&& expr instanceof AST_SymbolRef
|
&& expr instanceof AST_SymbolRef
|
||||||
&& expr.name == "arguments"
|
&& expr.name == "arguments"
|
||||||
&& expr.definition().orig.length == 1
|
&& expr.definition().orig.length == 1
|
||||||
&& (fn = expr.scope) instanceof AST_Lambda
|
&& prop instanceof AST_Number
|
||||||
&& prop instanceof AST_Number) {
|
&& (fn = expr.scope) === compressor.find_parent(AST_Lambda)) {
|
||||||
var index = prop.getValue();
|
var index = prop.getValue();
|
||||||
var argname = fn.argnames[index];
|
var argname = fn.argnames[index];
|
||||||
if (argname && compressor.has_directive("use strict")) {
|
if (argname && compressor.has_directive("use strict")) {
|
||||||
var def = argname.definition();
|
var def = argname.definition();
|
||||||
if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
|
if (!compressor.option("reduce_vars")
|
||||||
|
|| expr.definition().reassigned
|
||||||
|
|| def.assignments
|
||||||
|
|| def.orig.length > 1) {
|
||||||
argname = null;
|
argname = null;
|
||||||
}
|
}
|
||||||
} else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
|
} else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
|
||||||
@@ -6392,7 +6482,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
OPT(AST_Dot, function(self, compressor) {
|
OPT(AST_Dot, function(self, compressor) {
|
||||||
if (self.property == "arguments" || self.property == "caller") {
|
if (self.property == "arguments" || self.property == "caller") {
|
||||||
compressor.warn("Function.protoype.{prop} not supported [{file}:{line},{col}]", {
|
compressor.warn("Function.prototype.{prop} not supported [{file}:{line},{col}]", {
|
||||||
prop: self.property,
|
prop: self.property,
|
||||||
file: self.start.file,
|
file: self.start.file,
|
||||||
line: self.start.line,
|
line: self.start.line,
|
||||||
|
|||||||
29
lib/parse.js
29
lib/parse.js
@@ -758,17 +758,21 @@ function parse($TEXT, options) {
|
|||||||
croak(msg, token.line, token.col);
|
croak(msg, token.line, token.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function token_to_string(type, value) {
|
||||||
|
return type + (value === undefined ? "" : " «" + value + "»");
|
||||||
|
}
|
||||||
|
|
||||||
function unexpected(token) {
|
function unexpected(token) {
|
||||||
if (token == null)
|
if (token == null)
|
||||||
token = S.token;
|
token = S.token;
|
||||||
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
|
token_error(token, "Unexpected token: " + token_to_string(token.type, token.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function expect_token(type, val) {
|
function expect_token(type, val) {
|
||||||
if (is(type, val)) {
|
if (is(type, val)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
|
token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
function expect(punc) {
|
function expect(punc) {
|
||||||
@@ -788,7 +792,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function semicolon(optional) {
|
function semicolon(optional) {
|
||||||
if (is("punc", ";")) next();
|
if (is("punc", ";")) next();
|
||||||
else if (!optional && !can_insert_semicolon()) unexpected();
|
else if (!optional && !can_insert_semicolon()) expect_token("punc", ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parenthesised() {
|
function parenthesised() {
|
||||||
@@ -1069,7 +1073,7 @@ function parse($TEXT, options) {
|
|||||||
var in_statement = ctor === AST_Defun;
|
var in_statement = ctor === AST_Defun;
|
||||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||||
if (in_statement && !name)
|
if (in_statement && !name)
|
||||||
unexpected();
|
expect_token("name");
|
||||||
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
unexpected(prev());
|
unexpected(prev());
|
||||||
expect("(");
|
expect("(");
|
||||||
@@ -1119,7 +1123,7 @@ function parse($TEXT, options) {
|
|||||||
expect("{");
|
expect("{");
|
||||||
var a = [];
|
var a = [];
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) unexpected();
|
if (is("eof")) expect_token("punc", "}");
|
||||||
a.push(statement(strict_defun));
|
a.push(statement(strict_defun));
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
@@ -1130,7 +1134,7 @@ function parse($TEXT, options) {
|
|||||||
expect("{");
|
expect("{");
|
||||||
var a = [], cur = null, branch = null, tmp;
|
var a = [], cur = null, branch = null, tmp;
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) unexpected();
|
if (is("eof")) expect_token("punc", "}");
|
||||||
if (is("keyword", "case")) {
|
if (is("keyword", "case")) {
|
||||||
if (branch) branch.end = prev();
|
if (branch) branch.end = prev();
|
||||||
cur = [];
|
cur = [];
|
||||||
@@ -1141,8 +1145,7 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
a.push(branch);
|
a.push(branch);
|
||||||
expect(":");
|
expect(":");
|
||||||
}
|
} else if (is("keyword", "default")) {
|
||||||
else if (is("keyword", "default")) {
|
|
||||||
if (branch) branch.end = prev();
|
if (branch) branch.end = prev();
|
||||||
cur = [];
|
cur = [];
|
||||||
branch = new AST_Default({
|
branch = new AST_Default({
|
||||||
@@ -1150,8 +1153,7 @@ function parse($TEXT, options) {
|
|||||||
body : cur
|
body : cur
|
||||||
});
|
});
|
||||||
a.push(branch);
|
a.push(branch);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!cur) unexpected();
|
if (!cur) unexpected();
|
||||||
cur.push(statement());
|
cur.push(statement());
|
||||||
}
|
}
|
||||||
@@ -1420,10 +1422,10 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function as_name() {
|
function as_name() {
|
||||||
var tmp = S.token;
|
if (!is("name")) expect_token("name");
|
||||||
if (tmp.type != "name") unexpected();
|
var name = S.token.value;
|
||||||
next();
|
next();
|
||||||
return tmp.value;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _make_symbol(type) {
|
function _make_symbol(type) {
|
||||||
@@ -1625,6 +1627,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.expression) {
|
if (options.expression) {
|
||||||
|
handle_regexp();
|
||||||
return expression(true);
|
return expression(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,8 +309,12 @@ function names_in_use(scope, options) {
|
|||||||
if (!names) {
|
if (!names) {
|
||||||
scope.names_in_use = names = Object.create(scope.mangled_names || null);
|
scope.names_in_use = names = Object.create(scope.mangled_names || null);
|
||||||
scope.cname_holes = [];
|
scope.cname_holes = [];
|
||||||
|
var cache = options.cache && options.cache.props;
|
||||||
scope.enclosed.forEach(function(def) {
|
scope.enclosed.forEach(function(def) {
|
||||||
if (def.unmangleable(options)) names[def.name] = true;
|
if (def.unmangleable(options)) names[def.name] = true;
|
||||||
|
if (def.global && cache && cache.has(def.name)) {
|
||||||
|
names[cache.get(def.name)] = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.4.7",
|
"version": "3.4.10",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.16.0",
|
"commander": "~2.19.0",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.7.1",
|
"acorn": "~6.1.1",
|
||||||
"semver": "~5.5.0"
|
"semver": "~5.6.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
|
|||||||
@@ -237,3 +237,342 @@ duplicate_argname: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "bar 42 foo 42 bar"
|
expect_stdout: "bar 42 foo 42 bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3273: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(a, a);
|
||||||
|
a++;
|
||||||
|
console.log(a, a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(a, a);
|
||||||
|
a++;
|
||||||
|
console.log(a, a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_local_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_local_strict_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_global_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_global_strict_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
}
|
||||||
|
f(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_1_passes: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
function e(argument_0) {
|
||||||
|
return argument_0;
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_2: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(f) {
|
||||||
|
f();
|
||||||
|
})(function() {
|
||||||
|
return (function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
return function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
"use strict";
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_2_passes: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(f) {
|
||||||
|
f();
|
||||||
|
})(function() {
|
||||||
|
return (function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
return function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
"use strict";
|
||||||
|
function e(argument_0) {
|
||||||
|
return argument_0;
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -947,7 +947,7 @@ collapse_vars_misc1: {
|
|||||||
function f8() { var b = window.a * window.z; return b + (b + 5) }
|
function f8() { var b = window.a * window.z; return b + (b + 5) }
|
||||||
function f9() { var b = window.a * window.z; return bar() || b }
|
function f9() { var b = window.a * window.z; return bar() || b }
|
||||||
function f10(x) { var a = 5; return a += 3; }
|
function f10(x) { var a = 5; return a += 3; }
|
||||||
function f11(x) { var a = 5, b = 3; return a += --b; }
|
function f11(x) { var a = 5; return a += 2; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5827,3 +5827,297 @@ issue_3215_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "number"
|
expect_stdout: "number"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3238_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = Object.create(null);
|
||||||
|
c = Object.create(null);
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = Object.create(null);
|
||||||
|
c = Object.create(null);
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3238_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = Error();
|
||||||
|
c = Error();
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = Error();
|
||||||
|
c = Error();
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3238_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = new Date();
|
||||||
|
c = new Date();
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = new Date();
|
||||||
|
c = new Date();
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3238_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a && {};
|
||||||
|
c = a && {};
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a && {};
|
||||||
|
c = a && {};
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3238_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a ? [] : 42;
|
||||||
|
c = a ? [] : 42;
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a ? [] : 42;
|
||||||
|
c = a ? [] : 42;
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3238_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a && 0 || [];
|
||||||
|
c = a && 0 || [];
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
if (a) {
|
||||||
|
b = a && 0 || [];
|
||||||
|
c = a && 0 || [];
|
||||||
|
}
|
||||||
|
return b === c;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "true false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3247: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(o) {
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
a = Object({ p: "PASS" });
|
||||||
|
a.q = true;
|
||||||
|
f(a, true);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(o) {
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
(a = Object({ p: "PASS" })).q = true;
|
||||||
|
f(a, true);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3305: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function calc(a) {
|
||||||
|
var x, w;
|
||||||
|
if (a) {
|
||||||
|
x = a;
|
||||||
|
w = 1;
|
||||||
|
} else {
|
||||||
|
x = 1;
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
return add(x, w);
|
||||||
|
}
|
||||||
|
function add(x, w) {
|
||||||
|
return x + w;
|
||||||
|
}
|
||||||
|
console.log(calc(41));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function calc(a) {
|
||||||
|
var x, w;
|
||||||
|
return w = a ? (x = a, 1) : (x = 1, 0), add(x, w);
|
||||||
|
}
|
||||||
|
function add(x, w) {
|
||||||
|
return x + w;
|
||||||
|
}
|
||||||
|
console.log(calc(41));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3314: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function test(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
var a = "FAIL", b;
|
||||||
|
b = a = "PASS";
|
||||||
|
test(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function test(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
var a = "FAIL", b;
|
||||||
|
b = a = "PASS";
|
||||||
|
test(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3327: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b, l = ["PASS", 42];
|
||||||
|
if (l.length === 1) {
|
||||||
|
a = l[0].a;
|
||||||
|
b = l[0].b;
|
||||||
|
} else {
|
||||||
|
a = l[0];
|
||||||
|
b = l[1];
|
||||||
|
}
|
||||||
|
function echo(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
echo(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b, l = ["PASS", 42];
|
||||||
|
function echo(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
b = 1 === l.length ? (a = l[0].a, l[0].b) : (a = l[0], l[1]),
|
||||||
|
echo(a,b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1292,3 +1292,126 @@ to_and_or: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_seq_assign_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var t;
|
||||||
|
if (a) {
|
||||||
|
t = "foo";
|
||||||
|
t = "bar";
|
||||||
|
} else {
|
||||||
|
console.log(t);
|
||||||
|
t = 42;
|
||||||
|
}
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
f(f);
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var t;
|
||||||
|
t = a ? (t = "foo", "bar") : (console.log(t), 42),
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
f(f),
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"undefined",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_seq_assign_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var t;
|
||||||
|
if (a) {
|
||||||
|
t = "foo";
|
||||||
|
a = "bar";
|
||||||
|
} else {
|
||||||
|
console.log(t);
|
||||||
|
t = 42;
|
||||||
|
}
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
f(f);
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var t;
|
||||||
|
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
f(f),
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"undefined",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_seq_assign_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
if (this)
|
||||||
|
c = 1 + c, c = c + 1;
|
||||||
|
else
|
||||||
|
c = 1 + c, c = c + 1;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
this, c = 1 + c, c += 1;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3271: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var i = 0, b = [];
|
||||||
|
if (a) {
|
||||||
|
b[i++] = 4,
|
||||||
|
b[i++] = 1;
|
||||||
|
} else {
|
||||||
|
b[i++] = 3,
|
||||||
|
b[i++] = 2,
|
||||||
|
b[i++] = 1;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f(0).pop(), f(1).pop());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var i = 0, b = [];
|
||||||
|
a ? b[i++] = 4 : (b[i++] = 3, b[i++] = 2),
|
||||||
|
b[i++] = 1;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f(0).pop(), f(1).pop());
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1982,3 +1982,26 @@ issue_3192: {
|
|||||||
"foo bar",
|
"foo bar",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3233: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function b() {
|
||||||
|
b.c = "PASS";
|
||||||
|
};
|
||||||
|
a();
|
||||||
|
console.log(a.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function b() {
|
||||||
|
b.c = "PASS";
|
||||||
|
};
|
||||||
|
a();
|
||||||
|
console.log(a.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1245,12 +1245,12 @@ self_comparison_1: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { n: NaN };
|
var o = { n: NaN };
|
||||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(false, false, true, true, "number");
|
console.log("number", false, false, true, true);
|
||||||
}
|
}
|
||||||
expect_stdout: "false false true true 'number'"
|
expect_stdout: "number false false true true"
|
||||||
}
|
}
|
||||||
|
|
||||||
self_comparison_2: {
|
self_comparison_2: {
|
||||||
@@ -1265,12 +1265,12 @@ self_comparison_2: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { n: NaN };
|
var o = { n: NaN };
|
||||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(false, false, true, true, "number");
|
console.log("number", false, false, true, true);
|
||||||
}
|
}
|
||||||
expect_stdout: "false false true true 'number'"
|
expect_stdout: "number false false true true"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2535_1: {
|
issue_2535_1: {
|
||||||
|
|||||||
@@ -2315,3 +2315,218 @@ issue_3125: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3274: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var g = function(a) {
|
||||||
|
var c = a.p, b = c;
|
||||||
|
return b != c;
|
||||||
|
};
|
||||||
|
while (g(1))
|
||||||
|
console.log("FAIL");
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
for (var c; void 0, (c = 1..p) != c;)
|
||||||
|
console.log("FAIL");
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3297_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
function function1() {
|
||||||
|
var r = {
|
||||||
|
function2: function2
|
||||||
|
};
|
||||||
|
function function2() {
|
||||||
|
alert(1234);
|
||||||
|
function function3() {
|
||||||
|
function2();
|
||||||
|
};
|
||||||
|
function3();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function function1() {
|
||||||
|
return {
|
||||||
|
function2: function n() {
|
||||||
|
alert(1234);
|
||||||
|
function t() {
|
||||||
|
n();
|
||||||
|
}
|
||||||
|
t();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3297_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
function function1(session) {
|
||||||
|
var public = {
|
||||||
|
processBulk: processBulk
|
||||||
|
};
|
||||||
|
return public;
|
||||||
|
function processBulk(bulk) {
|
||||||
|
var subparam1 = session();
|
||||||
|
function processOne(param1) {
|
||||||
|
var param2 = {
|
||||||
|
subparam1: subparam1
|
||||||
|
};
|
||||||
|
doProcessOne({
|
||||||
|
param1: param1,
|
||||||
|
param2: param2,
|
||||||
|
}, function () {
|
||||||
|
processBulk(bulk);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if (bulk && bulk.length > 0)
|
||||||
|
processOne(bulk.shift());
|
||||||
|
}
|
||||||
|
function doProcessOne(config, callback) {
|
||||||
|
console.log(JSON.stringify(config));
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function1(function session() {
|
||||||
|
return 42;
|
||||||
|
}).processBulk([1, 2, 3]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function function1(o) {
|
||||||
|
return {
|
||||||
|
processBulk: function t(u) {
|
||||||
|
var r = o();
|
||||||
|
function n(n) {
|
||||||
|
var o = {
|
||||||
|
subparam1: r
|
||||||
|
};
|
||||||
|
c({
|
||||||
|
param1: n,
|
||||||
|
param2: o
|
||||||
|
}, function() {
|
||||||
|
t(u);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
u && u.length > 0 && n(u.shift());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function c(n, o) {
|
||||||
|
console.log(JSON.stringify(n));
|
||||||
|
o();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function1(function() {
|
||||||
|
return 42;
|
||||||
|
}).processBulk([ 1, 2, 3 ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
'{"param1":1,"param2":{"subparam1":42}}',
|
||||||
|
'{"param1":2,"param2":{"subparam1":42}}',
|
||||||
|
'{"param1":3,"param2":{"subparam1":42}}',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3297_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
function function1(session) {
|
||||||
|
var public = {
|
||||||
|
processBulk: processBulk
|
||||||
|
};
|
||||||
|
return public;
|
||||||
|
function processBulk(bulk) {
|
||||||
|
var subparam1 = session();
|
||||||
|
function processOne(param1) {
|
||||||
|
var param2 = {
|
||||||
|
subparam1: subparam1
|
||||||
|
};
|
||||||
|
doProcessOne({
|
||||||
|
param1: param1,
|
||||||
|
param2: param2,
|
||||||
|
}, function () {
|
||||||
|
processBulk(bulk);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if (bulk && bulk.length > 0)
|
||||||
|
processOne(bulk.shift());
|
||||||
|
}
|
||||||
|
function doProcessOne(config, callback) {
|
||||||
|
console.log(JSON.stringify(config));
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function1(function session() {
|
||||||
|
return 42;
|
||||||
|
}).processBulk([1, 2, 3]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function function1(c) {
|
||||||
|
return {
|
||||||
|
processBulk: function n(o) {
|
||||||
|
var r, t, u = c();
|
||||||
|
o && 0 < o.length && (r = {
|
||||||
|
param1: o.shift(),
|
||||||
|
param2: {
|
||||||
|
subparam1: u
|
||||||
|
}
|
||||||
|
}, t = function() {
|
||||||
|
n(o);
|
||||||
|
}, console.log(JSON.stringify(r)), t());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function1(function() {
|
||||||
|
return 42;
|
||||||
|
}).processBulk([ 1, 2, 3 ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
'{"param1":1,"param2":{"subparam1":42}}',
|
||||||
|
'{"param1":2,"param2":{"subparam1":42}}',
|
||||||
|
'{"param1":3,"param2":{"subparam1":42}}',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -396,3 +396,151 @@ if_if_return_return: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_body_return_1: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_2: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_3: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 == a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 != a) return true;
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ warn: {
|
|||||||
}().length);
|
}().length);
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:5,19]",
|
"WARN: Function.prototype.caller not supported [test/compress/issue-2719.js:5,19]",
|
||||||
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
"WARN: Function.prototype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -642,3 +642,41 @@ issue_3065_4: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3325_1: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: "cb",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function cb() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function cb() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3325_2: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: "xxxcbxxx",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function cb() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function cb() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2740,18 +2740,18 @@ issue_1814_2: {
|
|||||||
!function() {
|
!function() {
|
||||||
var b = a + 1;
|
var b = a + 1;
|
||||||
!function(a) {
|
!function(a) {
|
||||||
console.log(a++, b);
|
console.log(b, a++);
|
||||||
}(0);
|
}(0);
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
!function(a) {
|
!function(a) {
|
||||||
console.log(a++, "321");
|
console.log("321", a++);
|
||||||
}(0);
|
}(0);
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "0 '321'"
|
expect_stdout: "321 0"
|
||||||
}
|
}
|
||||||
|
|
||||||
try_abort: {
|
try_abort: {
|
||||||
@@ -5354,6 +5354,7 @@ issue_2774: {
|
|||||||
|
|
||||||
issue_2799_1: {
|
issue_2799_1: {
|
||||||
options = {
|
options = {
|
||||||
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -6429,3 +6430,289 @@ issue_3140_5: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3240_1: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
f(1);
|
||||||
|
function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
var g = function() {
|
||||||
|
f(a - 1);
|
||||||
|
};
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
var g = function() {
|
||||||
|
f(a - 1);
|
||||||
|
};
|
||||||
|
if (a) g();
|
||||||
|
})(1);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3240_2: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
f(1);
|
||||||
|
function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
var g = function() {
|
||||||
|
f(a - 1);
|
||||||
|
};
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
if (a) (function() {
|
||||||
|
f(a - 1);
|
||||||
|
})();
|
||||||
|
})(1);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3240_3: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
f();
|
||||||
|
function f(b) {
|
||||||
|
if (!f.a) f.a = 0;
|
||||||
|
console.log(f.a.toString());
|
||||||
|
var g = function() {
|
||||||
|
(b ? function() {} : function() {
|
||||||
|
f.a++;
|
||||||
|
f(1);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f(b) {
|
||||||
|
if (!f.a) f.a = 0;
|
||||||
|
console.log(f.a.toString());
|
||||||
|
var g = function() {
|
||||||
|
(b ? function() {} : function() {
|
||||||
|
f.a++;
|
||||||
|
f(1);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3240_4: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
f();
|
||||||
|
function f(b) {
|
||||||
|
if (!f.a) f.a = 0;
|
||||||
|
console.log(f.a.toString());
|
||||||
|
var g = function() {
|
||||||
|
(b ? function() {} : function() {
|
||||||
|
f.a++;
|
||||||
|
f(1);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f(b) {
|
||||||
|
if (!f.a) f.a = 0;
|
||||||
|
console.log(f.a.toString());
|
||||||
|
(function() {
|
||||||
|
(b ? function() {} : function() {
|
||||||
|
f.a++;
|
||||||
|
f(1);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issues_3267_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(x) {
|
||||||
|
x();
|
||||||
|
})(function() {
|
||||||
|
(function(i) {
|
||||||
|
if (i)
|
||||||
|
return console.log("PASS");
|
||||||
|
throw "FAIL";
|
||||||
|
})(Object());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(i) {
|
||||||
|
if (i)
|
||||||
|
return console.log("PASS");
|
||||||
|
throw "FAIL";
|
||||||
|
}(Object());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issues_3267_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(x) {
|
||||||
|
x();
|
||||||
|
})(function() {
|
||||||
|
(function(i) {
|
||||||
|
if (i)
|
||||||
|
return console.log("PASS");
|
||||||
|
throw "FAIL";
|
||||||
|
})(Object());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
if (Object())
|
||||||
|
return console.log("PASS");
|
||||||
|
throw "FAIL";
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issues_3267_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(x) {
|
||||||
|
x();
|
||||||
|
})(function() {
|
||||||
|
(function(i) {
|
||||||
|
if (i)
|
||||||
|
return console.log("PASS");
|
||||||
|
throw "FAIL";
|
||||||
|
})(Object());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3297: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
var b = function a() {
|
||||||
|
console.log(a === b) && f();
|
||||||
|
};
|
||||||
|
b();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f() {
|
||||||
|
var b = function a() {
|
||||||
|
console.log(a === b) && f();
|
||||||
|
};
|
||||||
|
b();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
8
test/input/issue-3315/config.json
Normal file
8
test/input/issue-3315/config.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compress": false,
|
||||||
|
"mangle": {
|
||||||
|
"properties": {
|
||||||
|
"regex": "/^_/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
test/input/issue-3315/input.js
Normal file
8
test/input/issue-3315/input.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
"aaaaaaaaaa";
|
||||||
|
var o = {
|
||||||
|
prop: 1,
|
||||||
|
_int: 2,
|
||||||
|
};
|
||||||
|
return o.prop + o._int;
|
||||||
|
}
|
||||||
@@ -257,7 +257,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
||||||
assert.strictEqual(lines[1], "function f(a{}");
|
assert.strictEqual(lines[1], "function f(a{}");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: punc «{», expected: punc «,»");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -281,7 +281,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
||||||
assert.strictEqual(lines[1], "foo, bar(");
|
assert.strictEqual(lines[1], "foo, bar(");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -293,7 +293,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
||||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -362,7 +362,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_1.js:1,2",
|
"Parse error at test/input/invalid/dot_1.js:1,2",
|
||||||
"a.=",
|
"a.=",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (=)"
|
"ERROR: Unexpected token: operator «=», expected: name"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -376,7 +376,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_2.js:1,0",
|
"Parse error at test/input/invalid/dot_2.js:1,0",
|
||||||
"%.a;",
|
"%.a;",
|
||||||
"^",
|
"^",
|
||||||
"ERROR: Unexpected token: operator (%)"
|
"ERROR: Unexpected token: operator «%»"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -390,7 +390,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_3.js:1,2",
|
"Parse error at test/input/invalid/dot_3.js:1,2",
|
||||||
"a./();",
|
"a./();",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (/)"
|
"ERROR: Unexpected token: operator «/», expected: name"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -404,7 +404,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/object.js:1,13",
|
"Parse error at test/input/invalid/object.js:1,13",
|
||||||
"console.log({%: 1});",
|
"console.log({%: 1});",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (%)"
|
"ERROR: Unexpected token: operator «%»"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -502,7 +502,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/else.js:1,7",
|
"Parse error at test/input/invalid/else.js:1,7",
|
||||||
"if (0) else 1;",
|
"if (0) else 1;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: keyword (else)"
|
"ERROR: Unexpected token: keyword «else»"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -633,6 +633,14 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should work with mangle.properties.regex from --config-file", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json";
|
||||||
|
exec(command, function(err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,a:2};return a.prop+a.a}\n');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should fail with --define a-b", function(done) {
|
it("Should fail with --define a-b", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
|
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
@@ -651,7 +659,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with explicit --no-rename", function(done) {
|
it("Should work with explicit --no-rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc --no-rename";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
||||||
@@ -659,7 +667,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --rename", function(done) {
|
it("Should work with implicit --rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return n}\n");
|
assert.strictEqual(stdout, "function f(n){return n}\n");
|
||||||
@@ -667,7 +675,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --no-rename", function(done) {
|
it("Should work with implicit --no-rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -c";
|
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe("comments", function() {
|
|||||||
|
|
||||||
var fail = function(e) {
|
var fail = function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unexpected token: operator (>)"
|
&& e.message === "Unexpected token: operator «>»"
|
||||||
&& e.line === 2
|
&& e.line === 2
|
||||||
&& e.col === 0;
|
&& e.col === 0;
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ describe("comments", function() {
|
|||||||
|
|
||||||
var fail = function(e) {
|
var fail = function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unexpected token: operator (>)"
|
&& e.message === "Unexpected token: operator «>»"
|
||||||
&& e.line === 5
|
&& e.line === 5
|
||||||
&& e.col === 0;
|
&& e.col === 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ describe("Directives", function() {
|
|||||||
UglifyJS.parse(tokenizer);
|
UglifyJS.parse(tokenizer);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unexpected token: punc (])"
|
&& /^Unexpected token: punc «]»/.test(e.message)
|
||||||
}, test[0]);
|
}, test[0]);
|
||||||
test[1].forEach(function(directive) {
|
test[1].forEach(function(directive) {
|
||||||
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]);
|
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ describe("Getters and setters", function() {
|
|||||||
var fail = function(data) {
|
var fail = function(data) {
|
||||||
return function(e) {
|
return function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unexpected token: operator (" + data.operator + ")";
|
&& e.message === "Unexpected token: operator «" + data.operator + "»";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
var errorMessage = function(data) {
|
var errorMessage = function(data) {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should avoid mangled names in cache", function() {
|
it("Should avoid cached names when mangling top-level variables", function() {
|
||||||
var cache = {};
|
var cache = {};
|
||||||
var original = "";
|
var original = "";
|
||||||
var compressed = "";
|
var compressed = "";
|
||||||
@@ -116,10 +116,34 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should avoid cached names when mangling inner-scoped variables", function() {
|
||||||
|
var cache = {};
|
||||||
|
var original = "";
|
||||||
|
var compressed = "";
|
||||||
|
[
|
||||||
|
'var extend = function(a, b) { console.log("extend"); a(); b(); }; function A() { console.log("A"); };',
|
||||||
|
'var B = function(A) { function B() { console.log("B") }; extend(B, A); return B; }(A);',
|
||||||
|
].forEach(function(code) {
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
nameCache: cache,
|
||||||
|
toplevel: true,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
original += code;
|
||||||
|
compressed += result.code;
|
||||||
|
});
|
||||||
|
assert.strictEqual(compressed, [
|
||||||
|
'var o=function(o,n){console.log("extend");o();n()};function n(){console.log("A")}',
|
||||||
|
'var e=function(n){function e(){console.log("B")}o(e,n);return e}(n);',
|
||||||
|
].join(""));
|
||||||
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
|
});
|
||||||
|
|
||||||
it("Should not parse invalid use of reserved words", function() {
|
it("Should not parse invalid use of reserved words", function() {
|
||||||
assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined);
|
assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined);
|
||||||
assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined);
|
assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined);
|
||||||
assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name «this»");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("keep_quoted_props", function() {
|
describe("keep_quoted_props", function() {
|
||||||
@@ -214,7 +238,7 @@ describe("minify", function() {
|
|||||||
var result = UglifyJS.minify("function f(a{}");
|
var result = UglifyJS.minify("function f(a{}");
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: punc «{», expected: punc «,»");
|
||||||
assert.strictEqual(err.filename, "0");
|
assert.strictEqual(err.filename, "0");
|
||||||
assert.strictEqual(err.line, 1);
|
assert.strictEqual(err.line, 1);
|
||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
@@ -241,7 +265,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword «debugger»");
|
||||||
});
|
});
|
||||||
it("Should skip inherited properties", function() {
|
it("Should skip inherited properties", function() {
|
||||||
var foo = Object.create({ skip: this });
|
var foo = Object.create({ skip: this });
|
||||||
|
|||||||
Reference in New Issue
Block a user