Compare commits
30 Commits
harmony-v2
...
v2.8.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9920f7ca1 | ||
|
|
7e465d4a01 | ||
|
|
aa80ee349d | ||
|
|
80e81765cf | ||
|
|
711f88dcb4 | ||
|
|
344d11d591 | ||
|
|
c7cdcf06a6 | ||
|
|
3ee55748d4 | ||
|
|
dedbeeff15 | ||
|
|
bd6dee52ab | ||
|
|
144052ca49 | ||
|
|
65c848cc6f | ||
|
|
8a8a94a596 | ||
|
|
8153b7bd8a | ||
|
|
d787d70127 | ||
|
|
3ac2421932 | ||
|
|
a9fc9ddc33 | ||
|
|
a5d62a3fc6 | ||
|
|
067e5a5762 | ||
|
|
33b5f31984 | ||
|
|
35a849dc48 | ||
|
|
b70591be1a | ||
|
|
b33e7f88e6 | ||
|
|
1f0333e9f1 | ||
|
|
eb98a7f2f3 | ||
|
|
78d1bb92d4 | ||
|
|
ea9ab9fb0e | ||
|
|
ce54c9ccee | ||
|
|
07accd2fbb | ||
|
|
18059cc94f |
7
.github/ISSUE_TEMPLATE.md
vendored
Normal file
7
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
- Bug report or feature request?
|
||||||
|
- `uglify-js` version (`uglifyjs -V`)
|
||||||
|
- JavaScript input - ideally as small as possible.
|
||||||
|
- The `uglifyjs` CLI command executed or `minify()` options used.
|
||||||
|
- An example of JavaScript output produced and/or the error or warning.
|
||||||
|
|
||||||
|
Note: the release version of `uglify-js` only supports ES5. Those wishing to minify ES6 should use the experimental [`harmony`](https://github.com/mishoo/UglifyJS2#harmony) branch.
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
before_install: "npm install -g npm"
|
before_install: "npm install -g npm"
|
||||||
node_js:
|
node_js:
|
||||||
- "0.12"
|
|
||||||
- "0.10"
|
- "0.10"
|
||||||
|
- "0.12"
|
||||||
- "4"
|
- "4"
|
||||||
- "6"
|
- "6"
|
||||||
|
- "7"
|
||||||
|
env:
|
||||||
|
- UGLIFYJS_TEST_ALL=1
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -75,8 +75,6 @@ The available options are:
|
|||||||
--support-ie8 Use this flag to support Internet Explorer 6/7/8.
|
--support-ie8 Use this flag to support Internet Explorer 6/7/8.
|
||||||
Equivalent to setting `screw_ie8: false` in `minify()`
|
Equivalent to setting `screw_ie8: false` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
Note: `--support-ie8` may generate incorrect code
|
|
||||||
for `try`/`catch` in ES5 compliant browsers.
|
|
||||||
--expr Parse a single expression, rather than a
|
--expr Parse a single expression, rather than a
|
||||||
program (for parsing JSON)
|
program (for parsing JSON)
|
||||||
-p, --prefix Skip prefix for original filenames that appear
|
-p, --prefix Skip prefix for original filenames that appear
|
||||||
@@ -350,6 +348,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
comparison are switching. Compression only works if both `comparisons` and
|
comparison are switching. Compression only works if both `comparisons` and
|
||||||
`unsafe_comps` are both set to true.
|
`unsafe_comps` are both set to true.
|
||||||
|
|
||||||
|
- `unsafe_math` (default: false) -- optimize numerical expressions like
|
||||||
|
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||||
|
|
||||||
- `unsafe_proto` (default: false) -- optimize expressions like
|
- `unsafe_proto` (default: false) -- optimize expressions like
|
||||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||||
|
|
||||||
@@ -390,11 +391,11 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
||||||
and `x = something(), x` into `x = something()`
|
and `x = something(), x` into `x = something()`
|
||||||
|
|
||||||
- `collapse_vars` -- default `false`. Collapse single-use `var` and `const`
|
- `collapse_vars` -- Collapse single-use `var` and `const` definitions
|
||||||
definitions when possible.
|
when possible.
|
||||||
|
|
||||||
- `reduce_vars` -- default `false`. Improve optimization on variables assigned
|
- `reduce_vars` -- Improve optimization on variables assigned with and
|
||||||
with and used as constant values.
|
used as constant values.
|
||||||
|
|
||||||
- `warnings` -- display warnings when dropping unreachable code or unused
|
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||||
declarations etc.
|
declarations etc.
|
||||||
@@ -423,6 +424,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
such as `console.info` and/or retain side effects from function arguments
|
such as `console.info` and/or retain side effects from function arguments
|
||||||
after dropping the function call then use `pure_funcs` instead.
|
after dropping the function call then use `pure_funcs` instead.
|
||||||
|
|
||||||
|
- `expression` -- default `false`. Pass `true` to preserve completion values
|
||||||
|
from terminal statements without `return`, e.g. in bookmarklets.
|
||||||
|
|
||||||
- `keep_fargs` -- default `true`. Prevents the
|
- `keep_fargs` -- default `true`. Prevents the
|
||||||
compressor from discarding unused function arguments. You need this
|
compressor from discarding unused function arguments. You need this
|
||||||
for code which relies on `Function.length`.
|
for code which relies on `Function.length`.
|
||||||
|
|||||||
14
bin/uglifyjs
14
bin/uglifyjs
@@ -8,7 +8,6 @@ var sys = require("util");
|
|||||||
var yargs = require("yargs");
|
var yargs = require("yargs");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var async = require("async");
|
|
||||||
var acorn;
|
var acorn;
|
||||||
var screw_ie8 = true;
|
var screw_ie8 = true;
|
||||||
var ARGS = yargs
|
var ARGS = yargs
|
||||||
@@ -27,7 +26,7 @@ mangling you need to use `-c` and `-m`.\
|
|||||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||||
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
||||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript. Note: may generate incorrect code for try/catch in ES5 compliant browsers.")
|
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript.")
|
||||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
||||||
@@ -319,8 +318,11 @@ var STATS = {};
|
|||||||
var TOPLEVEL = null;
|
var TOPLEVEL = null;
|
||||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
||||||
var SOURCES_CONTENT = {};
|
var SOURCES_CONTENT = {};
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
async.eachLimit(files, 1, function (file, cb) {
|
!function cb() {
|
||||||
|
if (index == files.length) return done();
|
||||||
|
var file = files[index++];
|
||||||
read_whole_file(file, function (err, code) {
|
read_whole_file(file, function (err, code) {
|
||||||
if (err) {
|
if (err) {
|
||||||
print_error("ERROR: can't read file: " + file);
|
print_error("ERROR: can't read file: " + file);
|
||||||
@@ -388,7 +390,9 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
});
|
});
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
}, function () {
|
}();
|
||||||
|
|
||||||
|
function done() {
|
||||||
var OUTPUT_FILE = ARGS.o;
|
var OUTPUT_FILE = ARGS.o;
|
||||||
|
|
||||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
||||||
@@ -537,7 +541,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
/* -----[ functions ]----- */
|
/* -----[ functions ]----- */
|
||||||
|
|
||||||
|
|||||||
30
lib/ast.js
30
lib/ast.js
@@ -91,9 +91,20 @@ var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos
|
|||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
var AST_Node = DEFNODE("Node", "start end", {
|
var AST_Node = DEFNODE("Node", "start end", {
|
||||||
clone: function() {
|
_clone: function(deep) {
|
||||||
|
if (deep) {
|
||||||
|
var self = this.clone();
|
||||||
|
return self.transform(new TreeTransformer(function(node) {
|
||||||
|
if (node !== self) {
|
||||||
|
return node.clone(true);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
return new this.CTOR(this);
|
return new this.CTOR(this);
|
||||||
},
|
},
|
||||||
|
clone: function(deep) {
|
||||||
|
return this._clone(deep);
|
||||||
|
},
|
||||||
$documentation: "Base class of all AST nodes",
|
$documentation: "Base class of all AST nodes",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
start: "[AST_Token] The first token of this node",
|
start: "[AST_Token] The first token of this node",
|
||||||
@@ -199,6 +210,20 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
this.label._walk(visitor);
|
this.label._walk(visitor);
|
||||||
this.body._walk(visitor);
|
this.body._walk(visitor);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
clone: function(deep) {
|
||||||
|
var node = this._clone(deep);
|
||||||
|
if (deep) {
|
||||||
|
var refs = node.label.references;
|
||||||
|
var label = this.label;
|
||||||
|
node.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_LoopControl
|
||||||
|
&& node.label && node.label.thedef === label) {
|
||||||
|
refs.push(node);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
@@ -812,9 +837,6 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
|||||||
|
|
||||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||||
$propdoc: {
|
|
||||||
init: "[AST_Node*/S] array of initializers for this declaration."
|
|
||||||
}
|
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||||
|
|||||||
436
lib/compress.js
436
lib/compress.js
@@ -54,6 +54,7 @@ function Compressor(options, false_by_default) {
|
|||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
unsafe : false,
|
unsafe : false,
|
||||||
unsafe_comps : false,
|
unsafe_comps : false,
|
||||||
|
unsafe_math : false,
|
||||||
unsafe_proto : false,
|
unsafe_proto : false,
|
||||||
conditionals : !false_by_default,
|
conditionals : !false_by_default,
|
||||||
comparisons : !false_by_default,
|
comparisons : !false_by_default,
|
||||||
@@ -79,6 +80,7 @@ function Compressor(options, false_by_default) {
|
|||||||
screw_ie8 : true,
|
screw_ie8 : true,
|
||||||
drop_console : false,
|
drop_console : false,
|
||||||
angular : false,
|
angular : false,
|
||||||
|
expression : false,
|
||||||
warnings : true,
|
warnings : true,
|
||||||
global_defs : {},
|
global_defs : {},
|
||||||
passes : 1,
|
passes : 1,
|
||||||
@@ -115,12 +117,18 @@ Compressor.prototype = new TreeTransformer;
|
|||||||
merge(Compressor.prototype, {
|
merge(Compressor.prototype, {
|
||||||
option: function(key) { return this.options[key] },
|
option: function(key) { return this.options[key] },
|
||||||
compress: function(node) {
|
compress: function(node) {
|
||||||
|
if (this.option("expression")) {
|
||||||
|
node = node.process_expression(true);
|
||||||
|
}
|
||||||
var passes = +this.options.passes || 1;
|
var passes = +this.options.passes || 1;
|
||||||
for (var pass = 0; pass < passes && pass < 3; ++pass) {
|
for (var pass = 0; pass < passes && pass < 3; ++pass) {
|
||||||
if (pass > 0 || this.option("reduce_vars"))
|
if (pass > 0 || this.option("reduce_vars"))
|
||||||
node.reset_opt_flags(this, true);
|
node.reset_opt_flags(this, true);
|
||||||
node = node.transform(this);
|
node = node.transform(this);
|
||||||
}
|
}
|
||||||
|
if (this.option("expression")) {
|
||||||
|
node = node.process_expression(false);
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
warn: function(text, props) {
|
warn: function(text, props) {
|
||||||
@@ -177,8 +185,46 @@ merge(Compressor.prototype, {
|
|||||||
return this.print_to_string() == node.print_to_string();
|
return this.print_to_string() == node.print_to_string();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Node.DEFMETHOD("process_expression", function(insert) {
|
||||||
|
var self = this;
|
||||||
|
var tt = new TreeTransformer(function(node) {
|
||||||
|
if (insert && node instanceof AST_SimpleStatement) {
|
||||||
|
return make_node(AST_Return, node, {
|
||||||
|
value: node.body
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!insert && node instanceof AST_Return) {
|
||||||
|
return make_node(AST_SimpleStatement, node, {
|
||||||
|
body: node.value || make_node(AST_Undefined, node)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Lambda && node !== self) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Block) {
|
||||||
|
var index = node.body.length - 1;
|
||||||
|
if (index >= 0) {
|
||||||
|
node.body[index] = node.body[index].transform(tt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node instanceof AST_If) {
|
||||||
|
node.body = node.body.transform(tt);
|
||||||
|
if (node.alternative) {
|
||||||
|
node.alternative = node.alternative.transform(tt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node instanceof AST_With) {
|
||||||
|
node.body = node.body.transform(tt);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
return self.transform(tt);
|
||||||
|
});
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){
|
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){
|
||||||
var reduce_vars = rescan && compressor.option("reduce_vars");
|
var reduce_vars = rescan && compressor.option("reduce_vars");
|
||||||
|
var toplevel = compressor.option("toplevel");
|
||||||
|
var ie8 = !compressor.option("screw_ie8");
|
||||||
var safe_ids = [];
|
var safe_ids = [];
|
||||||
push();
|
push();
|
||||||
var suppressor = new TreeWalker(function(node) {
|
var suppressor = new TreeWalker(function(node) {
|
||||||
@@ -188,7 +234,7 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var tw = new TreeWalker(function(node){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
|
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
|
||||||
node._squeezed = false;
|
node._squeezed = false;
|
||||||
node._optimized = false;
|
node._optimized = false;
|
||||||
@@ -199,10 +245,14 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var d = node.definition();
|
var d = node.definition();
|
||||||
d.references.push(node);
|
d.references.push(node);
|
||||||
if (!d.fixed || isModified(node, 0) || !is_safe(d)) {
|
if (!d.fixed || !is_safe(d)
|
||||||
|
|| is_modified(node, 0, d.fixed instanceof AST_Lambda)) {
|
||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ie8 && node instanceof AST_SymbolCatch) {
|
||||||
|
node.definition().fixed = false;
|
||||||
|
}
|
||||||
if (node instanceof AST_VarDef) {
|
if (node instanceof AST_VarDef) {
|
||||||
var d = node.name.definition();
|
var d = node.name.definition();
|
||||||
if (d.fixed === undefined) {
|
if (d.fixed === undefined) {
|
||||||
@@ -212,6 +262,21 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Defun) {
|
||||||
|
var d = node.name.definition();
|
||||||
|
if (!toplevel && d.global || is_safe(d)) {
|
||||||
|
d.fixed = false;
|
||||||
|
} else {
|
||||||
|
d.fixed = node;
|
||||||
|
mark_as_safe(d);
|
||||||
|
}
|
||||||
|
var save_ids = safe_ids;
|
||||||
|
safe_ids = [];
|
||||||
|
push();
|
||||||
|
descend();
|
||||||
|
safe_ids = save_ids;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
var iife;
|
var iife;
|
||||||
if (node instanceof AST_Function
|
if (node instanceof AST_Function
|
||||||
&& (iife = tw.parent()) instanceof AST_Call
|
&& (iife = tw.parent()) instanceof AST_Call
|
||||||
@@ -257,6 +322,12 @@ merge(Compressor.prototype, {
|
|||||||
pop();
|
pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Catch) {
|
||||||
|
push();
|
||||||
|
descend();
|
||||||
|
pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
@@ -280,18 +351,22 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function reset_def(def) {
|
function reset_def(def) {
|
||||||
def.fixed = undefined;
|
if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) {
|
||||||
|
def.fixed = undefined;
|
||||||
|
} else {
|
||||||
|
def.fixed = false;
|
||||||
|
}
|
||||||
def.references = [];
|
def.references = [];
|
||||||
def.should_replace = undefined;
|
def.should_replace = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isModified(node, level) {
|
function is_modified(node, level, func) {
|
||||||
var parent = tw.parent(level);
|
var parent = tw.parent(level);
|
||||||
if (isLHS(node, parent)
|
if (isLHS(node, parent)
|
||||||
|| parent instanceof AST_Call && parent.expression === node) {
|
|| !func && parent instanceof AST_Call && parent.expression === node) {
|
||||||
return true;
|
return true;
|
||||||
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||||
return isModified(parent, level + 1);
|
return !func && is_modified(parent, level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -481,12 +556,13 @@ merge(Compressor.prototype, {
|
|||||||
// Constant single use vars can be replaced in any scope.
|
// Constant single use vars can be replaced in any scope.
|
||||||
if (var_decl.value.is_constant()) {
|
if (var_decl.value.is_constant()) {
|
||||||
var ctt = new TreeTransformer(function(node) {
|
var ctt = new TreeTransformer(function(node) {
|
||||||
if (node === ref) {
|
var parent = ctt.parent();
|
||||||
var parent = ctt.parent();
|
if (parent instanceof AST_IterationStatement
|
||||||
if (!(parent instanceof AST_ForIn && parent.init === node)) {
|
&& (parent.condition === node || parent.init === node)) {
|
||||||
return replace_var(node, parent, true);
|
return node;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (node === ref)
|
||||||
|
return replace_var(node, parent, true);
|
||||||
});
|
});
|
||||||
stat.transform(ctt);
|
stat.transform(ctt);
|
||||||
continue;
|
continue;
|
||||||
@@ -555,10 +631,7 @@ merge(Compressor.prototype, {
|
|||||||
return statements;
|
return statements;
|
||||||
|
|
||||||
function is_lvalue(node, parent) {
|
function is_lvalue(node, parent) {
|
||||||
return node instanceof AST_SymbolRef && (
|
return node instanceof AST_SymbolRef && isLHS(node, parent);
|
||||||
(parent instanceof AST_Assign && node === parent.left)
|
|
||||||
|| (parent instanceof AST_Unary && parent.expression === node
|
|
||||||
&& (parent.operator == "++" || parent.operator == "--")));
|
|
||||||
}
|
}
|
||||||
function replace_var(node, parent, is_constant) {
|
function replace_var(node, parent, is_constant) {
|
||||||
if (is_lvalue(node, parent)) return node;
|
if (is_lvalue(node, parent)) return node;
|
||||||
@@ -723,7 +796,7 @@ merge(Compressor.prototype, {
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.alternative = ret[0] || make_node(AST_Return, stat, {
|
stat.alternative = ret[0] || make_node(AST_Return, stat, {
|
||||||
value: make_node(AST_Undefined, stat)
|
value: null
|
||||||
});
|
});
|
||||||
ret[0] = stat.transform(compressor);
|
ret[0] = stat.transform(compressor);
|
||||||
continue loop;
|
continue loop;
|
||||||
@@ -756,7 +829,7 @@ merge(Compressor.prototype, {
|
|||||||
&& !stat.alternative) {
|
&& !stat.alternative) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
ret.push(make_node(AST_Return, ret[0], {
|
ret.push(make_node(AST_Return, ret[0], {
|
||||||
value: make_node(AST_Undefined, ret[0])
|
value: null
|
||||||
}).transform(compressor));
|
}).transform(compressor));
|
||||||
ret.unshift(stat);
|
ret.unshift(stat);
|
||||||
continue loop;
|
continue loop;
|
||||||
@@ -1013,6 +1086,10 @@ merge(Compressor.prototype, {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function is_undefined(node) {
|
||||||
|
return node instanceof AST_Undefined || node.is_undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/* -----[ boolean/negation helpers ]----- */
|
/* -----[ boolean/negation helpers ]----- */
|
||||||
|
|
||||||
// methods to determine whether an expression has a boolean result type
|
// methods to determine whether an expression has a boolean result type
|
||||||
@@ -1043,6 +1120,34 @@ merge(Compressor.prototype, {
|
|||||||
node.DEFMETHOD("is_boolean", func);
|
node.DEFMETHOD("is_boolean", func);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// methods to determine if an expression has a numeric result type
|
||||||
|
(function (def){
|
||||||
|
def(AST_Node, return_false);
|
||||||
|
def(AST_Number, return_true);
|
||||||
|
var unary = makePredicate("+ - ~ ++ --");
|
||||||
|
def(AST_Unary, function(){
|
||||||
|
return unary(this.operator);
|
||||||
|
});
|
||||||
|
var binary = makePredicate("- * / % & | ^ << >> >>>");
|
||||||
|
def(AST_Binary, function(compressor){
|
||||||
|
return binary(this.operator) || this.operator == "+"
|
||||||
|
&& this.left.is_number(compressor)
|
||||||
|
&& this.right.is_number(compressor);
|
||||||
|
});
|
||||||
|
var assign = makePredicate("-= *= /= %= &= |= ^= <<= >>= >>>=");
|
||||||
|
def(AST_Assign, function(compressor){
|
||||||
|
return assign(this.operator) || this.right.is_number(compressor);
|
||||||
|
});
|
||||||
|
def(AST_Seq, function(compressor){
|
||||||
|
return this.cdr.is_number(compressor);
|
||||||
|
});
|
||||||
|
def(AST_Conditional, function(compressor){
|
||||||
|
return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
|
||||||
|
});
|
||||||
|
})(function(node, func){
|
||||||
|
node.DEFMETHOD("is_number", func);
|
||||||
|
});
|
||||||
|
|
||||||
// methods to determine if an expression has a string result type
|
// methods to determine if an expression has a string result type
|
||||||
(function (def){
|
(function (def){
|
||||||
def(AST_Node, return_false);
|
def(AST_Node, return_false);
|
||||||
@@ -1068,7 +1173,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function isLHS(node, parent) {
|
function isLHS(node, parent) {
|
||||||
return parent instanceof AST_Unary && (parent.operator === "++" || parent.operator === "--")
|
return parent instanceof AST_Unary && (parent.operator == "++" || parent.operator == "--")
|
||||||
|| parent instanceof AST_Assign && parent.left === node;
|
|| parent instanceof AST_Assign && parent.left === node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,14 +1323,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Statement, function(){
|
def(AST_Statement, function(){
|
||||||
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
||||||
});
|
});
|
||||||
// XXX: AST_Accessor and AST_Function both inherit from AST_Scope,
|
def(AST_Lambda, function(){
|
||||||
// which itself inherits from AST_Statement; however, they aren't
|
|
||||||
// really statements. This could bite in other places too. :-(
|
|
||||||
// Wish JS had multiple inheritance.
|
|
||||||
def(AST_Accessor, function(){
|
|
||||||
throw def;
|
|
||||||
});
|
|
||||||
def(AST_Function, function(){
|
|
||||||
throw def;
|
throw def;
|
||||||
});
|
});
|
||||||
function ev(node, compressor) {
|
function ev(node, compressor) {
|
||||||
@@ -1742,6 +1840,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
|
if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
|
||||||
var def = node.definitions.filter(function(def){
|
var def = node.definitions.filter(function(def){
|
||||||
|
if (def.value) def.value = def.value.transform(tt);
|
||||||
if (def.name.definition().id in in_use_ids) return true;
|
if (def.name.definition().id in in_use_ids) return true;
|
||||||
var w = {
|
var w = {
|
||||||
name : def.name.name,
|
name : def.name.name,
|
||||||
@@ -1802,17 +1901,15 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if (drop_vars && assign_as_unused) {
|
if (drop_vars && assign_as_unused
|
||||||
var n = node;
|
&& node instanceof AST_Assign
|
||||||
while (n instanceof AST_Assign
|
&& node.operator == "="
|
||||||
&& n.operator == "="
|
&& node.left instanceof AST_SymbolRef) {
|
||||||
&& n.left instanceof AST_SymbolRef) {
|
var def = node.left.definition();
|
||||||
var def = n.left.definition();
|
if (!(def.id in in_use_ids)
|
||||||
if (def.id in in_use_ids
|
&& self.variables.get(def.name) === def) {
|
||||||
|| self.variables.get(def.name) !== def) break;
|
return maintain_this_binding(tt.parent(), node, node.right.transform(tt));
|
||||||
n = n.right;
|
|
||||||
}
|
}
|
||||||
if (n !== node) return n;
|
|
||||||
}
|
}
|
||||||
if (node instanceof AST_For) {
|
if (node instanceof AST_For) {
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
@@ -2001,7 +2098,15 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Constant, return_null);
|
def(AST_Constant, return_null);
|
||||||
def(AST_This, return_null);
|
def(AST_This, return_null);
|
||||||
def(AST_Call, function(compressor, first_in_statement){
|
def(AST_Call, function(compressor, first_in_statement){
|
||||||
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) return this;
|
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
||||||
|
if (this.expression instanceof AST_Function
|
||||||
|
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
||||||
|
var node = this.clone();
|
||||||
|
node.expression = node.expression.process_expression(false);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
if (this.pure) {
|
if (this.pure) {
|
||||||
compressor.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
|
compressor.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
|
||||||
this.pure.value = this.pure.value.replace(/[@#]__PURE__/g, ' ');
|
this.pure.value = this.pure.value.replace(/[@#]__PURE__/g, ' ');
|
||||||
@@ -2325,8 +2430,8 @@ merge(Compressor.prototype, {
|
|||||||
return make_node(self.body.CTOR, self, {
|
return make_node(self.body.CTOR, self, {
|
||||||
value: make_node(AST_Conditional, self, {
|
value: make_node(AST_Conditional, self, {
|
||||||
condition : self.condition,
|
condition : self.condition,
|
||||||
consequent : self.body.value || make_node(AST_Undefined, self.body).optimize(compressor),
|
consequent : self.body.value || make_node(AST_Undefined, self.body),
|
||||||
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative).optimize(compressor)
|
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
}).transform(compressor);
|
||||||
}
|
}
|
||||||
@@ -2493,12 +2598,28 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Call, function(self, compressor){
|
OPT(AST_Call, function(self, compressor){
|
||||||
|
var exp = self.expression;
|
||||||
|
if (compressor.option("reduce_vars")
|
||||||
|
&& exp instanceof AST_SymbolRef) {
|
||||||
|
var def = exp.definition();
|
||||||
|
if (def.fixed instanceof AST_Defun) {
|
||||||
|
def.fixed = make_node(AST_Function, def.fixed, def.fixed).clone(true);
|
||||||
|
}
|
||||||
|
if (def.fixed instanceof AST_Function) {
|
||||||
|
exp = def.fixed;
|
||||||
|
if (compressor.option("unused")
|
||||||
|
&& def.references.length == 1
|
||||||
|
&& compressor.find_parent(AST_Scope) === def.scope) {
|
||||||
|
self.expression = exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& self.expression instanceof AST_Function
|
&& exp instanceof AST_Function
|
||||||
&& !self.expression.uses_arguments
|
&& !exp.uses_arguments
|
||||||
&& !self.expression.uses_eval
|
&& !exp.uses_eval
|
||||||
&& self.args.length > self.expression.argnames.length) {
|
&& self.args.length > exp.argnames.length) {
|
||||||
var end = self.expression.argnames.length;
|
var end = exp.argnames.length;
|
||||||
for (var i = end, len = self.args.length; i < len; i++) {
|
for (var i = end, len = self.args.length; i < len; i++) {
|
||||||
var node = self.args[i].drop_side_effect_free(compressor);
|
var node = self.args[i].drop_side_effect_free(compressor);
|
||||||
if (node) {
|
if (node) {
|
||||||
@@ -2508,7 +2629,6 @@ merge(Compressor.prototype, {
|
|||||||
self.args.length = end;
|
self.args.length = end;
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var exp = self.expression;
|
|
||||||
if (exp instanceof AST_SymbolRef && exp.undeclared()) {
|
if (exp instanceof AST_SymbolRef && exp.undeclared()) {
|
||||||
switch (exp.name) {
|
switch (exp.name) {
|
||||||
case "Array":
|
case "Array":
|
||||||
@@ -2682,16 +2802,24 @@ merge(Compressor.prototype, {
|
|||||||
return best_of(self, node);
|
return best_of(self, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects")) {
|
if (exp instanceof AST_Function) {
|
||||||
if (self.expression instanceof AST_Function
|
if (exp.body[0] instanceof AST_Return) {
|
||||||
&& self.args.length == 0
|
var value = exp.body[0].value;
|
||||||
&& !AST_Block.prototype.has_side_effects.call(self.expression, compressor)) {
|
if (!value || value.is_constant()) {
|
||||||
return make_node(AST_Undefined, self).transform(compressor);
|
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
||||||
|
return AST_Seq.from_array(args).transform(compressor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (compressor.option("side_effects")) {
|
||||||
|
if (!AST_Block.prototype.has_side_effects.call(exp, compressor)) {
|
||||||
|
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||||
|
return AST_Seq.from_array(args).transform(compressor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("drop_console")) {
|
if (compressor.option("drop_console")) {
|
||||||
if (self.expression instanceof AST_PropAccess) {
|
if (exp instanceof AST_PropAccess) {
|
||||||
var name = self.expression.expression;
|
var name = exp.expression;
|
||||||
while (name.expression) {
|
while (name.expression) {
|
||||||
name = name.expression;
|
name = name.expression;
|
||||||
}
|
}
|
||||||
@@ -2702,12 +2830,6 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self.args.length == 0
|
|
||||||
&& self.expression instanceof AST_Function
|
|
||||||
&& self.expression.body[0] instanceof AST_Return
|
|
||||||
&& self.expression.body[0].value.is_constant()) {
|
|
||||||
return self.expression.body[0].value;
|
|
||||||
}
|
|
||||||
if (compressor.option("negate_iife")
|
if (compressor.option("negate_iife")
|
||||||
&& compressor.parent() instanceof AST_SimpleStatement
|
&& compressor.parent() instanceof AST_SimpleStatement
|
||||||
&& is_iife_call(self)) {
|
&& is_iife_call(self)) {
|
||||||
@@ -2739,23 +2861,41 @@ merge(Compressor.prototype, {
|
|||||||
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
||||||
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
|
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
|
||||||
if (compressor.option("cascade")) {
|
if (compressor.option("cascade")) {
|
||||||
|
var left;
|
||||||
if (self.car instanceof AST_Assign
|
if (self.car instanceof AST_Assign
|
||||||
&& !self.car.left.has_side_effects(compressor)) {
|
&& !self.car.left.has_side_effects(compressor)) {
|
||||||
if (self.car.left.equivalent_to(self.cdr)) {
|
left = self.car.left;
|
||||||
return self.car;
|
} else if (self.car instanceof AST_Unary
|
||||||
}
|
&& (self.car.operator == "++" || self.car.operator == "--")) {
|
||||||
if (self.cdr instanceof AST_Call
|
left = self.car.expression;
|
||||||
&& self.cdr.expression.equivalent_to(self.car.left)) {
|
|
||||||
self.cdr.expression = self.car;
|
|
||||||
return self.cdr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!self.car.has_side_effects(compressor)
|
if (left) {
|
||||||
&& self.car.equivalent_to(self.cdr)) {
|
var parent, field;
|
||||||
return self.car;
|
var cdr = self.cdr;
|
||||||
|
while (true) {
|
||||||
|
if (cdr.equivalent_to(left)) {
|
||||||
|
var car = self.car instanceof AST_UnaryPostfix ? make_node(AST_UnaryPrefix, self.car, {
|
||||||
|
operator: self.car.operator,
|
||||||
|
expression: left
|
||||||
|
}) : self.car;
|
||||||
|
if (parent) {
|
||||||
|
parent[field] = car;
|
||||||
|
return self.cdr;
|
||||||
|
}
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) {
|
||||||
|
field = cdr.left.is_constant() ? "right" : "left";
|
||||||
|
} else if (cdr instanceof AST_Call
|
||||||
|
|| cdr instanceof AST_Unary && cdr.operator != "++" && cdr.operator != "--") {
|
||||||
|
field = "expression";
|
||||||
|
} else break;
|
||||||
|
parent = cdr;
|
||||||
|
cdr = cdr[field];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self.cdr instanceof AST_Undefined) {
|
if (is_undefined(self.cdr)) {
|
||||||
return make_node(AST_UnaryPrefix, self, {
|
return make_node(AST_UnaryPrefix, self, {
|
||||||
operator : "void",
|
operator : "void",
|
||||||
expression : self.car
|
expression : self.car
|
||||||
@@ -2794,7 +2934,7 @@ merge(Compressor.prototype, {
|
|||||||
self.expression = e;
|
self.expression = e;
|
||||||
return self;
|
return self;
|
||||||
} else {
|
} else {
|
||||||
return make_node(AST_Undefined, self);
|
return make_node(AST_Undefined, self).transform(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
@@ -2867,8 +3007,14 @@ merge(Compressor.prototype, {
|
|||||||
right: rhs[0]
|
right: rhs[0]
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
function reverse(op, force) {
|
function reversible() {
|
||||||
if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) {
|
return self.left instanceof AST_Constant
|
||||||
|
|| self.right instanceof AST_Constant
|
||||||
|
|| !self.left.has_side_effects(compressor)
|
||||||
|
&& !self.right.has_side_effects(compressor);
|
||||||
|
}
|
||||||
|
function reverse(op) {
|
||||||
|
if (reversible()) {
|
||||||
if (op) self.operator = op;
|
if (op) self.operator = op;
|
||||||
var tmp = self.left;
|
var tmp = self.left;
|
||||||
self.left = self.right;
|
self.left = self.right;
|
||||||
@@ -2884,7 +3030,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
if (!(self.left instanceof AST_Binary
|
if (!(self.left instanceof AST_Binary
|
||||||
&& PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
|
&& PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
|
||||||
reverse(null, true);
|
reverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (/^[!=]==?$/.test(self.operator)) {
|
if (/^[!=]==?$/.test(self.operator)) {
|
||||||
@@ -2919,6 +3065,7 @@ merge(Compressor.prototype, {
|
|||||||
case "===":
|
case "===":
|
||||||
case "!==":
|
case "!==":
|
||||||
if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
|
if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
|
||||||
|
(self.left.is_number(compressor) && self.right.is_number(compressor)) ||
|
||||||
(self.left.is_boolean() && self.right.is_boolean())) {
|
(self.left.is_boolean() && self.right.is_boolean())) {
|
||||||
self.operator = self.operator.substr(0, 2);
|
self.operator = self.operator.substr(0, 2);
|
||||||
}
|
}
|
||||||
@@ -3056,7 +3203,10 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (self.operator == "+") {
|
var associative = true;
|
||||||
|
switch (self.operator) {
|
||||||
|
case "+":
|
||||||
|
// "foo" + ("bar" + x) => "foobar" + x
|
||||||
if (self.left instanceof AST_Constant
|
if (self.left instanceof AST_Constant
|
||||||
&& self.right instanceof AST_Binary
|
&& self.right instanceof AST_Binary
|
||||||
&& self.right.operator == "+"
|
&& self.right.operator == "+"
|
||||||
@@ -3064,7 +3214,7 @@ merge(Compressor.prototype, {
|
|||||||
&& self.right.is_string(compressor)) {
|
&& self.right.is_string(compressor)) {
|
||||||
self = make_node(AST_Binary, self, {
|
self = make_node(AST_Binary, self, {
|
||||||
operator: "+",
|
operator: "+",
|
||||||
left: make_node(AST_String, null, {
|
left: make_node(AST_String, self.left, {
|
||||||
value: "" + self.left.getValue() + self.right.left.getValue(),
|
value: "" + self.left.getValue() + self.right.left.getValue(),
|
||||||
start: self.left.start,
|
start: self.left.start,
|
||||||
end: self.right.left.end
|
end: self.right.left.end
|
||||||
@@ -3072,6 +3222,7 @@ merge(Compressor.prototype, {
|
|||||||
right: self.right.right
|
right: self.right.right
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// (x + "foo") + "bar" => x + "foobar"
|
||||||
if (self.right instanceof AST_Constant
|
if (self.right instanceof AST_Constant
|
||||||
&& self.left instanceof AST_Binary
|
&& self.left instanceof AST_Binary
|
||||||
&& self.left.operator == "+"
|
&& self.left.operator == "+"
|
||||||
@@ -3080,13 +3231,14 @@ merge(Compressor.prototype, {
|
|||||||
self = make_node(AST_Binary, self, {
|
self = make_node(AST_Binary, self, {
|
||||||
operator: "+",
|
operator: "+",
|
||||||
left: self.left.left,
|
left: self.left.left,
|
||||||
right: make_node(AST_String, null, {
|
right: make_node(AST_String, self.right, {
|
||||||
value: "" + self.left.right.getValue() + self.right.getValue(),
|
value: "" + self.left.right.getValue() + self.right.getValue(),
|
||||||
start: self.left.right.start,
|
start: self.left.right.start,
|
||||||
end: self.right.end
|
end: self.right.end
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// (x + "foo") + ("bar" + y) => (x + "foobar") + y
|
||||||
if (self.left instanceof AST_Binary
|
if (self.left instanceof AST_Binary
|
||||||
&& self.left.operator == "+"
|
&& self.left.operator == "+"
|
||||||
&& self.left.is_string(compressor)
|
&& self.left.is_string(compressor)
|
||||||
@@ -3100,7 +3252,7 @@ merge(Compressor.prototype, {
|
|||||||
left: make_node(AST_Binary, self.left, {
|
left: make_node(AST_Binary, self.left, {
|
||||||
operator: "+",
|
operator: "+",
|
||||||
left: self.left.left,
|
left: self.left.left,
|
||||||
right: make_node(AST_String, null, {
|
right: make_node(AST_String, self.left.right, {
|
||||||
value: "" + self.left.right.getValue() + self.right.left.getValue(),
|
value: "" + self.left.right.getValue() + self.right.left.getValue(),
|
||||||
start: self.left.right.start,
|
start: self.left.right.start,
|
||||||
end: self.right.left.end
|
end: self.right.left.end
|
||||||
@@ -3109,6 +3261,122 @@ merge(Compressor.prototype, {
|
|||||||
right: self.right.right
|
right: self.right.right
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// a + -b => a - b
|
||||||
|
if (self.right instanceof AST_UnaryPrefix
|
||||||
|
&& self.right.operator == "-"
|
||||||
|
&& self.left.is_number(compressor)) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: "-",
|
||||||
|
left: self.left,
|
||||||
|
right: self.right.expression
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// -a + b => b - a
|
||||||
|
if (self.left instanceof AST_UnaryPrefix
|
||||||
|
&& self.left.operator == "-"
|
||||||
|
&& reversible()
|
||||||
|
&& self.right.is_number(compressor)) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: "-",
|
||||||
|
left: self.right,
|
||||||
|
right: self.left.expression
|
||||||
|
});
|
||||||
|
}
|
||||||
|
case "*":
|
||||||
|
associative = compressor.option("unsafe_math");
|
||||||
|
case "&":
|
||||||
|
case "|":
|
||||||
|
case "^":
|
||||||
|
// a + +b => +b + a
|
||||||
|
if (self.left.is_number(compressor)
|
||||||
|
&& self.right.is_number(compressor)
|
||||||
|
&& reversible()
|
||||||
|
&& !(self.left instanceof AST_Binary
|
||||||
|
&& self.left.operator != self.operator
|
||||||
|
&& PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
|
||||||
|
var reversed = make_node(AST_Binary, self, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: self.right,
|
||||||
|
right: self.left
|
||||||
|
});
|
||||||
|
if (self.right instanceof AST_Constant
|
||||||
|
&& !(self.left instanceof AST_Constant)) {
|
||||||
|
self = best_of(reversed, self);
|
||||||
|
} else {
|
||||||
|
self = best_of(self, reversed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (associative && self.is_number(compressor)) {
|
||||||
|
// a + (b + c) => (a + b) + c
|
||||||
|
if (self.right instanceof AST_Binary
|
||||||
|
&& self.right.operator == self.operator) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: make_node(AST_Binary, self.left, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: self.left,
|
||||||
|
right: self.right.left,
|
||||||
|
start: self.left.start,
|
||||||
|
end: self.right.left.end
|
||||||
|
}),
|
||||||
|
right: self.right.right
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// (n + 2) + 3 => 5 + n
|
||||||
|
// (2 * n) * 3 => 6 + n
|
||||||
|
if (self.right instanceof AST_Constant
|
||||||
|
&& self.left instanceof AST_Binary
|
||||||
|
&& self.left.operator == self.operator) {
|
||||||
|
if (self.left.left instanceof AST_Constant) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: make_node(AST_Binary, self.left, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: self.left.left,
|
||||||
|
right: self.right,
|
||||||
|
start: self.left.left.start,
|
||||||
|
end: self.right.end
|
||||||
|
}),
|
||||||
|
right: self.left.right
|
||||||
|
});
|
||||||
|
} else if (self.left.right instanceof AST_Constant) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: make_node(AST_Binary, self.left, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: self.left.right,
|
||||||
|
right: self.right,
|
||||||
|
start: self.left.right.start,
|
||||||
|
end: self.right.end
|
||||||
|
}),
|
||||||
|
right: self.left.left
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// (a | 1) | (2 | d) => (3 | a) | b
|
||||||
|
if (self.left instanceof AST_Binary
|
||||||
|
&& self.left.operator == self.operator
|
||||||
|
&& self.left.right instanceof AST_Constant
|
||||||
|
&& self.right instanceof AST_Binary
|
||||||
|
&& self.right.operator == self.operator
|
||||||
|
&& self.right.left instanceof AST_Constant) {
|
||||||
|
self = make_node(AST_Binary, self, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: make_node(AST_Binary, self.left, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: make_node(AST_Binary, self.left.left, {
|
||||||
|
operator: self.operator,
|
||||||
|
left: self.left.right,
|
||||||
|
right: self.right.left,
|
||||||
|
start: self.left.right.start,
|
||||||
|
end: self.right.left.end
|
||||||
|
}),
|
||||||
|
right: self.left.left
|
||||||
|
}),
|
||||||
|
right: self.right.right
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// x && (y && z) ==> x && y && z
|
// x && (y && z) ==> x && y && z
|
||||||
@@ -3141,11 +3409,13 @@ merge(Compressor.prototype, {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
// testing against !self.scope.uses_with first is an optimization
|
// testing against !self.scope.uses_with first is an optimization
|
||||||
if (self.undeclared() && !isLHS(self, compressor.parent())
|
if (compressor.option("screw_ie8")
|
||||||
|
&& self.undeclared()
|
||||||
|
&& !isLHS(self, compressor.parent())
|
||||||
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
||||||
switch (self.name) {
|
switch (self.name) {
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return make_node(AST_Undefined, self);
|
return make_node(AST_Undefined, self).transform(compressor);
|
||||||
case "NaN":
|
case "NaN":
|
||||||
return make_node(AST_NaN, self).transform(compressor);
|
return make_node(AST_NaN, self).transform(compressor);
|
||||||
case "Infinity":
|
case "Infinity":
|
||||||
@@ -3188,11 +3458,13 @@ merge(Compressor.prototype, {
|
|||||||
var scope = compressor.find_parent(AST_Scope);
|
var scope = compressor.find_parent(AST_Scope);
|
||||||
var undef = scope.find_variable("undefined");
|
var undef = scope.find_variable("undefined");
|
||||||
if (undef) {
|
if (undef) {
|
||||||
return make_node(AST_SymbolRef, self, {
|
var ref = make_node(AST_SymbolRef, self, {
|
||||||
name : "undefined",
|
name : "undefined",
|
||||||
scope : scope,
|
scope : scope,
|
||||||
thedef : undef
|
thedef : undef
|
||||||
});
|
});
|
||||||
|
ref.is_undefined = true;
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -3479,7 +3751,7 @@ merge(Compressor.prototype, {
|
|||||||
OPT(AST_RegExp, literals_in_boolean_context);
|
OPT(AST_RegExp, literals_in_boolean_context);
|
||||||
|
|
||||||
OPT(AST_Return, function(self, compressor){
|
OPT(AST_Return, function(self, compressor){
|
||||||
if (self.value instanceof AST_Undefined) {
|
if (self.value && is_undefined(self.value)) {
|
||||||
self.value = null;
|
self.value = null;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -46,17 +46,8 @@
|
|||||||
var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
||||||
|
|
||||||
function is_some_comments(comment) {
|
function is_some_comments(comment) {
|
||||||
var text = comment.value;
|
// multiline comment
|
||||||
var type = comment.type;
|
return comment.type == "comment2" && /@preserve|@license|@cc_on/i.test(comment.value);
|
||||||
if (type == "comment2") {
|
|
||||||
// multiline comment
|
|
||||||
return /@preserve|@license|@cc_on/i.test(text);
|
|
||||||
}
|
|
||||||
return type == "comment5";
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_comment5(comment) {
|
|
||||||
return comment.type == "comment5";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function OutputStream(options) {
|
function OutputStream(options) {
|
||||||
@@ -86,7 +77,7 @@ function OutputStream(options) {
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// Convert comment option to RegExp if neccessary and set up comments filter
|
// Convert comment option to RegExp if neccessary and set up comments filter
|
||||||
var comment_filter = options.shebang ? is_comment5 : return_false; // Default case, throw all comments away except shebangs
|
var comment_filter = return_false; // Default case, throw all comments away
|
||||||
if (options.comments) {
|
if (options.comments) {
|
||||||
var comments = options.comments;
|
var comments = options.comments;
|
||||||
if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
|
if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
|
||||||
@@ -98,12 +89,12 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
if (comments instanceof RegExp) {
|
if (comments instanceof RegExp) {
|
||||||
comment_filter = function(comment) {
|
comment_filter = function(comment) {
|
||||||
return comment.type == "comment5" || comments.test(comment.value);
|
return comment.type != "comment5" && comments.test(comment.value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (typeof comments === "function") {
|
else if (typeof comments === "function") {
|
||||||
comment_filter = function(comment) {
|
comment_filter = function(comment) {
|
||||||
return comment.type == "comment5" || comments(this, comment);
|
return comment.type != "comment5" && comments(this, comment);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (comments === "some") {
|
else if (comments === "some") {
|
||||||
@@ -400,10 +391,6 @@ function OutputStream(options) {
|
|||||||
return OUTPUT;
|
return OUTPUT;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.preamble) {
|
|
||||||
print(options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
return {
|
return {
|
||||||
get : get,
|
get : get,
|
||||||
@@ -523,6 +510,17 @@ function OutputStream(options) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comments.length > 0 && output.pos() == 0) {
|
||||||
|
if (output.option("shebang") && comments[0].type == "comment5") {
|
||||||
|
output.print("#!" + comments.shift().value + "\n");
|
||||||
|
output.indent();
|
||||||
|
}
|
||||||
|
var preamble = output.option("preamble");
|
||||||
|
if (preamble) {
|
||||||
|
output.print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
comments = comments.filter(output.comment_filter, self);
|
comments = comments.filter(output.comment_filter, self);
|
||||||
|
|
||||||
// Keep single line comments after nlb, after nlb
|
// Keep single line comments after nlb, after nlb
|
||||||
@@ -547,10 +545,6 @@ function OutputStream(options) {
|
|||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (output.pos() === 0 && c.type == "comment5" && output.option("shebang")) {
|
|
||||||
output.print("#!" + c.value + "\n");
|
|
||||||
output.indent();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -783,7 +777,7 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Do, function(self, output){
|
DEFPRINT(AST_Do, function(self, output){
|
||||||
output.print("do");
|
output.print("do");
|
||||||
output.space();
|
output.space();
|
||||||
self._do_print_body(output);
|
make_block(self.body, output);
|
||||||
output.space();
|
output.space();
|
||||||
output.print("while");
|
output.print("while");
|
||||||
output.space();
|
output.space();
|
||||||
@@ -910,10 +904,10 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
/* -----[ if ]----- */
|
/* -----[ if ]----- */
|
||||||
function make_then(self, output) {
|
function make_then(self, output) {
|
||||||
if (output.option("bracketize")) {
|
var b = self.body;
|
||||||
make_block(self.body, output);
|
if (output.option("bracketize")
|
||||||
return;
|
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
||||||
}
|
return make_block(b, output);
|
||||||
// The squeezer replaces "block"-s that contain only a single
|
// The squeezer replaces "block"-s that contain only a single
|
||||||
// statement with the statement itself; technically, the AST
|
// statement with the statement itself; technically, the AST
|
||||||
// is correct, but this can create problems when we output an
|
// is correct, but this can create problems when we output an
|
||||||
@@ -921,18 +915,7 @@ function OutputStream(options) {
|
|||||||
// IF *without* an ELSE block (then the outer ELSE would refer
|
// IF *without* an ELSE block (then the outer ELSE would refer
|
||||||
// to the inner IF). This function checks for this case and
|
// to the inner IF). This function checks for this case and
|
||||||
// adds the block brackets if needed.
|
// adds the block brackets if needed.
|
||||||
if (!self.body)
|
if (!b) return output.force_semicolon();
|
||||||
return output.force_semicolon();
|
|
||||||
if (self.body instanceof AST_Do) {
|
|
||||||
// Unconditionally use the if/do-while workaround for all browsers.
|
|
||||||
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
|
|
||||||
// croaks with "syntax error" on code like this: if (foo)
|
|
||||||
// do ... while(cond); else ... we need block brackets
|
|
||||||
// around do/while
|
|
||||||
make_block(self.body, output);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var b = self.body;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (b instanceof AST_If) {
|
if (b instanceof AST_If) {
|
||||||
if (!b.alternative) {
|
if (!b.alternative) {
|
||||||
@@ -1341,15 +1324,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function force_statement(stat, output) {
|
function force_statement(stat, output) {
|
||||||
if (output.option("bracketize")) {
|
if (output.option("bracketize")) {
|
||||||
if (!stat || stat instanceof AST_EmptyStatement)
|
make_block(stat, output);
|
||||||
output.print("{}");
|
|
||||||
else if (stat instanceof AST_BlockStatement)
|
|
||||||
stat.print(output);
|
|
||||||
else output.with_block(function(){
|
|
||||||
output.indent();
|
|
||||||
stat.print(output);
|
|
||||||
output.newline();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
if (!stat || stat instanceof AST_EmptyStatement)
|
if (!stat || stat instanceof AST_EmptyStatement)
|
||||||
output.force_semicolon();
|
output.force_semicolon();
|
||||||
@@ -1398,11 +1373,11 @@ function OutputStream(options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function make_block(stmt, output) {
|
function make_block(stmt, output) {
|
||||||
if (stmt instanceof AST_BlockStatement) {
|
if (!stmt || stmt instanceof AST_EmptyStatement)
|
||||||
|
output.print("{}");
|
||||||
|
else if (stmt instanceof AST_BlockStatement)
|
||||||
stmt.print(output);
|
stmt.print(output);
|
||||||
return;
|
else output.with_block(function(){
|
||||||
}
|
|
||||||
output.with_block(function(){
|
|
||||||
output.indent();
|
output.indent();
|
||||||
stmt.print(output);
|
stmt.print(output);
|
||||||
output.newline();
|
output.newline();
|
||||||
|
|||||||
12
lib/parse.js
12
lib/parse.js
@@ -558,6 +558,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
function next_token(force_regexp) {
|
function next_token(force_regexp) {
|
||||||
if (force_regexp != null)
|
if (force_regexp != null)
|
||||||
return read_regexp(force_regexp);
|
return read_regexp(force_regexp);
|
||||||
|
if (shebang && S.pos == 0 && looking_at("#!")) {
|
||||||
|
start_token();
|
||||||
|
forward(2);
|
||||||
|
skip_line_comment("comment5");
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
skip_whitespace();
|
skip_whitespace();
|
||||||
start_token();
|
start_token();
|
||||||
@@ -589,13 +594,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||||
if (shebang) {
|
|
||||||
if (S.pos == 0 && looking_at("#!")) {
|
|
||||||
forward(2);
|
|
||||||
skip_line_comment("comment5");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parse_error("Unexpected character '" + ch + "'");
|
parse_error("Unexpected character '" + ch + "'");
|
||||||
|
|||||||
25
lib/scope.js
25
lib/scope.js
@@ -97,7 +97,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
var labels = new Dictionary();
|
var labels = new Dictionary();
|
||||||
var defun = null;
|
var defun = null;
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
if (node instanceof AST_Catch) {
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
scope = new AST_Scope(node);
|
scope = new AST_Scope(node);
|
||||||
scope.init_scope_vars();
|
scope.init_scope_vars();
|
||||||
@@ -154,12 +154,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar
|
else if (node instanceof AST_SymbolVar
|
||||||
|| node instanceof AST_SymbolConst) {
|
|| node instanceof AST_SymbolConst) {
|
||||||
var def = defun.def_variable(node);
|
defun.def_variable(node);
|
||||||
def.init = tw.parent().value;
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
(options.screw_ie8 ? scope : defun)
|
scope.def_variable(node);
|
||||||
.def_variable(node);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_LabelRef) {
|
else if (node instanceof AST_LabelRef) {
|
||||||
var sym = labels.get(node.name);
|
var sym = labels.get(node.name);
|
||||||
@@ -209,6 +207,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
|
// pass 3: fix up any scoping issue with IE8
|
||||||
|
if (!options.screw_ie8) {
|
||||||
|
self.walk(new TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof AST_SymbolCatch) {
|
||||||
|
var name = node.name;
|
||||||
|
var scope = node.thedef.scope.parent_scope;
|
||||||
|
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||||
|
node.thedef.references.forEach(function(ref) {
|
||||||
|
ref.thedef = def;
|
||||||
|
ref.reference(options);
|
||||||
|
});
|
||||||
|
node.thedef = def;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.cname = options.cache.cname;
|
this.cname = options.cache.cname;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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": "2.8.5",
|
"version": "2.8.10",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -29,7 +29,6 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "~0.2.6",
|
|
||||||
"source-map": "~0.5.1",
|
"source-map": "~0.5.1",
|
||||||
"uglify-to-browserify": "~1.0.0",
|
"uglify-to-browserify": "~1.0.0",
|
||||||
"yargs": "~3.10.0"
|
"yargs": "~3.10.0"
|
||||||
|
|||||||
@@ -24,26 +24,57 @@ var results = {};
|
|||||||
var remaining = 2 * urls.length;
|
var remaining = 2 * urls.length;
|
||||||
function done() {
|
function done() {
|
||||||
if (!--remaining) {
|
if (!--remaining) {
|
||||||
|
var failures = [];
|
||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
|
var info = results[url];
|
||||||
console.log();
|
console.log();
|
||||||
console.log(url);
|
console.log(url);
|
||||||
console.log(results[url].time);
|
console.log(info.log);
|
||||||
console.log("SHA1:", results[url].sha1);
|
var elapsed = 0;
|
||||||
|
info.log.replace(/: ([0-9]+\.[0-9]{3})s/g, function(match, time) {
|
||||||
|
elapsed += parseFloat(time);
|
||||||
|
});
|
||||||
|
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||||
|
console.log("Original:", info.input, "bytes");
|
||||||
|
console.log("Uglified:", info.output, "bytes");
|
||||||
|
console.log("SHA1 sum:", info.sha1);
|
||||||
|
if (info.code) {
|
||||||
|
failures.push(url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
if (failures.length) {
|
||||||
|
console.error("Benchmark failed:");
|
||||||
|
failures.forEach(function(url) {
|
||||||
|
console.error(url);
|
||||||
|
});
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
results[url] = { time: "" };
|
results[url] = {
|
||||||
|
input: 0,
|
||||||
|
output: 0,
|
||||||
|
log: ""
|
||||||
|
};
|
||||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||||
res.pipe(uglifyjs.stdin);
|
res.on("data", function(data) {
|
||||||
uglifyjs.stdout.pipe(createHash("sha1")).on("data", function(data) {
|
results[url].input += data.length;
|
||||||
|
}).pipe(uglifyjs.stdin);
|
||||||
|
uglifyjs.stdout.on("data", function(data) {
|
||||||
|
results[url].output += data.length;
|
||||||
|
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||||
results[url].sha1 = data.toString("hex");
|
results[url].sha1 = data.toString("hex");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
uglifyjs.stderr.setEncoding("utf8");
|
uglifyjs.stderr.setEncoding("utf8");
|
||||||
uglifyjs.stderr.on("data", function(data) {
|
uglifyjs.stderr.on("data", function(data) {
|
||||||
results[url].time += data;
|
results[url].log += data;
|
||||||
}).on("end", done)
|
});
|
||||||
|
uglifyjs.on("exit", function(code) {
|
||||||
|
results[url].code = code;
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -344,9 +344,9 @@ collapse_vars_do_while: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
// The constant do-while condition `c` will be replaced.
|
// The constant do-while condition `c` will not be replaced.
|
||||||
var c = 9;
|
var c = 9;
|
||||||
do { } while (c === 77);
|
do {} while (c === 77);
|
||||||
}
|
}
|
||||||
function f2(y) {
|
function f2(y) {
|
||||||
// The non-constant do-while condition `c` will not be replaced.
|
// The non-constant do-while condition `c` will not be replaced.
|
||||||
@@ -381,7 +381,8 @@ collapse_vars_do_while: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
do ; while (false);
|
var c = 9;
|
||||||
|
do ; while (77 === c);
|
||||||
}
|
}
|
||||||
function f2(y) {
|
function f2(y) {
|
||||||
var c = 5 - y;
|
var c = 5 - y;
|
||||||
@@ -418,9 +419,9 @@ collapse_vars_do_while_drop_assign: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
// The constant do-while condition `c` will be replaced.
|
// The constant do-while condition `c` will be not replaced.
|
||||||
var c = 9;
|
var c = 9;
|
||||||
do { } while (c === 77);
|
do {} while (c === 77);
|
||||||
}
|
}
|
||||||
function f2(y) {
|
function f2(y) {
|
||||||
// The non-constant do-while condition `c` will not be replaced.
|
// The non-constant do-while condition `c` will not be replaced.
|
||||||
@@ -455,7 +456,8 @@ collapse_vars_do_while_drop_assign: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
do ; while (false);
|
var c = 9;
|
||||||
|
do ; while (77 === c);
|
||||||
}
|
}
|
||||||
function f2(y) {
|
function f2(y) {
|
||||||
var c = 5 - y;
|
var c = 5 - y;
|
||||||
@@ -1309,8 +1311,8 @@ collapse_vars_regexp: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
(function(){
|
(function(){
|
||||||
var result, rx = /ab*/g;
|
var result, s = "acdabcdeabbb", rx = /ab*/g;
|
||||||
while (result = rx.exec('acdabcdeabbb'))
|
while (result = rx.exec(s))
|
||||||
console.log(result[0]);
|
console.log(result[0]);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -1329,3 +1331,35 @@ issue_1537: {
|
|||||||
for (k in {prop: 'val'});
|
for (k in {prop: 'val'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1562: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var v = 1, B = 2;
|
||||||
|
for (v in objs) f(B);
|
||||||
|
|
||||||
|
var x = 3, C = 10;
|
||||||
|
while(x + 2) bar(C);
|
||||||
|
|
||||||
|
var y = 4, D = 20;
|
||||||
|
do bar(D); while(y + 2);
|
||||||
|
|
||||||
|
var z = 5, E = 30;
|
||||||
|
for (; f(z + 2) ;) bar(E);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var v = 1;
|
||||||
|
for (v in objs) f(2);
|
||||||
|
|
||||||
|
var x = 3;
|
||||||
|
while(x + 2) bar(10);
|
||||||
|
|
||||||
|
var y = 4;
|
||||||
|
do bar(20); while(y + 2);
|
||||||
|
|
||||||
|
var z = 5;
|
||||||
|
for (; f(z + 2) ;) bar(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ dead_code_const_annotation: {
|
|||||||
conditionals : true,
|
conditionals : true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
|
toplevel : true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var unused;
|
var unused;
|
||||||
@@ -172,6 +173,7 @@ dead_code_const_annotation_complex_scope: {
|
|||||||
conditionals : true,
|
conditionals : true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
|
toplevel : true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var unused_var;
|
var unused_var;
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ iife: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
~function() {}(b);
|
b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -700,3 +700,64 @@ issue_1539: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vardef_value: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g(){
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
var a = g();
|
||||||
|
return a(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a = function(){
|
||||||
|
return x();
|
||||||
|
}();
|
||||||
|
return a(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_binding: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
a = f.g, a();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
(0, f.g)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_chain: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a, b;
|
||||||
|
x = a = y = b = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
x = y = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -640,9 +640,7 @@ call_args: {
|
|||||||
expect: {
|
expect: {
|
||||||
const a = 1;
|
const a = 1;
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+function(a) {
|
+(1, 1);
|
||||||
return 1;
|
|
||||||
}(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,9 +661,7 @@ call_args_drop_param: {
|
|||||||
expect: {
|
expect: {
|
||||||
const a = 1;
|
const a = 1;
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+function() {
|
+(b, 1);
|
||||||
return 1;
|
|
||||||
}(b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ iifes_returning_constants_keep_fargs_true: {
|
|||||||
console.log("okay");
|
console.log("okay");
|
||||||
console.log(123);
|
console.log(123);
|
||||||
console.log(void 0);
|
console.log(void 0);
|
||||||
console.log(function(x,y,z){return 2}(1,2,3));
|
console.log(2);
|
||||||
console.log(function(x,y){return 6}(2,3));
|
console.log(6);
|
||||||
console.log(function(x, y){return 6}(2,3,a(),b()));
|
console.log((a(), b(), 6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +71,23 @@ iifes_returning_constants_keep_fargs_false: {
|
|||||||
console.log(void 0);
|
console.log(void 0);
|
||||||
console.log(2);
|
console.log(2);
|
||||||
console.log(6);
|
console.log(6);
|
||||||
console.log(function(){return 6}(a(),b()));
|
console.log((a(), b(), 6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_485_crashing_1530: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
if (true) return;
|
||||||
|
var b = 42;
|
||||||
|
})(this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
this, void 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
unsafe_undefined: {
|
unsafe_undefined: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe: true
|
||||||
}
|
}
|
||||||
@@ -19,12 +20,7 @@ unsafe_undefined: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
return function() {
|
return function() {
|
||||||
if (a)
|
return a ? b : c ? d : n;
|
||||||
return b;
|
|
||||||
if (c)
|
|
||||||
return d;
|
|
||||||
else
|
|
||||||
return n;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +28,7 @@ unsafe_undefined: {
|
|||||||
|
|
||||||
keep_fnames: {
|
keep_fnames: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe: true
|
||||||
}
|
}
|
||||||
@@ -57,12 +54,7 @@ keep_fnames: {
|
|||||||
function n(n) {
|
function n(n) {
|
||||||
return n * n;
|
return n * n;
|
||||||
}
|
}
|
||||||
if (a)
|
return a ? b : c ? d : r;
|
||||||
return b;
|
|
||||||
if (c)
|
|
||||||
return d;
|
|
||||||
else
|
|
||||||
return r;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
test/compress/issue-1569.js
Normal file
19
test/compress/issue-1569.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
inner_reference: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function f(a) {
|
||||||
|
return a && f(a - 1) + a;
|
||||||
|
}(42);
|
||||||
|
!function g(a) {
|
||||||
|
return a;
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function f(a) {
|
||||||
|
return a && f(a - 1) + a;
|
||||||
|
}(42);
|
||||||
|
!void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
test/compress/issue-368.js
Normal file
55
test/compress/issue-368.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
collapse: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a;
|
||||||
|
a = typeof b === 'function' ? b() : b;
|
||||||
|
return a !== undefined && c();
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
var a;
|
||||||
|
b = c();
|
||||||
|
a = typeof b === 'function' ? b() : b;
|
||||||
|
return 'stirng' == typeof a && d();
|
||||||
|
}
|
||||||
|
function f3(c) {
|
||||||
|
var a;
|
||||||
|
a = b(a / 2);
|
||||||
|
if (a < 0) {
|
||||||
|
a++;
|
||||||
|
++c;
|
||||||
|
return c / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f4(c) {
|
||||||
|
var a;
|
||||||
|
a = b(a / 2);
|
||||||
|
if (a < 0) {
|
||||||
|
a++;
|
||||||
|
c++;
|
||||||
|
return c / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
||||||
|
}
|
||||||
|
function f3(c) {
|
||||||
|
var a;
|
||||||
|
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||||
|
}
|
||||||
|
function f4(c) {
|
||||||
|
var a;
|
||||||
|
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
317
test/compress/issue-640.js
Normal file
317
test/compress/issue-640.js
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
cond_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
if (some_other_condition()) {
|
||||||
|
do_something();
|
||||||
|
} else {
|
||||||
|
alternate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alternate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (some_condition()) {
|
||||||
|
if (some_other_condition()) {
|
||||||
|
do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||||
|
if (some_condition() && some_other_condition()) do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation_regex: {
|
||||||
|
options = {
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
dead_code : true,
|
||||||
|
evaluate : true,
|
||||||
|
expression : true,
|
||||||
|
loops : true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
// @constraint this shouldn't be a constant
|
||||||
|
var CONST_FOO_ANN = false;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("reachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
if (CONST_FOO_ANN) console.log('reachable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_console_2: {
|
||||||
|
options = {
|
||||||
|
drop_console: true,
|
||||||
|
expression: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log('foo');
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// with regular compression these will be stripped out as well
|
||||||
|
void 0;
|
||||||
|
void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_value: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(1, [2, foo()], 3, {a:1, b:bar()});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
foo(), {a:1, b:bar()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wrongly_optimized: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
expression: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function func() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
if (func() || true) {
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function func() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
// TODO: optimize to `func(), bar()`
|
||||||
|
if (func(), !0) bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_1: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ stuff() })();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ stuff() })();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_4: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false), function(){
|
||||||
|
console.log("something");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||||
|
console.log("something");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
negate_iife: false,
|
||||||
|
sequences: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||||
|
console.log("something");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_true: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_nested: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()()()()();
|
||||||
|
}
|
||||||
|
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
pure_funcs: [ "pure" ],
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
pure(1 | a() ? 2 & b() : 7 ^ c());
|
||||||
|
pure(1 | a() ? 2 & b() : 5);
|
||||||
|
pure(1 | a() ? 4 : 7 ^ c());
|
||||||
|
pure(1 | a() ? 4 : 5);
|
||||||
|
pure(3 ? 2 & b() : 7 ^ c());
|
||||||
|
pure(3 ? 2 & b() : 5);
|
||||||
|
pure(3 ? 4 : 7 ^ c());
|
||||||
|
pure(3 ? 4 : 5);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1 | a() ? b() : c();
|
||||||
|
1 | a() && b();
|
||||||
|
1 | a() || c();
|
||||||
|
a();
|
||||||
|
3 ? b() : c();
|
||||||
|
3 && b();
|
||||||
|
3 || c();
|
||||||
|
pure(3 ? 4 : 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_1: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
sequences: 3,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a;
|
||||||
|
b;
|
||||||
|
c;
|
||||||
|
d;
|
||||||
|
e;
|
||||||
|
f;
|
||||||
|
g;
|
||||||
|
h;
|
||||||
|
i;
|
||||||
|
j;
|
||||||
|
k;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// Turned into a single return statement
|
||||||
|
// so it can no longer be split into lines
|
||||||
|
a,b,c,d,e,f,g,h,i,j,k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iife: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x = 42;
|
||||||
|
(function a() {})();
|
||||||
|
!function b() {}();
|
||||||
|
~function c() {}();
|
||||||
|
+function d() {}();
|
||||||
|
-function e() {}();
|
||||||
|
void function f() {}();
|
||||||
|
typeof function g() {}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||||
|
function d() {}(), function e() {}(), function f() {}(), typeof function g() {}();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -240,3 +240,159 @@ issue_1532: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_186: {
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x=3;if(foo())do{do{alert(x)}while(--x)}while(x);else bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_ie8: {
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_beautify: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x = 3;\n\nif (foo()) do {\n do {\n alert(x);\n } while (--x);\n} while (x); else bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_beautify_ie8: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_bracketize: {
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
bracketize: true,
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_bracketize_ie8: {
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
bracketize: true,
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_beautify_bracketize: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
bracketize: true,
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else {\n bar();\n}'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_186_beautify_bracketize_ie8: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
bracketize: true,
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
if (foo())
|
||||||
|
do
|
||||||
|
do
|
||||||
|
alert(x);
|
||||||
|
while (--x);
|
||||||
|
while (x);
|
||||||
|
else
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else {\n bar();\n}'
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,19 @@ negate_iife_2: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
negate_iife_2_side_effects: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return {} })().x = 10; // should not transform this one
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return {} })().x = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
negate_iife_3: {
|
negate_iife_3: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
@@ -45,6 +58,34 @@ negate_iife_3: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
negate_iife_3_evaluate: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3_side_effects: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
negate_iife: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
negate_iife_3_off: {
|
negate_iife_3_off: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: false,
|
negate_iife: false,
|
||||||
@@ -58,6 +99,20 @@ negate_iife_3_off: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
negate_iife_3_off_evaluate: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
negate_iife_4: {
|
negate_iife_4: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
@@ -320,3 +375,35 @@ issue_1288: {
|
|||||||
}(0);
|
}(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1288_side_effects: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
negate_iife: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (w) ;
|
||||||
|
else {
|
||||||
|
(function f() {})();
|
||||||
|
}
|
||||||
|
if (!x) {
|
||||||
|
(function() {
|
||||||
|
x = {};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
if (y)
|
||||||
|
(function() {})();
|
||||||
|
else
|
||||||
|
(function(z) {
|
||||||
|
return z;
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
w;
|
||||||
|
x || function() {
|
||||||
|
x = {};
|
||||||
|
}();
|
||||||
|
y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,3 +17,139 @@ hex_numbers_in_parentheses_for_prototype_functions: {
|
|||||||
}
|
}
|
||||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comparisons: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
~x === 42,
|
||||||
|
x % n === 42
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
42 == ~x,
|
||||||
|
x % n == 42
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
x + 1 + 2,
|
||||||
|
x * 1 * 2,
|
||||||
|
+x + 1 + 2,
|
||||||
|
1 + x + 2 + 3,
|
||||||
|
1 | x | 2 | 3,
|
||||||
|
1 + x-- + 2 + 3,
|
||||||
|
1 + (x*y + 2) + 3,
|
||||||
|
1 + (2 + x + 3),
|
||||||
|
1 + (2 + ~x + 3),
|
||||||
|
-y + (2 + ~x + 3),
|
||||||
|
1 & (2 & x & 3),
|
||||||
|
1 + (2 + (x |= 0) + 3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
x + 1 + 2,
|
||||||
|
1 * x * 2,
|
||||||
|
+x + 1 + 2,
|
||||||
|
1 + x + 2 + 3,
|
||||||
|
3 | x,
|
||||||
|
1 + x-- + 2 + 3,
|
||||||
|
x*y + 2 + 1 + 3,
|
||||||
|
1 + (2 + x + 3),
|
||||||
|
2 + ~x + 3 + 1,
|
||||||
|
-y + (2 + ~x + 3),
|
||||||
|
0 & x,
|
||||||
|
2 + (x |= 0) + 3 + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
x + 1 + 2,
|
||||||
|
x * 1 * 2,
|
||||||
|
+x + 1 + 2,
|
||||||
|
1 + x + 2 + 3,
|
||||||
|
1 | x | 2 | 3,
|
||||||
|
1 + x-- + 2 + 3,
|
||||||
|
1 + (x*y + 2) + 3,
|
||||||
|
1 + (2 + x + 3),
|
||||||
|
1 & (2 & x & 3),
|
||||||
|
1 + (2 + (x |= 0) + 3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
x + 1 + 2,
|
||||||
|
2 * x,
|
||||||
|
3 + +x,
|
||||||
|
1 + x + 2 + 3,
|
||||||
|
3 | x,
|
||||||
|
6 + x--,
|
||||||
|
6 + x*y,
|
||||||
|
1 + (2 + x + 3),
|
||||||
|
0 & x,
|
||||||
|
6 + (x |= 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(1 + Number(x) + 2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(3 + +x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
1+ +a,
|
||||||
|
+a+1,
|
||||||
|
1+-a,
|
||||||
|
-a+1,
|
||||||
|
+a+ +b,
|
||||||
|
+a+-b,
|
||||||
|
-a+ +b,
|
||||||
|
-a+-b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
+a+1,
|
||||||
|
+a+1,
|
||||||
|
1-a,
|
||||||
|
1-a,
|
||||||
|
+a+ +b,
|
||||||
|
+a-b,
|
||||||
|
-a+ +b,
|
||||||
|
-a-b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ reduce_vars: {
|
|||||||
C : 0
|
C : 0
|
||||||
},
|
},
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
|
toplevel : true,
|
||||||
unused : true
|
unused : true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -452,22 +453,26 @@ multi_def_2: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
if (code == 16)
|
function f(){
|
||||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
if (code == 16)
|
||||||
else if (code == 17)
|
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
else if (code == 17)
|
||||||
else if (code == 18)
|
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
else if (code == 18)
|
||||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||||
|
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
if (16 == code)
|
function f(){
|
||||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
if (16 == code)
|
||||||
else if (17 == code)
|
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
else if (17 == code)
|
||||||
else if (18 == code)
|
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
else if (18 == code)
|
||||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||||
|
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,12 +482,16 @@ use_before_var: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(t);
|
function f(){
|
||||||
var t = 1;
|
console.log(t);
|
||||||
|
var t = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(t);
|
function f(){
|
||||||
var t = 1;
|
console.log(t);
|
||||||
|
var t = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,22 +501,20 @@ inner_var_if: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(){
|
function f(a){
|
||||||
return 0;
|
if (a)
|
||||||
|
var t = 1;
|
||||||
|
if (!t)
|
||||||
|
console.log(t);
|
||||||
}
|
}
|
||||||
if (f())
|
|
||||||
var t = 1;
|
|
||||||
if (!t)
|
|
||||||
console.log(t);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(){
|
function f(a){
|
||||||
return 0;
|
if (a)
|
||||||
|
var t = 1;
|
||||||
|
if (!t)
|
||||||
|
console.log(t);
|
||||||
}
|
}
|
||||||
if (f())
|
|
||||||
var t = 1;
|
|
||||||
if (!t)
|
|
||||||
console.log(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,24 +524,22 @@ inner_var_label: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(){
|
function f(a){
|
||||||
return 1;
|
l: {
|
||||||
|
if (a) break l;
|
||||||
|
var t = 1;
|
||||||
|
}
|
||||||
|
console.log(t);
|
||||||
}
|
}
|
||||||
l: {
|
|
||||||
if (f()) break l;
|
|
||||||
var t = 1;
|
|
||||||
}
|
|
||||||
console.log(t);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(){
|
function f(a){
|
||||||
return 1;
|
l: {
|
||||||
|
if (a) break l;
|
||||||
|
var t = 1;
|
||||||
|
}
|
||||||
|
console.log(t);
|
||||||
}
|
}
|
||||||
l: {
|
|
||||||
if (f()) break l;
|
|
||||||
var t = 1;
|
|
||||||
}
|
|
||||||
console.log(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,22 +549,26 @@ inner_var_for: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
function f() {
|
||||||
x(a, b, d);
|
var a = 1;
|
||||||
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
|
x(a, b, d);
|
||||||
var d = 4, e = 5;
|
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
|
||||||
|
var d = 4, e = 5;
|
||||||
|
x(a, b, c, d, e);
|
||||||
|
}
|
||||||
x(a, b, c, d, e);
|
x(a, b, c, d, e);
|
||||||
}
|
}
|
||||||
x(a, b, c, d, e)
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
function f() {
|
||||||
x(1, b, d);
|
var a = 1;
|
||||||
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
|
x(1, b, d);
|
||||||
var d = 4, e = 5;
|
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
|
||||||
|
var d = 4, e = 5;
|
||||||
|
x(1, b, 3, d, e);
|
||||||
|
}
|
||||||
x(1, b, 3, d, e);
|
x(1, b, 3, d, e);
|
||||||
}
|
}
|
||||||
x(1, b, 3, d, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,24 +578,28 @@ inner_var_for_in_1: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1, b = 2;
|
function f() {
|
||||||
for (b in (function() {
|
var a = 1, b = 2;
|
||||||
return x(a, b, c);
|
for (b in (function() {
|
||||||
})()) {
|
return x(a, b, c);
|
||||||
var c = 3, d = 4;
|
})()) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(a, b, c, d);
|
||||||
|
}
|
||||||
x(a, b, c, d);
|
x(a, b, c, d);
|
||||||
}
|
}
|
||||||
x(a, b, c, d);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1, b = 2;
|
function f() {
|
||||||
for (b in (function() {
|
var a = 1, b = 2;
|
||||||
return x(1, b, c);
|
for (b in (function() {
|
||||||
})()) {
|
return x(1, b, c);
|
||||||
var c = 3, d = 4;
|
})()) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(1, b, c, d);
|
||||||
|
}
|
||||||
x(1, b, c, d);
|
x(1, b, c, d);
|
||||||
}
|
}
|
||||||
x(1, b, c, d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,12 +609,43 @@ inner_var_for_in_2: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
for (var long_name in {})
|
function f() {
|
||||||
console.log(long_name);
|
for (var long_name in {})
|
||||||
|
console.log(long_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (var long_name in {})
|
function f() {
|
||||||
console.log(long_name);
|
for (var long_name in {})
|
||||||
|
console.log(long_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_var_catch: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
a();
|
||||||
|
} catch (e) {
|
||||||
|
var b = 1;
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
a();
|
||||||
|
} catch (e) {
|
||||||
|
var b = 1;
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,14 +655,18 @@ issue_1533_1: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var id = "";
|
function f() {
|
||||||
for (id in {break: "me"})
|
var id = "";
|
||||||
console.log(id);
|
for (id in {break: "me"})
|
||||||
|
console.log(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var id = "";
|
function f() {
|
||||||
for (id in {break: "me"})
|
var id = "";
|
||||||
console.log(id);
|
for (id in {break: "me"})
|
||||||
|
console.log(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,15 +676,471 @@ issue_1533_2: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var id = "";
|
function f() {
|
||||||
for (var id in {break: "me"})
|
var id = "";
|
||||||
|
for (var id in {break: "me"})
|
||||||
|
console.log(id);
|
||||||
console.log(id);
|
console.log(id);
|
||||||
console.log(id);
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var id = "";
|
function f() {
|
||||||
for (var id in {break: "me"})
|
var id = "";
|
||||||
|
for (var id in {break: "me"})
|
||||||
|
console.log(id);
|
||||||
console.log(id);
|
console.log(id);
|
||||||
console.log(id);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_on: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_off: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 3;
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_on_loops_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:", --x);
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
(function() {
|
||||||
|
console.log("bar:", --x);
|
||||||
|
})();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_off_loops_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:", --x);
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:", --x);
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_on_loops_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:");
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (;;) (function() {
|
||||||
|
console.log("bar:");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_off_loops_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:");
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function bar() {
|
||||||
|
console.log("bar:");
|
||||||
|
}
|
||||||
|
var x = 3;
|
||||||
|
do
|
||||||
|
bar();
|
||||||
|
while (x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_on_loops_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
while (x) bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (;;) bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_off_loops_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel:false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 3;
|
||||||
|
while (x) bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 3;
|
||||||
|
for (;x;) bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_reference: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
x();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
var a = h();
|
||||||
|
var b = 2;
|
||||||
|
return a + b;
|
||||||
|
function h() {
|
||||||
|
y();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
x();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
var a = h();
|
||||||
|
var b = 2;
|
||||||
|
return a + b;
|
||||||
|
function h() {
|
||||||
|
y();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_inline_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g(2) + h();
|
||||||
|
function g(b) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
return h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return function(b) {
|
||||||
|
return b;
|
||||||
|
}(2) + h();
|
||||||
|
function h() {
|
||||||
|
return h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_inline_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g(b) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
return h();
|
||||||
|
}
|
||||||
|
return g(2) + h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function h() {
|
||||||
|
return h();
|
||||||
|
}
|
||||||
|
return function(b) {
|
||||||
|
return b;
|
||||||
|
}(2) + h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_inline_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g(2);
|
||||||
|
function g(b) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_call: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g() + h(1) - h(g(), 2, 3);
|
||||||
|
function g() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
function h(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return 4 + h(1) - h(4);
|
||||||
|
function h(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_redefine: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
g = function() {
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
return g() + h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g = function() {
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
return g() + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func_inline: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var g = function() {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
console.log(g() + h());
|
||||||
|
var h = function() {
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log(1 + h());
|
||||||
|
var h = function() {
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func_modified: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
function a() { return 1; }
|
||||||
|
function b() { return 2; }
|
||||||
|
function c() { return 3; }
|
||||||
|
b.inject = [];
|
||||||
|
c = function() { return 4; };
|
||||||
|
return a() + b() + c();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
function b() { return 2; }
|
||||||
|
function c() { return 3; }
|
||||||
|
b.inject = [];
|
||||||
|
c = function() { return 4; };
|
||||||
|
return 1 + 2 + c();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_label: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
function f(a) {
|
||||||
|
L: {
|
||||||
|
if (a) break L;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f(2));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
console.log(function(a) {
|
||||||
|
L: {
|
||||||
|
if (a) break L;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}(2));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double_reference: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var g = function g() {
|
||||||
|
g();
|
||||||
|
};
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
(function g() {
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,26 @@ dont_screw: {
|
|||||||
expect_exact: 'f("\\x0B");';
|
expect_exact: 'f("\\x0B");';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_screw_constants: {
|
||||||
|
options = {
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f(undefined, Infinity);
|
||||||
|
}
|
||||||
|
expect_exact: "f(void 0,1/0);"
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_screw_constants: {
|
||||||
|
options = {
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f(undefined, Infinity);
|
||||||
|
}
|
||||||
|
expect_exact: "f(undefined,Infinity);"
|
||||||
|
}
|
||||||
|
|
||||||
do_screw_try_catch: {
|
do_screw_try_catch: {
|
||||||
options = { screw_ie8: true };
|
options = { screw_ie8: true };
|
||||||
mangle = { screw_ie8: true };
|
mangle = { screw_ie8: true };
|
||||||
@@ -46,8 +66,6 @@ do_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch: {
|
dont_screw_try_catch: {
|
||||||
// This test is known to generate incorrect code for screw_ie8=false.
|
|
||||||
// Update expected result in the event this bug is ever fixed.
|
|
||||||
options = { screw_ie8: false };
|
options = { screw_ie8: false };
|
||||||
mangle = { screw_ie8: false };
|
mangle = { screw_ie8: false };
|
||||||
beautify = { screw_ie8: false };
|
beautify = { screw_ie8: false };
|
||||||
@@ -64,11 +82,11 @@ dont_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
bad = function(n){
|
bad = function(n){
|
||||||
return function(n){
|
return function(t){
|
||||||
try{
|
try{
|
||||||
t()
|
n()
|
||||||
} catch(t) {
|
} catch(n) {
|
||||||
n(t)
|
t(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -104,8 +122,6 @@ do_screw_try_catch_undefined: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch_undefined: {
|
dont_screw_try_catch_undefined: {
|
||||||
// This test is known to generate incorrect code for screw_ie8=false.
|
|
||||||
// Update expected result in the event this bug is ever fixed.
|
|
||||||
options = { screw_ie8: false };
|
options = { screw_ie8: false };
|
||||||
mangle = { screw_ie8: false };
|
mangle = { screw_ie8: false };
|
||||||
beautify = { screw_ie8: false };
|
beautify = { screw_ie8: false };
|
||||||
@@ -121,14 +137,48 @@ dont_screw_try_catch_undefined: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a(o){
|
function a(n){
|
||||||
try{
|
try{
|
||||||
throw "Stuff"
|
throw "Stuff"
|
||||||
} catch (n) {
|
} catch (undefined) {
|
||||||
console.log("caught: "+n)
|
console.log("caught: " + undefined)
|
||||||
}
|
}
|
||||||
console.log("undefined is " + n);
|
console.log("undefined is " + undefined);
|
||||||
return o === n
|
return n === undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
screw_ie8: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
alert(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var t;
|
||||||
|
try {
|
||||||
|
x();
|
||||||
|
} catch (t) {
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
alert(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,6 +248,39 @@ iife: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||||
function d() {}(), function e() {}(), function f() {}(), function g() {}()
|
function d() {}(), function e() {}(), function f() {}(), function g() {}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_undefined: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(undefined) {
|
||||||
|
if (a)
|
||||||
|
return b;
|
||||||
|
if (c)
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
function g(undefined) {
|
||||||
|
if (a)
|
||||||
|
return b;
|
||||||
|
if (c)
|
||||||
|
return d;
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(undefined) {
|
||||||
|
return a ? b : c ? d : undefined;
|
||||||
|
}
|
||||||
|
function g(undefined) {
|
||||||
|
return a ? b : c ? d : void e();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --keep-fnames (mangle & compress)", function (done) {
|
it("Should work with --keep-fnames (mangle & compress)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|||||||
@@ -72,4 +72,12 @@ describe("comment filters", function() {
|
|||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should handle shebang and preamble correctly", function() {
|
||||||
|
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||||
|
fromString: true,
|
||||||
|
output: { preamble: "/* Build */" }
|
||||||
|
}).code;
|
||||||
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,17 +3,13 @@ var assert = require("assert");
|
|||||||
|
|
||||||
describe("minify() with input file globs", function() {
|
describe("minify() with input file globs", function() {
|
||||||
it("minify() with one input file glob string.", function() {
|
it("minify() with one input file glob string.", function() {
|
||||||
var result = Uglify.minify("test/input/issue-1242/foo.*", {
|
var result = Uglify.minify("test/input/issue-1242/foo.*");
|
||||||
compress: { collapse_vars: true }
|
|
||||||
});
|
|
||||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
||||||
});
|
});
|
||||||
it("minify() with an array of one input file glob.", function() {
|
it("minify() with an array of one input file glob.", function() {
|
||||||
var result = Uglify.minify([
|
var result = Uglify.minify([
|
||||||
"test/input/issue-1242/b*.es5",
|
"test/input/issue-1242/b*.es5",
|
||||||
], {
|
]);
|
||||||
compress: { collapse_vars: true }
|
|
||||||
});
|
|
||||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
||||||
});
|
});
|
||||||
it("minify() with an array of multiple input file globs.", function() {
|
it("minify() with an array of multiple input file globs.", function() {
|
||||||
@@ -21,8 +17,8 @@ describe("minify() with input file globs", function() {
|
|||||||
"test/input/issue-1242/???.es5",
|
"test/input/issue-1242/???.es5",
|
||||||
"test/input/issue-1242/*.js",
|
"test/input/issue-1242/*.js",
|
||||||
], {
|
], {
|
||||||
compress: { collapse_vars: true }
|
compress: { toplevel: true }
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}function foo(n){print("Foo:",2*n)}var print=console.log.bind(console);print("qux",bar(3),baz(12)),foo(11);');
|
assert.strictEqual(result.code, 'var print=console.log.bind(console);print("qux",function(n){return 3*n}(3),function(n){return n/2}(12)),function(n){print("Foo:",2*n)}(11);');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
54
test/mocha/release.js
Normal file
54
test/mocha/release.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var spawn = require("child_process").spawn;
|
||||||
|
|
||||||
|
if (!process.env.UGLIFYJS_TEST_ALL) return;
|
||||||
|
|
||||||
|
function run(command, args, done) {
|
||||||
|
var id = setInterval(function() {
|
||||||
|
process.stdout.write("\0");
|
||||||
|
}, 5 * 60 * 1000);
|
||||||
|
spawn(command, args, {
|
||||||
|
stdio: "ignore"
|
||||||
|
}).on("exit", function(code) {
|
||||||
|
clearInterval(id);
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("test/benchmark.js", function() {
|
||||||
|
this.timeout(5 * 60 * 1000);
|
||||||
|
[
|
||||||
|
"-b",
|
||||||
|
"-b bracketize",
|
||||||
|
"-m",
|
||||||
|
"-mc passes=3",
|
||||||
|
"-mc passes=3,toplevel",
|
||||||
|
"-mc passes=3,unsafe",
|
||||||
|
"-mc keep_fargs=false,passes=3",
|
||||||
|
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||||
|
].forEach(function(options) {
|
||||||
|
it("Should pass with options " + options, function(done) {
|
||||||
|
var args = options.split(/ /);
|
||||||
|
args.unshift("test/benchmark.js");
|
||||||
|
run(process.argv[0], args, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("test/jetstream.js", function() {
|
||||||
|
this.timeout(20 * 60 * 1000);
|
||||||
|
it("Should install phantomjs-prebuilt", function(done) {
|
||||||
|
run("npm", ["install", "phantomjs-prebuilt@2.1.14"], done);
|
||||||
|
});
|
||||||
|
[
|
||||||
|
"-mc warnings=false",
|
||||||
|
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto,warnings=false",
|
||||||
|
].forEach(function(options) {
|
||||||
|
it("Should pass with options " + options, function(done) {
|
||||||
|
var args = options.split(/ /);
|
||||||
|
args.unshift("test/jetstream.js");
|
||||||
|
run(process.argv[0], args, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user