Compare commits
9 Commits
harmony-v3
...
v3.1.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
667fc4d08b | ||
|
|
6142117cdd | ||
|
|
ae28a24c7f | ||
|
|
ebe761cad0 | ||
|
|
fa7a7c5c5a | ||
|
|
557636f3b7 | ||
|
|
49fbe9c5ac | ||
|
|
2ac5086831 | ||
|
|
c6cfa04d10 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -15,6 +15,8 @@
|
|||||||
UglifyJS alone - without third party tools or libraries.
|
UglifyJS alone - without third party tools or libraries.
|
||||||
Ideally the input should be as small as possible.
|
Ideally the input should be as small as possible.
|
||||||
Post a link to a gist if necessary.
|
Post a link to a gist if necessary.
|
||||||
|
|
||||||
|
Issues without a reproducible test case will be closed.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -689,10 +689,11 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||||
|
|
||||||
- `reduce_funcs` (default: `true`) -- Allows single-use functions
|
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
|
||||||
to be inlined as function expressions when permissible.
|
inlined as function expressions when permissible allowing further
|
||||||
Enabled by default. Option depends on `reduce_vars` being enabled.
|
optimization. Enabled by default. Option depends on `reduce_vars`
|
||||||
For speed critical code this option should be disabled.
|
being enabled. Some code runs faster in the Chrome V8 engine if this
|
||||||
|
option is disabled. Does not negatively impact other major browsers.
|
||||||
|
|
||||||
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
||||||
used as constant values.
|
used as constant values.
|
||||||
@@ -864,6 +865,9 @@ can pass additional arguments that control the code output:
|
|||||||
|
|
||||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
||||||
|
|
||||||
|
- `webkit` (default `false`) -- enable workarounds for WebKit bugs.
|
||||||
|
PhantomJS users should set this option to `true`.
|
||||||
|
|
||||||
- `width` (default `80`) -- only takes effect when beautification is on, this
|
- `width` (default `80`) -- only takes effect when beautification is on, this
|
||||||
specifies an (orientative) line width that the beautifier will try to
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
obey. It refers to the width of the line text (excluding indentation).
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
|
|||||||
@@ -352,11 +352,11 @@ var AST_Accessor = DEFNODE("Accessor", null, {
|
|||||||
$documentation: "A setter/getter function. The `name` property is always null."
|
$documentation: "A setter/getter function. The `name` property is always null."
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", null, {
|
var AST_Function = DEFNODE("Function", "inlined", {
|
||||||
$documentation: "A function expression"
|
$documentation: "A function expression"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", null, {
|
var AST_Defun = DEFNODE("Defun", "inlined", {
|
||||||
$documentation: "A function definition"
|
$documentation: "A function definition"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
|||||||
198
lib/compress.js
198
lib/compress.js
@@ -373,6 +373,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Defun) {
|
if (node instanceof AST_Defun) {
|
||||||
|
node.inlined = false;
|
||||||
var d = node.name.definition();
|
var d = node.name.definition();
|
||||||
if (compressor.exposed(d) || safe_to_read(d)) {
|
if (compressor.exposed(d) || safe_to_read(d)) {
|
||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
@@ -389,6 +390,7 @@ merge(Compressor.prototype, {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Function) {
|
if (node instanceof AST_Function) {
|
||||||
|
node.inlined = false;
|
||||||
push();
|
push();
|
||||||
var iife;
|
var iife;
|
||||||
if (!node.name
|
if (!node.name
|
||||||
@@ -796,8 +798,8 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function drop_decl(def) {
|
function drop_decl(def) {
|
||||||
def._eliminiated = (def._eliminiated || 0) + 1;
|
def.eliminated++;
|
||||||
if (def.orig.length == def._eliminiated) {
|
if (def.orig.length == def.eliminated) {
|
||||||
def.scope.functions.del(def.name);
|
def.scope.functions.del(def.name);
|
||||||
def.scope.variables.del(def.name);
|
def.scope.variables.del(def.name);
|
||||||
}
|
}
|
||||||
@@ -839,26 +841,7 @@ merge(Compressor.prototype, {
|
|||||||
var args;
|
var args;
|
||||||
var candidates = [];
|
var candidates = [];
|
||||||
var stat_index = statements.length;
|
var stat_index = statements.length;
|
||||||
while (--stat_index >= 0) {
|
var scanner = new TreeTransformer(function(node, descend) {
|
||||||
// Treat parameters as collapsible in IIFE, i.e.
|
|
||||||
// function(a, b){ ... }(x());
|
|
||||||
// would be translated into equivalent assignments:
|
|
||||||
// var a = x(), b = undefined;
|
|
||||||
if (stat_index == 0 && compressor.option("unused")) extract_args();
|
|
||||||
// Find collapsible assignments
|
|
||||||
extract_candidates(statements[stat_index]);
|
|
||||||
while (candidates.length > 0) {
|
|
||||||
var candidate = candidates.pop();
|
|
||||||
var lhs = get_lhs(candidate);
|
|
||||||
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
|
|
||||||
// Locate symbols which may execute code outside of scanning range
|
|
||||||
var lvalues = get_lvalues(candidate);
|
|
||||||
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
|
||||||
var one_off = lhs instanceof AST_Symbol && lhs.definition().references.length == 1;
|
|
||||||
var side_effects = value_has_side_effects(candidate);
|
|
||||||
var hit = candidate.name instanceof AST_SymbolFunarg;
|
|
||||||
var abort = false, replaced = false, can_replace = !args || !hit;
|
|
||||||
var tt = new TreeTransformer(function(node, descend) {
|
|
||||||
if (abort) return node;
|
if (abort) return node;
|
||||||
// Skip nodes before `candidate` as quickly as possible
|
// Skip nodes before `candidate` as quickly as possible
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
@@ -869,7 +852,7 @@ merge(Compressor.prototype, {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Stop immediately if these node types are encountered
|
// Stop immediately if these node types are encountered
|
||||||
var parent = tt.parent();
|
var parent = scanner.parent();
|
||||||
if (node instanceof AST_Assign && node.operator != "=" && lhs.equivalent_to(node.left)
|
if (node instanceof AST_Assign && node.operator != "=" && lhs.equivalent_to(node.left)
|
||||||
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
||||||
|| node instanceof AST_Debugger
|
|| node instanceof AST_Debugger
|
||||||
@@ -884,9 +867,13 @@ merge(Compressor.prototype, {
|
|||||||
// Replace variable with assignment when found
|
// Replace variable with assignment when found
|
||||||
if (can_replace
|
if (can_replace
|
||||||
&& !(node instanceof AST_SymbolDeclaration)
|
&& !(node instanceof AST_SymbolDeclaration)
|
||||||
&& !is_lhs(node, parent)
|
|
||||||
&& lhs.equivalent_to(node)) {
|
&& lhs.equivalent_to(node)) {
|
||||||
CHANGED = replaced = abort = true;
|
if (is_lhs(node, parent)) {
|
||||||
|
if (candidate.multiple) replaced++;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
CHANGED = abort = true;
|
||||||
|
replaced++;
|
||||||
compressor.info("Collapsing {name} [{file}:{line},{col}]", {
|
compressor.info("Collapsing {name} [{file}:{line},{col}]", {
|
||||||
name: node.print_to_string(),
|
name: node.print_to_string(),
|
||||||
file: node.start.file,
|
file: node.start.file,
|
||||||
@@ -897,8 +884,13 @@ merge(Compressor.prototype, {
|
|||||||
return make_node(AST_UnaryPrefix, candidate, candidate);
|
return make_node(AST_UnaryPrefix, candidate, candidate);
|
||||||
}
|
}
|
||||||
if (candidate instanceof AST_VarDef) {
|
if (candidate instanceof AST_VarDef) {
|
||||||
|
if (candidate.multiple) {
|
||||||
|
abort = false;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
var def = candidate.name.definition();
|
var def = candidate.name.definition();
|
||||||
if (def.references.length == 1 && !compressor.exposed(def)) {
|
if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
|
||||||
|
def.replaced++;
|
||||||
return maintain_this_binding(parent, node, candidate.value);
|
return maintain_this_binding(parent, node, candidate.value);
|
||||||
}
|
}
|
||||||
return make_node(AST_Assign, candidate, {
|
return make_node(AST_Assign, candidate, {
|
||||||
@@ -922,26 +914,83 @@ merge(Compressor.prototype, {
|
|||||||
|| side_effects && !references_in_scope(node.definition()))
|
|| side_effects && !references_in_scope(node.definition()))
|
||||||
|| (sym = lhs_or_def(node))
|
|| (sym = lhs_or_def(node))
|
||||||
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
||||||
|| (side_effects || !one_off)
|
|| (side_effects || !replace_all)
|
||||||
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
||||||
|| parent instanceof AST_Case
|
|| parent instanceof AST_Case
|
||||||
|| parent instanceof AST_Conditional
|
|| parent instanceof AST_Conditional
|
||||||
|| parent instanceof AST_If)) {
|
|| parent instanceof AST_If)) {
|
||||||
if (!(node instanceof AST_Scope)) descend(node, tt);
|
if (!(node instanceof AST_Scope)) descend(node, scanner);
|
||||||
abort = true;
|
abort = true;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
// Skip (non-executed) functions and (leading) default case in switch statements
|
// Skip (non-executed) functions and (leading) default case in switch statements
|
||||||
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
||||||
});
|
});
|
||||||
|
var multi_replacer = new TreeTransformer(function(node) {
|
||||||
|
if (abort) return node;
|
||||||
|
// Skip nodes before `candidate` as quickly as possible
|
||||||
|
if (!hit) {
|
||||||
|
if (node === candidate) {
|
||||||
|
hit = true;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Replace variable when found
|
||||||
|
if (node instanceof AST_SymbolRef
|
||||||
|
&& node.name == def.name) {
|
||||||
|
if (!--replaced) abort = true;
|
||||||
|
if (is_lhs(node, multi_replacer.parent())) return node;
|
||||||
|
def.replaced++;
|
||||||
|
value_def.replaced--;
|
||||||
|
return candidate.value;
|
||||||
|
}
|
||||||
|
// Skip (non-executed) functions and (leading) default case in switch statements
|
||||||
|
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
||||||
|
});
|
||||||
|
while (--stat_index >= 0) {
|
||||||
|
// Treat parameters as collapsible in IIFE, i.e.
|
||||||
|
// function(a, b){ ... }(x());
|
||||||
|
// would be translated into equivalent assignments:
|
||||||
|
// var a = x(), b = undefined;
|
||||||
|
if (stat_index == 0 && compressor.option("unused")) extract_args();
|
||||||
|
// Find collapsible assignments
|
||||||
|
extract_candidates(statements[stat_index]);
|
||||||
|
while (candidates.length > 0) {
|
||||||
|
var candidate = candidates.pop();
|
||||||
|
var lhs = get_lhs(candidate);
|
||||||
|
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
|
||||||
|
// Locate symbols which may execute code outside of scanning range
|
||||||
|
var lvalues = get_lvalues(candidate);
|
||||||
|
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
||||||
|
var replace_all = candidate.multiple;
|
||||||
|
if (!replace_all && lhs instanceof AST_SymbolRef) {
|
||||||
|
var def = lhs.definition();
|
||||||
|
replace_all = def.references.length - def.replaced == 1;
|
||||||
|
}
|
||||||
|
var side_effects = value_has_side_effects(candidate);
|
||||||
|
var hit = candidate.name instanceof AST_SymbolFunarg;
|
||||||
|
var abort = false, replaced = 0, can_replace = !args || !hit;
|
||||||
if (!can_replace) {
|
if (!can_replace) {
|
||||||
for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; j < args.length; j++) {
|
for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
|
||||||
args[j].transform(tt);
|
args[j].transform(scanner);
|
||||||
}
|
}
|
||||||
can_replace = true;
|
can_replace = true;
|
||||||
}
|
}
|
||||||
for (var i = stat_index; !abort && i < statements.length; i++) {
|
for (var i = stat_index; !abort && i < statements.length; i++) {
|
||||||
statements[i].transform(tt);
|
statements[i].transform(scanner);
|
||||||
|
}
|
||||||
|
if (candidate.multiple) {
|
||||||
|
var def = candidate.name.definition();
|
||||||
|
if (abort && def.references.length - def.replaced > replaced) replaced = false;
|
||||||
|
else {
|
||||||
|
abort = false;
|
||||||
|
hit = candidate.name instanceof AST_SymbolFunarg;
|
||||||
|
var value_def = candidate.value.definition();
|
||||||
|
for (var i = stat_index; !abort && i < statements.length; i++) {
|
||||||
|
statements[i].transform(multi_replacer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
||||||
}
|
}
|
||||||
@@ -956,7 +1005,7 @@ merge(Compressor.prototype, {
|
|||||||
&& (iife = compressor.parent()) instanceof AST_Call
|
&& (iife = compressor.parent()) instanceof AST_Call
|
||||||
&& iife.expression === fn) {
|
&& iife.expression === fn) {
|
||||||
var fn_strict = compressor.has_directive("use strict");
|
var fn_strict = compressor.has_directive("use strict");
|
||||||
if (fn_strict && fn.body.indexOf(fn_strict) < 0) fn_strict = false;
|
if (fn_strict && !member(fn_strict, fn.body)) fn_strict = false;
|
||||||
var len = fn.argnames.length;
|
var len = fn.argnames.length;
|
||||||
args = iife.args.slice(len);
|
args = iife.args.slice(len);
|
||||||
var names = Object.create(null);
|
var names = Object.create(null);
|
||||||
@@ -1012,12 +1061,22 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mangleable_var(expr) {
|
||||||
|
var value = expr.value;
|
||||||
|
if (!(value instanceof AST_SymbolRef)) return false;
|
||||||
|
if (value.name == "arguments") return false;
|
||||||
|
if (value.definition().undeclared) return false;
|
||||||
|
expr.multiple = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function get_lhs(expr) {
|
function get_lhs(expr) {
|
||||||
if (expr instanceof AST_VarDef) {
|
if (expr instanceof AST_VarDef) {
|
||||||
var def = expr.name.definition();
|
var def = expr.name.definition();
|
||||||
if (def.orig.length - (def._eliminiated || 0) > 1
|
var declared = def.orig.length - def.eliminated;
|
||||||
&& !(expr.name instanceof AST_SymbolFunarg)
|
var referenced = def.references.length - def.replaced;
|
||||||
|| def.references.length == 1 && !compressor.exposed(def)) {
|
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
||||||
|
|| (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
|
||||||
return make_node(AST_SymbolRef, expr.name, expr.name);
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2502,12 +2561,14 @@ merge(Compressor.prototype, {
|
|||||||
var def = tail.pop();
|
var def = tail.pop();
|
||||||
compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", template(def.name));
|
compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", template(def.name));
|
||||||
remove(var_defs, def);
|
remove(var_defs, def);
|
||||||
drop_decl(def.name.definition());
|
|
||||||
side_effects.unshift(make_node(AST_Assign, def, {
|
side_effects.unshift(make_node(AST_Assign, def, {
|
||||||
operator: "=",
|
operator: "=",
|
||||||
left: make_node(AST_SymbolRef, def.name, def.name),
|
left: make_node(AST_SymbolRef, def.name, def.name),
|
||||||
right: def.value
|
right: def.value
|
||||||
}));
|
}));
|
||||||
|
def = def.name.definition();
|
||||||
|
drop_decl(def);
|
||||||
|
def.replaced--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (head.length > 0 || tail.length > 0) {
|
if (head.length > 0 || tail.length > 0) {
|
||||||
@@ -2719,17 +2780,29 @@ merge(Compressor.prototype, {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
|
||||||
|
var var_names = this.var_names;
|
||||||
|
if (!var_names) {
|
||||||
|
this.var_names = var_names = Object.create(null);
|
||||||
|
this.enclosed.forEach(function(def) {
|
||||||
|
var_names[def.name] = true;
|
||||||
|
});
|
||||||
|
this.variables.each(function(def, name) {
|
||||||
|
var_names[name] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prefix = prefix.replace(/[^a-z_$]+/ig, "_");
|
||||||
|
var name = prefix;
|
||||||
|
for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
|
||||||
|
var_names[name] = true;
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("hoist_properties", function(compressor){
|
AST_Scope.DEFMETHOD("hoist_properties", function(compressor){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
|
if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
|
||||||
|
var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
|
||||||
var defs_by_id = Object.create(null);
|
var defs_by_id = Object.create(null);
|
||||||
var var_names = Object.create(null);
|
|
||||||
self.enclosed.forEach(function(def) {
|
|
||||||
var_names[def.name] = true;
|
|
||||||
});
|
|
||||||
self.variables.each(function(def, name) {
|
|
||||||
var_names[name] = true;
|
|
||||||
});
|
|
||||||
return self.transform(new TreeTransformer(function(node) {
|
return self.transform(new TreeTransformer(function(node) {
|
||||||
if (node instanceof AST_VarDef) {
|
if (node instanceof AST_VarDef) {
|
||||||
var sym = node.name, def, value;
|
var sym = node.name, def, value;
|
||||||
@@ -2737,6 +2810,7 @@ merge(Compressor.prototype, {
|
|||||||
&& !(def = sym.definition()).escaped
|
&& !(def = sym.definition()).escaped
|
||||||
&& !def.single_use
|
&& !def.single_use
|
||||||
&& !def.direct_access
|
&& !def.direct_access
|
||||||
|
&& !top_retain(def)
|
||||||
&& (value = sym.fixed_value()) === node.value
|
&& (value = sym.fixed_value()) === node.value
|
||||||
&& value instanceof AST_Object) {
|
&& value instanceof AST_Object) {
|
||||||
var defs = new Dictionary();
|
var defs = new Dictionary();
|
||||||
@@ -2768,17 +2842,13 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function make_sym(key) {
|
function make_sym(key) {
|
||||||
var prefix = sym.name + "_" + key.toString().replace(/[^a-z_$]+/ig, "_");
|
|
||||||
var name = prefix;
|
|
||||||
for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
|
|
||||||
var new_var = make_node(sym.CTOR, sym, {
|
var new_var = make_node(sym.CTOR, sym, {
|
||||||
name: name,
|
name: self.make_var_name(sym.name + "_" + key),
|
||||||
scope: self
|
scope: self
|
||||||
});
|
});
|
||||||
var def = self.def_variable(new_var);
|
var def = self.def_variable(new_var);
|
||||||
defs.set(key, def);
|
defs.set(key, def);
|
||||||
self.enclosed.push(def);
|
self.enclosed.push(def);
|
||||||
var_names[name] = true;
|
|
||||||
return new_var;
|
return new_var;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -3347,8 +3417,7 @@ merge(Compressor.prototype, {
|
|||||||
self.args.length = last;
|
self.args.length = last;
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
if (is_undeclared_ref(exp)) {
|
if (is_undeclared_ref(exp)) switch (exp.name) {
|
||||||
switch (exp.name) {
|
|
||||||
case "Array":
|
case "Array":
|
||||||
if (self.args.length != 1) {
|
if (self.args.length != 1) {
|
||||||
return make_node(AST_Array, self, {
|
return make_node(AST_Array, self, {
|
||||||
@@ -3391,16 +3460,16 @@ merge(Compressor.prototype, {
|
|||||||
operator: "!"
|
operator: "!"
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
break;
|
break;
|
||||||
}
|
} else if (exp instanceof AST_Dot) switch(exp.property) {
|
||||||
}
|
case "toString":
|
||||||
else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) {
|
if (self.args.length == 0) return make_node(AST_Binary, self, {
|
||||||
return make_node(AST_Binary, self, {
|
|
||||||
left: make_node(AST_String, self, { value: "" }),
|
left: make_node(AST_String, self, { value: "" }),
|
||||||
operator: "+",
|
operator: "+",
|
||||||
right: exp.expression
|
right: exp.expression
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
break;
|
||||||
else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: {
|
case "join":
|
||||||
|
if (exp.expression instanceof AST_Array) EXIT: {
|
||||||
var separator;
|
var separator;
|
||||||
if (self.args.length > 0) {
|
if (self.args.length > 0) {
|
||||||
separator = self.args[0].evaluate(compressor);
|
separator = self.args[0].evaluate(compressor);
|
||||||
@@ -3462,7 +3531,9 @@ merge(Compressor.prototype, {
|
|||||||
node.expression.expression.elements = elements;
|
node.expression.expression.elements = elements;
|
||||||
return best_of(compressor, self, node);
|
return best_of(compressor, self, node);
|
||||||
}
|
}
|
||||||
else if (exp instanceof AST_Dot && exp.expression.is_string(compressor) && exp.property == "charAt") {
|
break;
|
||||||
|
case "charAt":
|
||||||
|
if (exp.expression.is_string(compressor)) {
|
||||||
var arg = self.args[0];
|
var arg = self.args[0];
|
||||||
var index = arg ? arg.evaluate(compressor) : 0;
|
var index = arg ? arg.evaluate(compressor) : 0;
|
||||||
if (index !== arg) {
|
if (index !== arg) {
|
||||||
@@ -3472,6 +3543,8 @@ merge(Compressor.prototype, {
|
|||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe_Func")
|
if (compressor.option("unsafe_Func")
|
||||||
&& is_undeclared_ref(exp)
|
&& is_undeclared_ref(exp)
|
||||||
@@ -4258,16 +4331,21 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
||||||
}
|
}
|
||||||
if (d.single_use && fixed instanceof AST_Function) {
|
if (d.single_use && fixed instanceof AST_Function) {
|
||||||
if (!compressor.option("reduce_funcs") && d.scope !== self.scope) {
|
if (d.scope !== self.scope
|
||||||
|
&& (!compressor.option("reduce_funcs")
|
||||||
|
|| d.escaped
|
||||||
|
|| fixed.inlined)) {
|
||||||
d.single_use = false;
|
d.single_use = false;
|
||||||
} else if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {
|
} else if (recursive_ref(compressor, d)) {
|
||||||
d.single_use = false;
|
d.single_use = false;
|
||||||
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
|
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
|
||||||
d.single_use = fixed.is_constant_expression(self.scope);
|
d.single_use = fixed.is_constant_expression(self.scope);
|
||||||
if (d.single_use == "f") {
|
if (d.single_use == "f") {
|
||||||
var scope = self.scope;
|
var scope = self.scope;
|
||||||
do {
|
do {
|
||||||
if (scope.name) scope.name.definition().single_use = false;
|
if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
||||||
|
scope.inlined = true;
|
||||||
|
}
|
||||||
} while (scope = scope.parent_scope);
|
} while (scope = scope.parent_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,8 +46,10 @@
|
|||||||
function SymbolDef(scope, index, orig) {
|
function SymbolDef(scope, index, orig) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
|
this.replaced = 0;
|
||||||
this.global = false;
|
this.global = false;
|
||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"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.1.9",
|
"version": "3.1.10",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3098,3 +3098,483 @@ issue_2437: {
|
|||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2436_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log({
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o.a = 3;
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o.a = 3;
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o = {
|
||||||
|
a: 3,
|
||||||
|
b: 4,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o = {
|
||||||
|
a: 3,
|
||||||
|
b: 4,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
var o;
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(o) {
|
||||||
|
return {
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(o) {
|
||||||
|
return {
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
};
|
||||||
|
}({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
x: 1,
|
||||||
|
y: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_7: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
x: 1,
|
||||||
|
y: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_8: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_9: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = console;
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = console;
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_10: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
function f(n) {
|
||||||
|
o = { b: 3 };
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
console.log(function(c) {
|
||||||
|
return [
|
||||||
|
c.a,
|
||||||
|
f(c.b),
|
||||||
|
c.b,
|
||||||
|
];
|
||||||
|
}(o).join(" "));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
function f(n) {
|
||||||
|
o = { b: 3 };
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
console.log(function(c) {
|
||||||
|
return [
|
||||||
|
c.a,
|
||||||
|
f(c.b),
|
||||||
|
c.b,
|
||||||
|
];
|
||||||
|
}(o).join(" "));
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_11: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function matrix() {}
|
||||||
|
function isCollection() {}
|
||||||
|
function _randomDataForMatrix() {}
|
||||||
|
function _randomInt() {}
|
||||||
|
function f(arg1, arg2) {
|
||||||
|
if (isCollection(arg1)) {
|
||||||
|
var size = arg1;
|
||||||
|
var max = arg2;
|
||||||
|
var min = 0;
|
||||||
|
var res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
|
||||||
|
return size && true === size.isMatrix ? matrix(res) : res;
|
||||||
|
} else {
|
||||||
|
var min = arg1;
|
||||||
|
var max = arg2;
|
||||||
|
return _randomInt(min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function matrix() {}
|
||||||
|
function isCollection() {}
|
||||||
|
function _randomDataForMatrix() {}
|
||||||
|
function _randomInt() {}
|
||||||
|
function f(arg1, arg2) {
|
||||||
|
if (isCollection(arg1)) {
|
||||||
|
var size = arg1, max = arg2, min = 0, res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
|
||||||
|
return size && true === size.isMatrix ? matrix(res) : res;
|
||||||
|
} else {
|
||||||
|
return _randomInt(min = arg1, max = arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_12: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function isUndefined() {}
|
||||||
|
function f() {
|
||||||
|
var viewValue = this.$$lastCommittedViewValue;
|
||||||
|
var modelValue = viewValue;
|
||||||
|
return isUndefined(modelValue) ? modelValue : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function isUndefined() {}
|
||||||
|
function f() {
|
||||||
|
var modelValue = this.$$lastCommittedViewValue;
|
||||||
|
return isUndefined(modelValue) ? modelValue : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_13: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
function f(b) {
|
||||||
|
(function g(b) {
|
||||||
|
var b = b && (b.null = "FAIL");
|
||||||
|
})(a);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
(function(b) {
|
||||||
|
(function(b) {
|
||||||
|
a && (a.null = "FAIL");
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_14: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
var b = {};
|
||||||
|
(function() {
|
||||||
|
var c = a;
|
||||||
|
c && function(c, d) {
|
||||||
|
console.log(c, d);
|
||||||
|
}(b, c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
var b = {};
|
||||||
|
(function() {
|
||||||
|
a && function(c, d) {
|
||||||
|
console.log(c, d);
|
||||||
|
}(b, a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -411,3 +411,92 @@ new_this: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1 2"
|
expect_stdout: "1 2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2473_1: {
|
||||||
|
options = {
|
||||||
|
hoist_props: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: [ "x", "y" ],
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
var z = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_2: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: [ "x", "y" ],
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
var z = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_3: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: "o",
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_4: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: "o",
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var o_a = 1, o_b = 2;
|
||||||
|
console.log(o_a, o_b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -4477,3 +4477,51 @@ perf_8: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "348150"
|
expect_stdout: "348150"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2485: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = function(bar) {
|
||||||
|
var n = function(a, b) {
|
||||||
|
return a + b;
|
||||||
|
};
|
||||||
|
var sumAll = function(arg) {
|
||||||
|
return arg.reduce(n, 0);
|
||||||
|
};
|
||||||
|
var runSumAll = function(arg) {
|
||||||
|
return sumAll(arg);
|
||||||
|
};
|
||||||
|
bar.baz = function(arg) {
|
||||||
|
var n = runSumAll(arg);
|
||||||
|
return (n.get = 1), n;
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
};
|
||||||
|
var bar = foo({});
|
||||||
|
console.log(bar.baz([1, 2, 3]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = function(bar) {
|
||||||
|
var n = function(a, b) {
|
||||||
|
return a + b;
|
||||||
|
};
|
||||||
|
var runSumAll = function(arg) {
|
||||||
|
return function(arg) {
|
||||||
|
return arg.reduce(n, 0);
|
||||||
|
}(arg);
|
||||||
|
};
|
||||||
|
bar.baz = function(arg) {
|
||||||
|
var n = runSumAll(arg);
|
||||||
|
return (n.get = 1), n;
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
};
|
||||||
|
var bar = foo({});
|
||||||
|
console.log(bar.baz([1, 2, 3]));
|
||||||
|
}
|
||||||
|
expect_stdout: "6"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user