Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0af80eca22 | ||
|
|
23876a84a5 | ||
|
|
092d0275a0 | ||
|
|
06296bee7f | ||
|
|
3818a9e9c1 | ||
|
|
75e2748b16 | ||
|
|
a7c987ad2b | ||
|
|
957c54bc87 | ||
|
|
4cbf5a7821 | ||
|
|
93d4224072 | ||
|
|
6cd580dc23 | ||
|
|
ecb63ad8bc | ||
|
|
1ca43bcca1 | ||
|
|
3ee1464aa4 | ||
|
|
24967b8be8 | ||
|
|
a8c67ea353 | ||
|
|
d0b0aecfc5 | ||
|
|
9f5a6029a3 | ||
|
|
4027a0c962 | ||
|
|
87f8a484e6 | ||
|
|
c736834aa4 | ||
|
|
9a98513981 | ||
|
|
f631d6437a | ||
|
|
aa7e8783f8 | ||
|
|
13e5e33448 | ||
|
|
487ae8e3be | ||
|
|
5dfda6e212 | ||
|
|
d08c772eb3 | ||
|
|
90ed54401b | ||
|
|
d8106b6c63 | ||
|
|
dda4eb96e1 | ||
|
|
7305ba0296 | ||
|
|
2c21dc5e8e | ||
|
|
d0faa471db | ||
|
|
6ad823d1e8 | ||
|
|
43ad4e9775 |
25
.github/ISSUE_TEMPLATE.md
vendored
25
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,20 +1,9 @@
|
||||
**Bug report or feature request?**
|
||||
|
||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||
|
||||
**ES5 or ES6+ input?**
|
||||
|
||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||
|
||||
**Uglify version (`uglifyjs -V`)**
|
||||
|
||||
**JavaScript input** <!-- ideally as small as possible -->
|
||||
|
||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||
|
||||
**JavaScript output or error produced.**
|
||||
|
||||
- Bug report or feature request? <!-- Note: sub-optimal but correct code is not a bug -->
|
||||
- `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: `uglify-js` only supports ES5.
|
||||
Those wishing to minify ES6 should use `uglify-es`.
|
||||
Note: the release version of uglify-js only supports ES5. Those wishing
|
||||
to minify ES6 should use the experimental harmony branch.
|
||||
-->
|
||||
|
||||
@@ -4,11 +4,8 @@ node_js:
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "8"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
cache:
|
||||
directories: tmp
|
||||
|
||||
77
bin/extract-props.js
Executable file
77
bin/extract-props.js
Executable file
@@ -0,0 +1,77 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
var U2 = require("../tools/node");
|
||||
var fs = require("fs");
|
||||
var yargs = require("yargs");
|
||||
var ARGS = yargs
|
||||
.describe("o", "Output file")
|
||||
.argv;
|
||||
var files = ARGS._.slice();
|
||||
var output = {
|
||||
vars: {},
|
||||
props: {}
|
||||
};
|
||||
|
||||
if (ARGS.o) try {
|
||||
output = JSON.parse(fs.readFileSync(ARGS.o, "utf8"));
|
||||
} catch(ex) {}
|
||||
|
||||
files.forEach(getProps);
|
||||
|
||||
if (ARGS.o) {
|
||||
fs.writeFileSync(ARGS.o, JSON.stringify(output, null, 2), "utf8");
|
||||
} else {
|
||||
console.log("%s", JSON.stringify(output, null, 2));
|
||||
}
|
||||
|
||||
function getProps(filename) {
|
||||
var code = fs.readFileSync(filename, "utf8");
|
||||
var ast = U2.parse(code);
|
||||
|
||||
ast.walk(new U2.TreeWalker(function(node){
|
||||
if (node instanceof U2.AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
}
|
||||
else if (node instanceof U2.AST_ObjectProperty) {
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof U2.AST_Dot) {
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof U2.AST_Sub) {
|
||||
addStrings(node.property);
|
||||
}
|
||||
}));
|
||||
|
||||
function addStrings(node) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
node.walk(new U2.TreeWalker(function(node){
|
||||
if (node instanceof U2.AST_Seq) {
|
||||
walk(node.cdr);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U2.AST_String) {
|
||||
add(node.value);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U2.AST_Conditional) {
|
||||
walk(node.consequent);
|
||||
walk(node.alternative);
|
||||
return true;
|
||||
}
|
||||
throw out;
|
||||
}));
|
||||
})(node);
|
||||
} catch(ex) {
|
||||
if (ex !== out) throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
output.props[name] = true;
|
||||
}
|
||||
}
|
||||
972
bin/uglifyjs
972
bin/uglifyjs
File diff suppressed because it is too large
Load Diff
153
lib/ast.js
153
lib/ast.js
@@ -182,13 +182,21 @@ var AST_BlockStatement = DEFNODE("BlockStatement", null, {
|
||||
}, AST_Block);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this);
|
||||
}
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
||||
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -318,13 +326,62 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
$propdoc: {
|
||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||
},
|
||||
wrap_commonjs: function(name) {
|
||||
var body = this.body;
|
||||
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||
wrap_enclose: function(arg_parameter_pairs) {
|
||||
var self = this;
|
||||
var args = [];
|
||||
var parameters = [];
|
||||
|
||||
arg_parameter_pairs.forEach(function(pair) {
|
||||
var splitAt = pair.lastIndexOf(":");
|
||||
|
||||
args.push(pair.substr(0, splitAt));
|
||||
parameters.push(pair.substr(splitAt + 1));
|
||||
});
|
||||
|
||||
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(body);
|
||||
return MAP.splice(self.body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
},
|
||||
wrap_commonjs: function(name, export_all) {
|
||||
var self = this;
|
||||
var to_export = [];
|
||||
if (export_all) {
|
||||
self.figure_out_scope();
|
||||
self.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
||||
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
||||
to_export.push(node);
|
||||
}
|
||||
}));
|
||||
}
|
||||
var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive) {
|
||||
switch (node.value) {
|
||||
case "$ORIG":
|
||||
return MAP.splice(self.body);
|
||||
case "$EXPORTS":
|
||||
var body = [];
|
||||
to_export.forEach(function(sym){
|
||||
body.push(new AST_SimpleStatement({
|
||||
body: new AST_Assign({
|
||||
left: new AST_Sub({
|
||||
expression: new AST_SymbolRef({ name: "exports" }),
|
||||
property: new AST_String({ value: sym.name }),
|
||||
}),
|
||||
operator: "=",
|
||||
right: new AST_SymbolRef(sym),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
@@ -495,10 +552,10 @@ var AST_Finally = DEFNODE("Finally", null, {
|
||||
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||
}, AST_Block);
|
||||
|
||||
/* -----[ VAR ]----- */
|
||||
/* -----[ VAR/CONST ]----- */
|
||||
|
||||
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
$documentation: "Base class for `var` nodes (variable declarations/initializations)",
|
||||
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
@@ -516,10 +573,14 @@ var AST_Var = DEFNODE("Var", null, {
|
||||
$documentation: "A `var` statement"
|
||||
}, AST_Definitions);
|
||||
|
||||
var AST_Const = DEFNODE("Const", null, {
|
||||
$documentation: "A `const` statement"
|
||||
}, AST_Definitions);
|
||||
|
||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolVar] name of the variable",
|
||||
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
@@ -540,11 +601,11 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.expression._walk(visitor);
|
||||
var args = this.args;
|
||||
for (var i = 0, len = args.length; i < len; i++) {
|
||||
args[i]._walk(visitor);
|
||||
}
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -553,16 +614,68 @@ var AST_New = DEFNODE("New", null, {
|
||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
||||
}, AST_Call);
|
||||
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
var AST_Seq = DEFNODE("Seq", "car cdr", {
|
||||
$documentation: "A sequence expression (two comma-separated expressions)",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
car: "[AST_Node] first element in sequence",
|
||||
cdr: "[AST_Node] second element in sequence"
|
||||
},
|
||||
$cons: function(x, y) {
|
||||
var seq = new AST_Seq(x);
|
||||
seq.car = x;
|
||||
seq.cdr = y;
|
||||
return seq;
|
||||
},
|
||||
$from_array: function(array) {
|
||||
if (array.length == 0) return null;
|
||||
if (array.length == 1) return array[0].clone();
|
||||
var list = null;
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
list = AST_Seq.cons(array[i], list);
|
||||
}
|
||||
var p = list;
|
||||
while (p) {
|
||||
if (p.cdr && !p.cdr.cdr) {
|
||||
p.cdr = p.cdr.car;
|
||||
break;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
return list;
|
||||
},
|
||||
to_array: function() {
|
||||
var p = this, a = [];
|
||||
while (p) {
|
||||
a.push(p.car);
|
||||
if (p.cdr && !(p.cdr instanceof AST_Seq)) {
|
||||
a.push(p.cdr);
|
||||
break;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
return a;
|
||||
},
|
||||
add: function(node) {
|
||||
var p = this;
|
||||
while (p) {
|
||||
if (!(p.cdr instanceof AST_Seq)) {
|
||||
var cell = AST_Seq.cons(p.cdr, node);
|
||||
return p.cdr = cell;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
},
|
||||
len: function() {
|
||||
if (this.cdr instanceof AST_Seq) {
|
||||
return this.cdr.len() + 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.expressions.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
this.car._walk(visitor);
|
||||
if (this.cdr) this.cdr._walk(visitor);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -615,7 +728,7 @@ var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||
}, AST_Unary);
|
||||
|
||||
var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
||||
$documentation: "Binary expression, i.e. `a + b`",
|
||||
$propdoc: {
|
||||
left: "[AST_Node] left-hand side expression",
|
||||
@@ -724,13 +837,17 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||
$documentation: "A declaration symbol (symbol in var, function name or argument, symbol in catch)",
|
||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||
$documentation: "Symbol defining a variable",
|
||||
}, AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
$documentation: "A constant declaration"
|
||||
}, AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||
$documentation: "Symbol naming a function argument",
|
||||
}, AST_SymbolVar);
|
||||
@@ -865,7 +982,7 @@ TreeWalker.prototype = {
|
||||
parent: function(n) {
|
||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||
},
|
||||
push: function(node) {
|
||||
push: function (node) {
|
||||
if (node instanceof AST_Lambda) {
|
||||
this.directives = Object.create(this.directives);
|
||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||
|
||||
2194
lib/compress.js
2194
lib/compress.js
File diff suppressed because it is too large
Load Diff
211
lib/minify.js
211
lib/minify.js
@@ -1,211 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
||||
return new Buffer(b64, "base64").toString();
|
||||
} : atob;
|
||||
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||
return new Buffer(str).toString("base64");
|
||||
} : btoa;
|
||||
|
||||
function read_source_map(code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
AST_Node.warn("inline source map not found");
|
||||
return null;
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
if (options[name]) {
|
||||
keys.forEach(function(key) {
|
||||
if (options[key]) {
|
||||
if (typeof options[key] != "object") options[key] = {};
|
||||
if (!(name in options[key])) options[key][name] = options[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init_cache(cache) {
|
||||
if (!cache) return;
|
||||
if (!("cname" in cache)) cache.cname = -1;
|
||||
if (!("props" in cache)) {
|
||||
cache.props = new Dictionary();
|
||||
} else if (!(cache.props instanceof Dictionary)) {
|
||||
cache.props = Dictionary.fromObject(cache.props);
|
||||
}
|
||||
}
|
||||
|
||||
function to_json(cache) {
|
||||
return {
|
||||
cname: cache.cname,
|
||||
props: cache.props.toObject()
|
||||
};
|
||||
}
|
||||
|
||||
function minify(files, options) {
|
||||
var warn_function = AST_Node.warn_function;
|
||||
try {
|
||||
options = defaults(options, {
|
||||
compress: {},
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
warnings: false,
|
||||
wrap: false,
|
||||
}, true);
|
||||
var timings = options.timings && {
|
||||
start: Date.now()
|
||||
};
|
||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("warnings", options, [ "compress" ]);
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
eval: false,
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
toplevel: false,
|
||||
}, true);
|
||||
if (options.nameCache && options.mangle.properties) {
|
||||
if (typeof options.mangle.properties != "object") {
|
||||
options.mangle.properties = {};
|
||||
}
|
||||
if (!("cache" in options.mangle.properties)) {
|
||||
options.mangle.properties.cache = options.nameCache.props || {};
|
||||
}
|
||||
}
|
||||
init_cache(options.mangle.cache);
|
||||
init_cache(options.mangle.properties.cache);
|
||||
}
|
||||
if (options.sourceMap) {
|
||||
options.sourceMap = defaults(options.sourceMap, {
|
||||
content: null,
|
||||
filename: null,
|
||||
includeSources: false,
|
||||
root: null,
|
||||
url: null,
|
||||
}, true);
|
||||
}
|
||||
var warnings = [];
|
||||
if (options.warnings && !AST_Node.warn_function) {
|
||||
AST_Node.warn_function = function(warning) {
|
||||
warnings.push(warning);
|
||||
};
|
||||
}
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
if (Object.keys(files).length > 1)
|
||||
throw new Error("inline source map only works with singular input");
|
||||
options.sourceMap.content = read_source_map(files[name]);
|
||||
}
|
||||
}
|
||||
toplevel = options.parse.toplevel;
|
||||
}
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (timings) timings.scope1 = Date.now();
|
||||
if (options.compress) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
if (timings) timings.scope2 = Date.now();
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
if (options.mangle) {
|
||||
base54.reset();
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||
}
|
||||
if (timings) timings.output = Date.now();
|
||||
var result = {};
|
||||
if (options.output.ast) {
|
||||
result.ast = toplevel;
|
||||
}
|
||||
if (!HOP(options.output, "code") || options.output.code) {
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||
}
|
||||
options.output.source_map = SourceMap({
|
||||
file: options.sourceMap.filename,
|
||||
orig: options.sourceMap.content,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
if (files instanceof AST_Toplevel) {
|
||||
throw new Error("original source content unavailable");
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete options.output.ast;
|
||||
delete options.output.code;
|
||||
var stream = OutputStream(options.output);
|
||||
toplevel.print(stream);
|
||||
result.code = stream.get();
|
||||
if (options.sourceMap) {
|
||||
result.map = options.output.source_map.toString();
|
||||
if (options.sourceMap.url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.nameCache && options.mangle) {
|
||||
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
||||
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||
options.nameCache.props = to_json(options.mangle.properties.cache);
|
||||
}
|
||||
}
|
||||
if (timings) {
|
||||
timings.end = Date.now();
|
||||
result.timings = {
|
||||
parse: 1e-3 * (timings.scope1 - timings.parse),
|
||||
scope: 1e-3 * (timings.compress - timings.scope1 + timings.mangle - timings.scope2),
|
||||
compress: 1e-3 * (timings.scope2 - timings.compress),
|
||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||
properties: 1e-3 * (timings.output - timings.properties),
|
||||
output: 1e-3 * (timings.end - timings.output),
|
||||
total: 1e-3 * (timings.end - timings.start)
|
||||
}
|
||||
}
|
||||
if (warnings.length) {
|
||||
result.warnings = warnings;
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
return { error: ex };
|
||||
} finally {
|
||||
AST_Node.warn_function = warn_function;
|
||||
}
|
||||
}
|
||||
@@ -145,11 +145,7 @@
|
||||
});
|
||||
},
|
||||
SequenceExpression: function(M) {
|
||||
return new AST_Sequence({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
expressions: M.expressions.map(from_moz)
|
||||
});
|
||||
return AST_Seq.from_array(M.expressions.map(from_moz));
|
||||
},
|
||||
MemberExpression: function(M) {
|
||||
return new (M.computed ? AST_Sub : AST_Dot)({
|
||||
@@ -168,7 +164,7 @@
|
||||
});
|
||||
},
|
||||
VariableDeclaration: function(M) {
|
||||
return new AST_Var({
|
||||
return new (M.kind === "const" ? AST_Const : AST_Var)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
definitions : M.declarations.map(from_moz)
|
||||
@@ -204,7 +200,7 @@
|
||||
Identifier: function(M) {
|
||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||
return new ( p.type == "LabeledStatement" ? AST_Label
|
||||
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
|
||||
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
||||
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||
@@ -324,15 +320,15 @@
|
||||
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
||||
return {
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
kind: M instanceof AST_Const ? "const" : "var",
|
||||
declarations: M.definitions.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
|
||||
def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) {
|
||||
return {
|
||||
type: "SequenceExpression",
|
||||
expressions: M.expressions.map(to_moz)
|
||||
expressions: M.to_array().map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
159
lib/output.js
159
lib/output.js
@@ -57,7 +57,6 @@ function OutputStream(options) {
|
||||
beautify : false,
|
||||
bracketize : false,
|
||||
comments : false,
|
||||
ie8 : false,
|
||||
indent_level : 4,
|
||||
indent_start : 0,
|
||||
inline_script : true,
|
||||
@@ -67,10 +66,12 @@ function OutputStream(options) {
|
||||
preserve_line : false,
|
||||
quote_keys : false,
|
||||
quote_style : 0,
|
||||
screw_ie8 : true,
|
||||
semicolons : true,
|
||||
shebang : true,
|
||||
source_map : null,
|
||||
webkit : false,
|
||||
space_colon : true,
|
||||
unescape_regexps : false,
|
||||
width : 80,
|
||||
wrap_iife : false,
|
||||
}, true);
|
||||
@@ -135,7 +136,7 @@ function OutputStream(options) {
|
||||
case "\t": return "\\t";
|
||||
case "\b": return "\\b";
|
||||
case "\f": return "\\f";
|
||||
case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
|
||||
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
case "\ufeff": return "\\ufeff";
|
||||
@@ -190,43 +191,12 @@ function OutputStream(options) {
|
||||
var might_need_semicolon = false;
|
||||
var might_add_newline = 0;
|
||||
var last = "";
|
||||
var mapping_token, mapping_name, mappings = options.source_map && [];
|
||||
|
||||
var do_add_mapping = mappings ? function() {
|
||||
mappings.forEach(function(mapping) {
|
||||
try {
|
||||
options.source_map.add(
|
||||
mapping.token.file,
|
||||
mapping.line, mapping.col,
|
||||
mapping.token.line, mapping.token.col,
|
||||
!mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
|
||||
);
|
||||
} catch(ex) {
|
||||
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||
file: mapping.token.file,
|
||||
line: mapping.token.line,
|
||||
col: mapping.token.col,
|
||||
cline: mapping.line,
|
||||
ccol: mapping.col,
|
||||
name: mapping.name || ""
|
||||
})
|
||||
}
|
||||
});
|
||||
mappings = [];
|
||||
} : noop;
|
||||
|
||||
var ensure_line_len = options.max_line_len ? function() {
|
||||
if (current_col > options.max_line_len) {
|
||||
if (might_add_newline) {
|
||||
var left = OUTPUT.slice(0, might_add_newline);
|
||||
var right = OUTPUT.slice(might_add_newline);
|
||||
if (mappings) {
|
||||
var delta = right.length - current_col;
|
||||
mappings.forEach(function(mapping) {
|
||||
mapping.line++;
|
||||
mapping.col += delta;
|
||||
});
|
||||
}
|
||||
OUTPUT = left + "\n" + right;
|
||||
current_line++;
|
||||
current_pos++;
|
||||
@@ -236,10 +206,7 @@ function OutputStream(options) {
|
||||
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
||||
}
|
||||
}
|
||||
if (might_add_newline) {
|
||||
might_add_newline = 0;
|
||||
do_add_mapping();
|
||||
}
|
||||
might_add_newline = 0;
|
||||
} : noop;
|
||||
|
||||
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
||||
@@ -299,18 +266,6 @@ function OutputStream(options) {
|
||||
}
|
||||
might_need_space = false;
|
||||
}
|
||||
|
||||
if (mapping_token) {
|
||||
mappings.push({
|
||||
token: mapping_token,
|
||||
name: mapping_name,
|
||||
line: current_line,
|
||||
col: current_col
|
||||
});
|
||||
mapping_token = false;
|
||||
if (!might_add_newline) do_add_mapping();
|
||||
}
|
||||
|
||||
OUTPUT += str;
|
||||
current_pos += str.length;
|
||||
var a = str.split(/\r?\n/), n = a.length - 1;
|
||||
@@ -402,12 +357,27 @@ function OutputStream(options) {
|
||||
|
||||
function colon() {
|
||||
print(":");
|
||||
space();
|
||||
if (options.space_colon) space();
|
||||
};
|
||||
|
||||
var add_mapping = mappings ? function(token, name) {
|
||||
mapping_token = token;
|
||||
mapping_name = name;
|
||||
var add_mapping = options.source_map ? function(token, name) {
|
||||
try {
|
||||
if (token) options.source_map.add(
|
||||
token.file || "?",
|
||||
current_line, current_col,
|
||||
token.line, token.col,
|
||||
(!name && token.type == "name") ? token.value : name
|
||||
);
|
||||
} catch(ex) {
|
||||
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||
file: token.file,
|
||||
line: token.line,
|
||||
col: token.col,
|
||||
cline: current_line,
|
||||
ccol: current_col,
|
||||
name: name || ""
|
||||
})
|
||||
}
|
||||
} : noop;
|
||||
|
||||
function get() {
|
||||
@@ -501,7 +471,6 @@ function OutputStream(options) {
|
||||
use_asm = prev_use_asm;
|
||||
}
|
||||
});
|
||||
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
||||
|
||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||
var s = OutputStream(options);
|
||||
@@ -599,13 +568,6 @@ function OutputStream(options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (output.option('webkit')) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (output.option('wrap_iife')) {
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call && p.expression === this;
|
||||
@@ -626,7 +588,7 @@ function OutputStream(options) {
|
||||
|| p instanceof AST_Call && p.expression === this;
|
||||
});
|
||||
|
||||
PARENS(AST_Sequence, function(output){
|
||||
PARENS(AST_Seq, function(output){
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
||||
|| p instanceof AST_Unary // !(foo, bar, baz)
|
||||
@@ -715,7 +677,7 @@ function OutputStream(options) {
|
||||
}
|
||||
});
|
||||
|
||||
PARENS([ AST_Assign, AST_Conditional ], function(output){
|
||||
PARENS([ AST_Assign, AST_Conditional ], function (output){
|
||||
var p = output.parent();
|
||||
// !(a = false) → true
|
||||
if (p instanceof AST_Unary)
|
||||
@@ -940,7 +902,7 @@ function OutputStream(options) {
|
||||
function make_then(self, output) {
|
||||
var b = self.body;
|
||||
if (output.option("bracketize")
|
||||
|| output.option("ie8") && b instanceof AST_Do)
|
||||
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
||||
return make_block(b, output);
|
||||
// The squeezer replaces "block"-s that contain only a single
|
||||
// statement with the statement itself; technically, the AST
|
||||
@@ -1071,6 +1033,9 @@ function OutputStream(options) {
|
||||
DEFPRINT(AST_Var, function(self, output){
|
||||
self._do_print(output, "var");
|
||||
});
|
||||
DEFPRINT(AST_Const, function(self, output){
|
||||
self._do_print(output, "const");
|
||||
});
|
||||
|
||||
function parenthesize_for_noin(node, output, noin) {
|
||||
if (!noin) node.print(output);
|
||||
@@ -1118,19 +1083,18 @@ function OutputStream(options) {
|
||||
AST_Call.prototype._codegen(self, output);
|
||||
});
|
||||
|
||||
AST_Sequence.DEFMETHOD("_do_print", function(output){
|
||||
this.expressions.forEach(function(node, index) {
|
||||
if (index > 0) {
|
||||
output.comma();
|
||||
if (output.should_break()) {
|
||||
output.newline();
|
||||
output.indent();
|
||||
}
|
||||
AST_Seq.DEFMETHOD("_do_print", function(output){
|
||||
this.car.print(output);
|
||||
if (this.cdr) {
|
||||
output.comma();
|
||||
if (output.should_break()) {
|
||||
output.newline();
|
||||
output.indent();
|
||||
}
|
||||
node.print(output);
|
||||
});
|
||||
this.cdr.print(output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_Sequence, function(self, output){
|
||||
DEFPRINT(AST_Seq, function(self, output){
|
||||
self._do_print(output);
|
||||
// var p = output.parent();
|
||||
// if (p instanceof AST_Statement) {
|
||||
@@ -1252,7 +1216,7 @@ function OutputStream(options) {
|
||||
&& +key + "" == key)
|
||||
&& parseFloat(key) >= 0) {
|
||||
output.print(make_num(key));
|
||||
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
||||
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
|
||||
if (quote && output.option("keep_quoted_props")) {
|
||||
output.print_string(key, quote);
|
||||
} else {
|
||||
@@ -1302,14 +1266,45 @@ function OutputStream(options) {
|
||||
}
|
||||
});
|
||||
|
||||
function regexp_safe_literal(code) {
|
||||
return [
|
||||
0x5c , // \
|
||||
0x2f , // /
|
||||
0x2e , // .
|
||||
0x2b , // +
|
||||
0x2a , // *
|
||||
0x3f , // ?
|
||||
0x28 , // (
|
||||
0x29 , // )
|
||||
0x5b , // [
|
||||
0x5d , // ]
|
||||
0x7b , // {
|
||||
0x7d , // }
|
||||
0x24 , // $
|
||||
0x5e , // ^
|
||||
0x3a , // :
|
||||
0x7c , // |
|
||||
0x21 , // !
|
||||
0x0a , // \n
|
||||
0x0d , // \r
|
||||
0x00 , // \0
|
||||
0xfeff , // Unicode BOM
|
||||
0x2028 , // unicode "line separator"
|
||||
0x2029 , // unicode "paragraph separator"
|
||||
].indexOf(code) < 0;
|
||||
};
|
||||
|
||||
DEFPRINT(AST_RegExp, function(self, output){
|
||||
var regexp = self.getValue();
|
||||
var str = regexp.toString();
|
||||
if (regexp.raw_source) {
|
||||
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
|
||||
}
|
||||
var str = self.getValue().toString();
|
||||
if (output.option("ascii_only")) {
|
||||
str = output.to_ascii(str);
|
||||
} else if (output.option("unescape_regexps")) {
|
||||
str = str.split("\\\\").map(function(str){
|
||||
return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){
|
||||
var code = parseInt(s.substr(2), 16);
|
||||
return regexp_safe_literal(code) ? String.fromCharCode(code) : s;
|
||||
});
|
||||
}).join("\\\\");
|
||||
}
|
||||
output.print(str);
|
||||
var p = output.parent();
|
||||
|
||||
152
lib/parse.js
152
lib/parse.js
@@ -115,6 +115,8 @@ var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
|
||||
|
||||
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
|
||||
|
||||
var REGEXP_MODIFIERS = makePredicate(characters("gmsiy"));
|
||||
|
||||
/* -----[ Tokenizer ]----- */
|
||||
|
||||
// regexps adapted from http://xregexp.com/plugins/#unicode
|
||||
@@ -475,33 +477,31 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return name;
|
||||
};
|
||||
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){
|
||||
var prev_backslash = false, ch, in_class = false;
|
||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
||||
parse_error("Unexpected line terminator");
|
||||
} else if (prev_backslash) {
|
||||
source += "\\" + ch;
|
||||
regexp += "\\" + ch;
|
||||
prev_backslash = false;
|
||||
} else if (ch == "[") {
|
||||
in_class = true;
|
||||
source += ch;
|
||||
regexp += ch;
|
||||
} else if (ch == "]" && in_class) {
|
||||
in_class = false;
|
||||
source += ch;
|
||||
regexp += ch;
|
||||
} else if (ch == "/" && !in_class) {
|
||||
break;
|
||||
} else if (ch == "\\") {
|
||||
prev_backslash = true;
|
||||
} else {
|
||||
source += ch;
|
||||
regexp += ch;
|
||||
}
|
||||
var mods = read_name();
|
||||
try {
|
||||
var regexp = new RegExp(source, mods);
|
||||
regexp.raw_source = source;
|
||||
return token("regexp", regexp);
|
||||
return token("regexp", new RegExp(regexp, mods));
|
||||
} catch(e) {
|
||||
parse_error(e.message);
|
||||
parse_error(e.message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -633,7 +633,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
|
||||
next_token.has_directive = function(directive) {
|
||||
return S.directives[directive] > 0;
|
||||
return S.directives[directive] !== undefined &&
|
||||
S.directives[directive] > 0;
|
||||
}
|
||||
|
||||
return next_token;
|
||||
@@ -682,7 +683,9 @@ var PRECEDENCE = (function(a, ret){
|
||||
{}
|
||||
);
|
||||
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||
var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
|
||||
|
||||
var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
|
||||
|
||||
/* -----[ Parser ]----- */
|
||||
|
||||
@@ -690,13 +693,14 @@ function parse($TEXT, options) {
|
||||
|
||||
options = defaults(options, {
|
||||
bare_returns : false,
|
||||
cli : false,
|
||||
expression : false,
|
||||
filename : null,
|
||||
html5_comments : true,
|
||||
shebang : true,
|
||||
strict : false,
|
||||
toplevel : null,
|
||||
}, true);
|
||||
});
|
||||
|
||||
var S = {
|
||||
input : (typeof $TEXT == "string"
|
||||
@@ -937,6 +941,12 @@ function parse($TEXT, options) {
|
||||
semicolon();
|
||||
return node;
|
||||
|
||||
case "const":
|
||||
next();
|
||||
var node = const_();
|
||||
semicolon();
|
||||
return node;
|
||||
|
||||
case "with":
|
||||
if (S.input.has_directive("use strict")) {
|
||||
croak("Strict mode may not include a with statement");
|
||||
@@ -1010,12 +1020,8 @@ function parse($TEXT, options) {
|
||||
? (next(), var_(true))
|
||||
: expression(true, true);
|
||||
if (is("operator", "in")) {
|
||||
if (init instanceof AST_Var) {
|
||||
if (init.definitions.length > 1)
|
||||
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||
} else if (!is_assignable(init)) {
|
||||
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||
}
|
||||
if (init instanceof AST_Var && init.definitions.length > 1)
|
||||
croak("Only one variable declaration allowed in for..in loop");
|
||||
next();
|
||||
return for_in(init);
|
||||
}
|
||||
@@ -1055,32 +1061,29 @@ function parse($TEXT, options) {
|
||||
if (in_statement && !name)
|
||||
unexpected();
|
||||
expect("(");
|
||||
var argnames = [];
|
||||
for (var first = true; !is("punc", ")");) {
|
||||
if (first) first = false; else expect(",");
|
||||
argnames.push(as_symbol(AST_SymbolFunarg));
|
||||
}
|
||||
next();
|
||||
var loop = S.in_loop;
|
||||
var labels = S.labels;
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var body = block_();
|
||||
if (S.input.has_directive("use strict")) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
argnames.forEach(strict_verify_symbol);
|
||||
}
|
||||
S.input.pop_directives_stack();
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
return new ctor({
|
||||
name: name,
|
||||
argnames: argnames,
|
||||
body: body
|
||||
argnames: (function(first, a){
|
||||
while (!is("punc", ")")) {
|
||||
if (first) first = false; else expect(",");
|
||||
a.push(as_symbol(AST_SymbolFunarg));
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
})(true, []),
|
||||
body: (function(loop, labels){
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var a = block_();
|
||||
S.input.pop_directives_stack();
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
return a;
|
||||
})(S.in_loop, S.labels)
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1176,12 +1179,12 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
function vardefs(no_in) {
|
||||
function vardefs(no_in, in_const) {
|
||||
var a = [];
|
||||
for (;;) {
|
||||
a.push(new AST_VarDef({
|
||||
start : S.token,
|
||||
name : as_symbol(AST_SymbolVar),
|
||||
name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar),
|
||||
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
|
||||
end : prev()
|
||||
}));
|
||||
@@ -1195,7 +1198,15 @@ function parse($TEXT, options) {
|
||||
var var_ = function(no_in) {
|
||||
return new AST_Var({
|
||||
start : prev(),
|
||||
definitions : vardefs(no_in),
|
||||
definitions : vardefs(no_in, false),
|
||||
end : prev()
|
||||
});
|
||||
};
|
||||
|
||||
var const_ = function() {
|
||||
return new AST_Const({
|
||||
start : prev(),
|
||||
definitions : vardefs(false, true),
|
||||
end : prev()
|
||||
});
|
||||
};
|
||||
@@ -1222,6 +1233,7 @@ function parse($TEXT, options) {
|
||||
var tok = S.token, ret;
|
||||
switch (tok.type) {
|
||||
case "name":
|
||||
case "keyword":
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
case "num":
|
||||
@@ -1251,6 +1263,13 @@ function parse($TEXT, options) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "operator":
|
||||
if (!is_identifier_string(tok.value)) {
|
||||
croak("Invalid getter/setter name: " + tok.value,
|
||||
tok.line, tok.col, tok.pos);
|
||||
}
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
}
|
||||
next();
|
||||
return ret;
|
||||
@@ -1284,7 +1303,7 @@ function parse($TEXT, options) {
|
||||
func.end = prev();
|
||||
return subscripts(func, allow_calls);
|
||||
}
|
||||
if (ATOMIC_START_TOKEN(S.token.type)) {
|
||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||
return subscripts(as_atom_node(), allow_calls);
|
||||
}
|
||||
unexpected();
|
||||
@@ -1398,20 +1417,12 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
function strict_verify_symbol(sym) {
|
||||
if (sym.name == "arguments" || sym.name == "eval")
|
||||
croak("Unexpected " + sym.name + " in strict mode", sym.start.line, sym.start.col, sym.start.pos);
|
||||
}
|
||||
|
||||
function as_symbol(type, noerror) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
return null;
|
||||
}
|
||||
var sym = _make_symbol(type);
|
||||
if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) {
|
||||
strict_verify_symbol(sym);
|
||||
}
|
||||
next();
|
||||
return sym;
|
||||
};
|
||||
@@ -1472,17 +1483,8 @@ function parse($TEXT, options) {
|
||||
|
||||
function make_unary(ctor, token, expr) {
|
||||
var op = token.value;
|
||||
switch (op) {
|
||||
case "++":
|
||||
case "--":
|
||||
if (!is_assignable(expr))
|
||||
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
|
||||
break;
|
||||
case "delete":
|
||||
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
|
||||
croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
|
||||
break;
|
||||
}
|
||||
if ((op == "++" || op == "--") && !is_assignable(expr))
|
||||
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
|
||||
return new ctor({ operator: op, expression: expr });
|
||||
};
|
||||
|
||||
@@ -1527,6 +1529,7 @@ function parse($TEXT, options) {
|
||||
};
|
||||
|
||||
function is_assignable(expr) {
|
||||
if (options.cli) return true;
|
||||
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
|
||||
};
|
||||
|
||||
@@ -1551,18 +1554,17 @@ function parse($TEXT, options) {
|
||||
|
||||
var expression = function(commas, no_in) {
|
||||
var start = S.token;
|
||||
var exprs = [];
|
||||
while (true) {
|
||||
exprs.push(maybe_assign(no_in));
|
||||
if (!commas || !is("punc", ",")) break;
|
||||
var expr = maybe_assign(no_in);
|
||||
if (commas && is("punc", ",")) {
|
||||
next();
|
||||
commas = true;
|
||||
return new AST_Seq({
|
||||
start : start,
|
||||
car : expr,
|
||||
cdr : expression(true, no_in),
|
||||
end : peek()
|
||||
});
|
||||
}
|
||||
return exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
||||
start : start,
|
||||
expressions : exprs,
|
||||
end : peek()
|
||||
});
|
||||
return expr;
|
||||
};
|
||||
|
||||
function in_loop(cont) {
|
||||
|
||||
@@ -43,16 +43,16 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function find_builtins(reserved) {
|
||||
function find_builtins() {
|
||||
// NaN will be included due to Number.NaN
|
||||
[
|
||||
var a = [
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
"Infinity",
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
];
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp
|
||||
@@ -63,24 +63,24 @@ function find_builtins(reserved) {
|
||||
}
|
||||
});
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
push_uniq(a, name);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function mangle_properties(ast, options) {
|
||||
options = defaults(options, {
|
||||
builtins: false,
|
||||
cache: null,
|
||||
debug: false,
|
||||
keep_quoted: false,
|
||||
ignore_quoted: false,
|
||||
only_cache: false,
|
||||
regex: null,
|
||||
reserved: null,
|
||||
});
|
||||
|
||||
var reserved = options.reserved;
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
if (reserved == null)
|
||||
reserved = find_builtins();
|
||||
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
@@ -91,12 +91,12 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
var keep_quoted = options.keep_quoted;
|
||||
var ignore_quoted = options.ignore_quoted;
|
||||
|
||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug = (options.debug !== false);
|
||||
var debug_name_suffix;
|
||||
if (debug) {
|
||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||
@@ -104,12 +104,12 @@ function mangle_properties(ast, options) {
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
var to_keep = {};
|
||||
var ignored = {};
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
add(node.key, keep_quoted && node.quote);
|
||||
add(node.key, ignore_quoted && node.quote);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
@@ -119,14 +119,14 @@ function mangle_properties(ast, options) {
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, keep_quoted);
|
||||
addStrings(node.property, ignore_quoted);
|
||||
}
|
||||
}));
|
||||
|
||||
// step 2: transform the tree, renaming properties
|
||||
return ast.transform(new TreeTransformer(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
if (!(keep_quoted && node.quote))
|
||||
if (!(ignore_quoted && node.quote))
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
@@ -137,7 +137,7 @@ function mangle_properties(ast, options) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
if (!keep_quoted)
|
||||
if (!ignore_quoted)
|
||||
node.property = mangleStrings(node.property);
|
||||
}
|
||||
// else if (node instanceof AST_String) {
|
||||
@@ -167,16 +167,16 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (keep_quoted && name in to_keep) return false;
|
||||
if (ignore_quoted && name in ignored) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.props.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
function add(name, keep) {
|
||||
if (keep) {
|
||||
to_keep[name] = true;
|
||||
function add(name, ignore) {
|
||||
if (ignore) {
|
||||
ignored[name] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -199,19 +199,19 @@ function mangle_properties(ast, options) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||
|
||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
||||
if (can_mangle(debug_mangled) && !(ignore_quoted && debug_mangled in ignored)) {
|
||||
mangled = debug_mangled;
|
||||
}
|
||||
}
|
||||
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) {
|
||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
||||
// note can_mangle() does not check if the name collides with the 'ignored' set
|
||||
// (filled with quoted properties when ignore_quoted set). Make sure we add this
|
||||
// check so we don't collide with a quoted name.
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
||||
} while (!can_mangle(mangled) || (ignore_quoted && mangled in ignored));
|
||||
}
|
||||
|
||||
cache.props.set(name, mangled);
|
||||
@@ -219,17 +219,17 @@ function mangle_properties(ast, options) {
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function addStrings(node, keep) {
|
||||
function addStrings(node, ignore) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
node.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_Sequence) {
|
||||
walk(node.expressions[node.expressions.length - 1]);
|
||||
if (node instanceof AST_Seq) {
|
||||
walk(node.cdr);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_String) {
|
||||
add(node.value, keep);
|
||||
add(node.value, ignore);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Conditional) {
|
||||
@@ -247,9 +247,8 @@ function mangle_properties(ast, options) {
|
||||
|
||||
function mangleStrings(node) {
|
||||
return node.transform(new TreeTransformer(function(node){
|
||||
if (node instanceof AST_Sequence) {
|
||||
var last = node.expressions.length - 1;
|
||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||
if (node instanceof AST_Seq) {
|
||||
node.cdr = mangleStrings(node.cdr);
|
||||
}
|
||||
else if (node instanceof AST_String) {
|
||||
node.value = mangle(node.value);
|
||||
@@ -261,4 +260,5 @@ function mangle_properties(ast, options) {
|
||||
return node;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
285
lib/scope.js
285
lib/scope.js
@@ -76,10 +76,10 @@ SymbolDef.prototype = {
|
||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
var sym = this.orig[0];
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
if (!options.screw_ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
var def;
|
||||
if (def = this.redefined()) {
|
||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
@@ -87,16 +87,13 @@ SymbolDef.prototype = {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
}
|
||||
},
|
||||
redefined: function() {
|
||||
return this.defun && this.defun.variables.get(this.name);
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
cache: null,
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
});
|
||||
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
@@ -159,7 +156,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar) {
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
defun.def_variable(node);
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
@@ -186,8 +184,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: find back references and eval
|
||||
self.globals = new Dictionary();
|
||||
var func = null;
|
||||
var globals = self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_Lambda) {
|
||||
var prev_func = func;
|
||||
func = node;
|
||||
descend();
|
||||
func = prev_func;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_LoopControl && node.label) {
|
||||
node.label.thedef.references.push(node);
|
||||
return true;
|
||||
@@ -200,30 +206,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
}
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
||||
node.scope.uses_arguments = true;
|
||||
}
|
||||
if (!sym) {
|
||||
sym = self.def_global(node);
|
||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||
sym.scope.uses_arguments = true;
|
||||
}
|
||||
node.thedef = sym;
|
||||
node.reference(options);
|
||||
return true;
|
||||
}
|
||||
// ensure mangling works if catch reuses a scope variable
|
||||
var def;
|
||||
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
|
||||
var s = node.scope;
|
||||
while (s) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie8) {
|
||||
if (!options.screw_ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
@@ -271,7 +268,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
this.def_variable(new AST_SymbolVar({
|
||||
name: "arguments",
|
||||
start: this.start,
|
||||
end: this.end
|
||||
@@ -328,8 +325,8 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name reserved from mangling.
|
||||
if (options.reserved.indexOf(m) >= 0) continue;
|
||||
// shadow a name excepted from mangling.
|
||||
if (options.except.indexOf(m) >= 0) continue;
|
||||
|
||||
// we must ensure that the mangled name does not shadow a name
|
||||
// from some parent scope that is referenced in this or in
|
||||
@@ -361,12 +358,13 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
var def = this.definition();
|
||||
return !def || def.unmangleable(options);
|
||||
return this.definition().unmangleable(options);
|
||||
});
|
||||
|
||||
// labels are always mangleable
|
||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||
return this.definition().references.length == 0
|
||||
@@ -377,9 +375,13 @@ AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||
return this.definition().undeclared;
|
||||
});
|
||||
|
||||
AST_LabelRef.DEFMETHOD("undeclared", return_false);
|
||||
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Label.DEFMETHOD("undeclared", return_false);
|
||||
AST_Label.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
return this.thedef;
|
||||
@@ -390,22 +392,21 @@ AST_Symbol.DEFMETHOD("global", function(){
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
options = defaults(options, {
|
||||
return defaults(options, {
|
||||
eval : false,
|
||||
ie8 : false,
|
||||
except : [],
|
||||
keep_fnames : false,
|
||||
reserved : [],
|
||||
screw_ie8 : true,
|
||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
||||
toplevel : false,
|
||||
});
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
return options;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
|
||||
// Never mangle arguments
|
||||
options.reserved.push('arguments');
|
||||
options.except.push('arguments');
|
||||
|
||||
// We only need to mangle declaration nodes. Special logic wired
|
||||
// into the code generator will display the mangled name if it's
|
||||
@@ -416,7 +417,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
|
||||
if (options.cache) {
|
||||
this.globals.each(function(symbol){
|
||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||
if (options.except.indexOf(symbol.name) < 0) {
|
||||
to_mangle.push(symbol);
|
||||
}
|
||||
});
|
||||
@@ -433,7 +434,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
if (node instanceof AST_Scope) {
|
||||
var p = tw.parent(), a = [];
|
||||
node.variables.each(function(symbol){
|
||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||
if (options.except.indexOf(symbol.name) < 0) {
|
||||
a.push(symbol);
|
||||
}
|
||||
});
|
||||
@@ -446,7 +447,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
}
|
||||
@@ -461,69 +462,105 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
try {
|
||||
AST_Node.prototype.print = function(stream, force_parens) {
|
||||
this._print(stream, force_parens);
|
||||
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||
base54.consider(this.name, -1);
|
||||
} else if (options.properties) {
|
||||
if (this instanceof AST_Dot) {
|
||||
base54.consider(this.property, -1);
|
||||
} else if (this instanceof AST_Sub) {
|
||||
skip_string(this.property);
|
||||
}
|
||||
}
|
||||
};
|
||||
base54.consider(this.print_to_string(), 1);
|
||||
} finally {
|
||||
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||
}
|
||||
base54.sort();
|
||||
|
||||
function skip_string(node) {
|
||||
if (node instanceof AST_String) {
|
||||
base54.consider(node.value, -1);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
skip_string(node.consequent);
|
||||
skip_string(node.alternative);
|
||||
} else if (node instanceof AST_Sequence) {
|
||||
skip_string(node.expressions[node.expressions.length - 1]);
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (node instanceof AST_Constant)
|
||||
base54.consider(node.print_to_string());
|
||||
else if (node instanceof AST_Return)
|
||||
base54.consider("return");
|
||||
else if (node instanceof AST_Throw)
|
||||
base54.consider("throw");
|
||||
else if (node instanceof AST_Continue)
|
||||
base54.consider("continue");
|
||||
else if (node instanceof AST_Break)
|
||||
base54.consider("break");
|
||||
else if (node instanceof AST_Debugger)
|
||||
base54.consider("debugger");
|
||||
else if (node instanceof AST_Directive)
|
||||
base54.consider(node.value);
|
||||
else if (node instanceof AST_While)
|
||||
base54.consider("while");
|
||||
else if (node instanceof AST_Do)
|
||||
base54.consider("do while");
|
||||
else if (node instanceof AST_If) {
|
||||
base54.consider("if");
|
||||
if (node.alternative) base54.consider("else");
|
||||
}
|
||||
}
|
||||
else if (node instanceof AST_Var)
|
||||
base54.consider("var");
|
||||
else if (node instanceof AST_Const)
|
||||
base54.consider("const");
|
||||
else if (node instanceof AST_Lambda)
|
||||
base54.consider("function");
|
||||
else if (node instanceof AST_For)
|
||||
base54.consider("for");
|
||||
else if (node instanceof AST_ForIn)
|
||||
base54.consider("for in");
|
||||
else if (node instanceof AST_Switch)
|
||||
base54.consider("switch");
|
||||
else if (node instanceof AST_Case)
|
||||
base54.consider("case");
|
||||
else if (node instanceof AST_Default)
|
||||
base54.consider("default");
|
||||
else if (node instanceof AST_With)
|
||||
base54.consider("with");
|
||||
else if (node instanceof AST_ObjectSetter)
|
||||
base54.consider("set" + node.key);
|
||||
else if (node instanceof AST_ObjectGetter)
|
||||
base54.consider("get" + node.key);
|
||||
else if (node instanceof AST_ObjectKeyVal)
|
||||
base54.consider(node.key);
|
||||
else if (node instanceof AST_New)
|
||||
base54.consider("new");
|
||||
else if (node instanceof AST_This)
|
||||
base54.consider("this");
|
||||
else if (node instanceof AST_Try)
|
||||
base54.consider("try");
|
||||
else if (node instanceof AST_Catch)
|
||||
base54.consider("catch");
|
||||
else if (node instanceof AST_Finally)
|
||||
base54.consider("finally");
|
||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||
base54.consider(node.name);
|
||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||
base54.consider(node.operator);
|
||||
else if (node instanceof AST_Dot)
|
||||
base54.consider(node.property);
|
||||
});
|
||||
this.walk(tw);
|
||||
base54.sort();
|
||||
});
|
||||
|
||||
var base54 = (function() {
|
||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||
var digits = "0123456789".split("");
|
||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
||||
var chars, frequency;
|
||||
function reset() {
|
||||
frequency = Object.create(null);
|
||||
leading.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
digits.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
||||
}
|
||||
base54.consider = function(str, delta) {
|
||||
base54.consider = function(str){
|
||||
for (var i = str.length; --i >= 0;) {
|
||||
frequency[str[i]] += delta;
|
||||
var code = str.charCodeAt(i);
|
||||
if (code in frequency) ++frequency[code];
|
||||
}
|
||||
};
|
||||
function compare(a, b) {
|
||||
return frequency[b] - frequency[a];
|
||||
}
|
||||
base54.sort = function() {
|
||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||
chars = mergeSort(chars, function(a, b){
|
||||
if (is_digit(a) && !is_digit(b)) return 1;
|
||||
if (is_digit(b) && !is_digit(a)) return -1;
|
||||
return frequency[b] - frequency[a];
|
||||
});
|
||||
};
|
||||
base54.reset = reset;
|
||||
reset();
|
||||
base54.get = function(){ return chars };
|
||||
base54.freq = function(){ return frequency };
|
||||
function base54(num) {
|
||||
var ret = "", base = 54;
|
||||
num++;
|
||||
do {
|
||||
num--;
|
||||
ret += chars[num % base];
|
||||
ret += String.fromCharCode(chars[num % base]);
|
||||
num = Math.floor(num / base);
|
||||
base = 64;
|
||||
} while (num > 0);
|
||||
@@ -531,3 +568,89 @@ var base54 = (function() {
|
||||
};
|
||||
return base54;
|
||||
})();
|
||||
|
||||
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||
options = defaults(options, {
|
||||
assign_to_global : true,
|
||||
eval : true,
|
||||
func_arguments : true,
|
||||
nested_defuns : true,
|
||||
undeclared : false, // this makes a lot of noise
|
||||
unreferenced : true,
|
||||
});
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (options.undeclared
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node.undeclared())
|
||||
{
|
||||
// XXX: this also warns about JS standard names,
|
||||
// i.e. Object, Array, parseInt etc. Should add a list of
|
||||
// exceptions.
|
||||
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.assign_to_global)
|
||||
{
|
||||
var sym = null;
|
||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef)
|
||||
sym = node.left;
|
||||
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef)
|
||||
sym = node.init;
|
||||
if (sym
|
||||
&& (sym.undeclared()
|
||||
|| (sym.global() && sym.scope !== sym.definition().scope))) {
|
||||
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
||||
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
|
||||
name: sym.name,
|
||||
file: sym.start.file,
|
||||
line: sym.start.line,
|
||||
col: sym.start.col
|
||||
});
|
||||
}
|
||||
}
|
||||
if (options.eval
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node.undeclared()
|
||||
&& node.name == "eval") {
|
||||
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
||||
}
|
||||
if (options.unreferenced
|
||||
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label)
|
||||
&& !(node instanceof AST_SymbolCatch)
|
||||
&& node.unreferenced()) {
|
||||
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
||||
type: node instanceof AST_Label ? "Label" : "Symbol",
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.func_arguments
|
||||
&& node instanceof AST_Lambda
|
||||
&& node.uses_arguments) {
|
||||
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
||||
name: node.name ? node.name.name : "anonymous",
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.nested_defuns
|
||||
&& node instanceof AST_Defun
|
||||
&& !(tw.parent() instanceof AST_Scope)) {
|
||||
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
||||
name: node.name.name,
|
||||
type: tw.parent().TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
});
|
||||
this.walk(tw);
|
||||
});
|
||||
|
||||
@@ -174,8 +174,9 @@ TreeTransformer.prototype = new TreeWalker;
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
|
||||
_(AST_Sequence, function(self, tw){
|
||||
self.expressions = do_list(self.expressions, tw);
|
||||
_(AST_Seq, function(self, tw){
|
||||
self.car = self.car.transform(tw);
|
||||
self.cdr = self.cdr.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function array_to_hash(a) {
|
||||
var ret = Object.create(null);
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
ret[a[i]] = true;
|
||||
return ret;
|
||||
};
|
||||
|
||||
function slice(a, start) {
|
||||
return Array.prototype.slice.call(a, start || 0);
|
||||
};
|
||||
@@ -339,7 +346,7 @@ function first_in_statement(stack) {
|
||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||
if ((p instanceof AST_Seq && p.car === node ) ||
|
||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
||||
(p instanceof AST_Dot && p.expression === node ) ||
|
||||
(p instanceof AST_Sub && p.expression === node ) ||
|
||||
|
||||
19
package.json
19
package.json
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.0.23",
|
||||
"version": "2.8.29",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -29,16 +29,23 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.9.0",
|
||||
"source-map": "~0.5.1"
|
||||
"source-map": "~0.5.1",
|
||||
"yargs": "~3.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~5.0.3",
|
||||
"mocha": "~2.3.4",
|
||||
"semver": "~5.3.0"
|
||||
"mocha": "~2.3.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"uglify-to-browserify": "~1.0.0"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
"uglify-to-browserify"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/run-tests.js"
|
||||
},
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
"use strict";
|
||||
|
||||
var createHash = require("crypto").createHash;
|
||||
var fetch = require("./fetch");
|
||||
var fork = require("child_process").fork;
|
||||
var args = process.argv.slice(2);
|
||||
if (!args.length) {
|
||||
args.push("-mc");
|
||||
args.push("-mc", "warnings=false");
|
||||
}
|
||||
args.push("--timings");
|
||||
args.push("--stats");
|
||||
var urls = [
|
||||
"https://code.jquery.com/jquery-3.2.1.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||
@@ -31,6 +30,11 @@ function done() {
|
||||
console.log();
|
||||
console.log(url);
|
||||
console.log(info.log);
|
||||
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);
|
||||
@@ -53,8 +57,7 @@ urls.forEach(function(url) {
|
||||
output: 0,
|
||||
log: ""
|
||||
};
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||
res.on("data", function(data) {
|
||||
results[url].input += data.length;
|
||||
|
||||
67
test/compress/angular-inject.js
vendored
Normal file
67
test/compress/angular-inject.js
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
ng_inject_defun: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_assignment: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_inline: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
angular.module('a').
|
||||
factory('b',
|
||||
/*@ngInject*/
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}).
|
||||
directive('c',
|
||||
/*@ngInject*/
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
})
|
||||
}
|
||||
expect: {
|
||||
angular.module('a').
|
||||
factory('b',[
|
||||
'dependency',
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}]).
|
||||
directive('c',[
|
||||
'anotherDependency',
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
}])
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ ascii_only_true: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : true,
|
||||
ie8 : false,
|
||||
screw_ie8 : true,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
@@ -20,7 +20,7 @@ ascii_only_false: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : false,
|
||||
ie8 : false,
|
||||
screw_ie8 : true,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
@@ -33,3 +33,4 @@ ascii_only_false: {
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ collapse_vars_side_effects_1: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -68,10 +68,11 @@ collapse_vars_side_effects_1: {
|
||||
log(x, s.charAt(i++), y, 7);
|
||||
}
|
||||
function f4() {
|
||||
var i = 10,
|
||||
var log = console.log.bind(console),
|
||||
i = 10,
|
||||
x = i += 2,
|
||||
y = i += 3;
|
||||
console.log.bind(console)(x, i += 4, y, i);
|
||||
log(x, i += 4, y, i);
|
||||
}
|
||||
f1(), f2(), f3(), f4();
|
||||
}
|
||||
@@ -150,7 +151,7 @@ collapse_vars_issue_721: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
define(["require", "exports", 'handlebars'], function (require, exports, hb) {
|
||||
@@ -216,7 +217,7 @@ collapse_vars_properties: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1(obj) {
|
||||
@@ -243,7 +244,7 @@ collapse_vars_if: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -293,7 +294,7 @@ collapse_vars_while: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:false, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1(y) {
|
||||
@@ -392,9 +393,9 @@ collapse_vars_do_while: {
|
||||
}
|
||||
function f3(y) {
|
||||
function fn(n) { console.log(n); }
|
||||
var a = 2, x = 7;
|
||||
var a = 2;
|
||||
do {
|
||||
fn(a = x);
|
||||
fn(a = 7);
|
||||
break;
|
||||
} while (y);
|
||||
}
|
||||
@@ -467,9 +468,8 @@ collapse_vars_do_while_drop_assign: {
|
||||
}
|
||||
function f3(y) {
|
||||
function fn(n) { console.log(n); }
|
||||
var x = 7;
|
||||
do {
|
||||
fn(x);
|
||||
fn(7);
|
||||
break;
|
||||
} while (y);
|
||||
}
|
||||
@@ -583,8 +583,8 @@ collapse_vars_assignment: {
|
||||
return a = a;
|
||||
}
|
||||
function f1(c) {
|
||||
var a = 3 / c;
|
||||
var b = 1 - a;
|
||||
const a = 3 / c;
|
||||
const b = 1 - a;
|
||||
return b;
|
||||
}
|
||||
function f2(c) {
|
||||
@@ -670,8 +670,8 @@ collapse_vars_lvalues: {
|
||||
function f4(x) { var a = (x -= 3); return x + a; }
|
||||
function f5(x) { var w = e1(), v = e2(), c = v = --x; return (w = x) - c; }
|
||||
function f6(x) { var w = e1(), v = e2(); return (v = --x) - (w = x); }
|
||||
function f7(x) { var w = e1(); return (w = x) - (e2() - x); }
|
||||
function f8(x) { var w = e1(); return (w = x) - (e2() - x); }
|
||||
function f7(x) { var w = e1(), v = e2(), c = v - x; return (w = x) - c; }
|
||||
function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); }
|
||||
function f9(x) { var w = e1(); return e2() - x - (w = x); }
|
||||
}
|
||||
}
|
||||
@@ -700,10 +700,10 @@ collapse_vars_lvalues_drop_assign: {
|
||||
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||
function f3(x) { var a = (x -= 3); return x + a; }
|
||||
function f4(x) { var a = (x -= 3); return x + a; }
|
||||
function f5(x) { e1(); var v = e2(), c = v = --x; return x - c; }
|
||||
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
|
||||
function f6(x) { e1(), e2(); return --x - x; }
|
||||
function f7(x) { e1(); return x - (e2() - x); }
|
||||
function f8(x) { e1(); return x - (e2() - x); }
|
||||
function f7(x) { var v = (e1(), e2()), c = v - x; return x - c; }
|
||||
function f8(x) { var v = (e1(), e2()); return x - (v - x); }
|
||||
function f9(x) { e1(); return e2() - x - x; }
|
||||
}
|
||||
}
|
||||
@@ -712,7 +712,7 @@ collapse_vars_misc1: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f0(o, a, h) {
|
||||
@@ -724,10 +724,10 @@ collapse_vars_misc1: {
|
||||
return t;
|
||||
}
|
||||
function f1(x) { var y = 5 - x; return y; }
|
||||
function f2(x) { var z = foo(), y = z / (5 - x); return y; }
|
||||
function f2(x) { const z = foo(), y = z / (5 - x); return y; }
|
||||
function f3(x) { var z = foo(), y = (5 - x) / z; return y; }
|
||||
function f4(x) { var z = foo(), y = (5 - u) / z; return y; }
|
||||
function f5(x) { var z = foo(), y = (5 - window.x) / z; return y; }
|
||||
function f5(x) { const z = foo(), y = (5 - window.x) / z; return y; }
|
||||
function f6() { var b = window.a * window.z; return b && zap(); }
|
||||
function f7() { var b = window.a * window.z; return b + b; }
|
||||
function f8() { var b = window.a * window.z; var c = b + 5; return b + c; }
|
||||
@@ -744,7 +744,7 @@ collapse_vars_misc1: {
|
||||
function f2(x) { return foo() / (5 - x) }
|
||||
function f3(x) { return (5 - x) / foo() }
|
||||
function f4(x) { var z = foo(); return (5 - u) / z }
|
||||
function f5(x) { var z = foo(); return (5 - window.x) / z }
|
||||
function f5(x) { const z = foo(); return (5 - window.x) / z }
|
||||
function f6() { return window.a * window.z && zap() }
|
||||
function f7() { var b = window.a * window.z; return b + b }
|
||||
function f8() { var b = window.a * window.z; return b + (b + 5) }
|
||||
@@ -789,7 +789,7 @@ collapse_vars_repeated: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -812,17 +812,19 @@ collapse_vars_repeated: {
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
return -3;
|
||||
return -3
|
||||
}
|
||||
function f2(x) {
|
||||
return x;
|
||||
return x
|
||||
}
|
||||
(function(x){
|
||||
console.log("GOOD!!");
|
||||
})(),
|
||||
var a = "GOOD" + x, e = "BAD", e = a;
|
||||
console.log(e + "!");
|
||||
})("!"),
|
||||
(function(x){
|
||||
console.log("GOOD!!");
|
||||
})();
|
||||
var a = "GOOD" + x, e = "BAD" + x, e = a;
|
||||
console.log(e + "!");
|
||||
})("!");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -831,7 +833,7 @@ collapse_vars_closures: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function constant_vars_can_be_replaced_in_any_scope() {
|
||||
@@ -921,7 +923,7 @@ collapse_vars_try: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -1046,9 +1048,10 @@ collapse_vars_object: {
|
||||
}
|
||||
expect: {
|
||||
function f0(x, y) {
|
||||
var z = x + y;
|
||||
return {
|
||||
get b() { return 7; },
|
||||
r: x + y
|
||||
r: z
|
||||
};
|
||||
}
|
||||
function f1(x, y) {
|
||||
@@ -1118,7 +1121,7 @@ collapse_vars_constants: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true, reduce_vars:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1(x) {
|
||||
@@ -1146,7 +1149,7 @@ collapse_vars_constants: {
|
||||
function f3(x) {
|
||||
var b = x.prop;
|
||||
sideeffect1();
|
||||
return b + (function() { return -9; })();
|
||||
return b + -9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1156,7 +1159,7 @@ collapse_vars_arguments: {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true,
|
||||
toplevel:true, reduce_vars:true
|
||||
toplevel:true
|
||||
}
|
||||
input: {
|
||||
var outer = function() {
|
||||
@@ -1283,7 +1286,6 @@ collapse_vars_regexp: {
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -1317,8 +1319,8 @@ collapse_vars_regexp: {
|
||||
};
|
||||
}
|
||||
(function(){
|
||||
var result, rx = /ab*/g;
|
||||
while (result = rx.exec("acdabcdeabbb"))
|
||||
var result, s = "acdabcdeabbb", rx = /ab*/g;
|
||||
while (result = rx.exec(s))
|
||||
console.log(result[0]);
|
||||
})();
|
||||
}
|
||||
@@ -1342,10 +1344,7 @@ issue_1537: {
|
||||
issue_1562: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var v = 1, B = 2;
|
||||
@@ -1364,11 +1363,14 @@ issue_1562: {
|
||||
var v = 1;
|
||||
for (v in objs) f(2);
|
||||
|
||||
while(5) bar(10);
|
||||
var x = 3;
|
||||
while(x + 2) bar(10);
|
||||
|
||||
do bar(20); while(6);
|
||||
var y = 4;
|
||||
do bar(20); while(y + 2);
|
||||
|
||||
for (; f(7) ;) bar(30);
|
||||
var z = 5;
|
||||
for (; f(z + 2) ;) bar(30);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1591,668 +1593,48 @@ var_side_effects_3: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_vars_assign: {
|
||||
reassign_const_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a = 1;
|
||||
a = [].length,
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a = 1;
|
||||
a = [].length,
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
iife_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var log = function(x) {
|
||||
console.log(x);
|
||||
}, foo = bar();
|
||||
log(foo);
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x);
|
||||
})(bar());
|
||||
}
|
||||
}
|
||||
|
||||
iife_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: false,
|
||||
toplevel: true,
|
||||
unused: false,
|
||||
}
|
||||
input: {
|
||||
var foo = bar();
|
||||
!function(x) {
|
||||
console.log(x);
|
||||
}(foo);
|
||||
}
|
||||
expect: {
|
||||
!function(x) {
|
||||
console.log(x);
|
||||
}(bar());
|
||||
}
|
||||
}
|
||||
|
||||
var_defs: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
var f1 = function(x, y) {
|
||||
var a, b, r = x + y, q = r * r, z = q - r, a = z, b = 7;
|
||||
console.log(a + b);
|
||||
};
|
||||
f1("1", 0);
|
||||
}
|
||||
expect: {
|
||||
var f1 = function(x, y) {
|
||||
var r = x + y, a = r * r - r, b = 7;
|
||||
console.log(a + b);
|
||||
};
|
||||
f1("1", 0);
|
||||
}
|
||||
expect_stdout: "97"
|
||||
}
|
||||
|
||||
assignment: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
a = x;
|
||||
const a = 1;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return x;
|
||||
const a = 1;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for_init: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var a = x;
|
||||
var b = y;
|
||||
for (a; b;);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
var b = y;
|
||||
for (x; b;);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch_case: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, z) {
|
||||
var a = x();
|
||||
var b = y();
|
||||
var c = z;
|
||||
switch (a) {
|
||||
default: d();
|
||||
case b: e();
|
||||
case c: f();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, z) {
|
||||
var c = z;
|
||||
switch (x()) {
|
||||
default: d();
|
||||
case y(): e();
|
||||
case c: f();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_27: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(jQuery) {
|
||||
var $;
|
||||
$ = jQuery;
|
||||
$("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
expect: {
|
||||
(function(jQuery) {
|
||||
jQuery("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(b) {
|
||||
var a = b;
|
||||
return b + a;
|
||||
}
|
||||
function f2(b) {
|
||||
var a = b;
|
||||
return b++ + a;
|
||||
}
|
||||
function f3(b) {
|
||||
var a = b++;
|
||||
return b + a;
|
||||
}
|
||||
function f4(b) {
|
||||
var a = b++;
|
||||
return b++ + a;
|
||||
}
|
||||
function f5(b) {
|
||||
var a = function() {
|
||||
return b;
|
||||
}();
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f1(1), f2(1), f3(1), f4(1), f5(1));
|
||||
}
|
||||
expect: {
|
||||
function f1(b) {
|
||||
return b + b;
|
||||
}
|
||||
function f2(b) {
|
||||
var a = b;
|
||||
return b++ + a;
|
||||
}
|
||||
function f3(b) {
|
||||
var a = b++;
|
||||
return b + a;
|
||||
}
|
||||
function f4(b) {
|
||||
var a = b++;
|
||||
return b++ + a;
|
||||
}
|
||||
function f5(b) {
|
||||
var a = function() {
|
||||
return b;
|
||||
}();
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f1(1), f2(1), f3(1), f4(1), f5(1));
|
||||
}
|
||||
expect_stdout: "2 2 3 3 2"
|
||||
}
|
||||
|
||||
issue_1858: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(x) {
|
||||
var a = {}, b = a.b = x;
|
||||
return a.b + b;
|
||||
}(1));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(x) {
|
||||
var a = {}, b = a.b = x;
|
||||
return a.b + b;
|
||||
}(1));
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
anonymous_function: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
f ^= 0;
|
||||
return f * a;
|
||||
}(1));
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
f ^= 0;
|
||||
return f * a;
|
||||
}(1));
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
side_effects_property: {
|
||||
reassign_const_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = [];
|
||||
var b = 0;
|
||||
a[b++] = function() { return 42;};
|
||||
var c = a[b++]();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
var b = 0;
|
||||
a[b++] = function() { return 42;};
|
||||
var c = a[b++]();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
undeclared: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var a;
|
||||
a = x;
|
||||
b = y;
|
||||
return b + a;
|
||||
function f() {
|
||||
const a = 1;
|
||||
++a;
|
||||
return a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
var a;
|
||||
a = x;
|
||||
b = y;
|
||||
return b + a;
|
||||
function f() {
|
||||
const a = 1;
|
||||
++a;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref_scope: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
var a = c++, b = b /= a;
|
||||
return function() {
|
||||
return a;
|
||||
}() + b;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = b /= a = c++;
|
||||
return function() {
|
||||
return a;
|
||||
}() + b;
|
||||
}());
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
chained_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2;
|
||||
var a = 3 / a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 3 / (a = 2);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
chained_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
var a = 2;
|
||||
a = 3 / a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = 3 / (a = 2);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
chained_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a, b) {
|
||||
var c = a, c = b;
|
||||
b++;
|
||||
return c;
|
||||
}(1, 2));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
var c = 1, c = b;
|
||||
b++;
|
||||
return c;
|
||||
}(0, 2));
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
boolean_binary_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a++;
|
||||
(function() {} || a || 3).toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a++;
|
||||
(function() {} || a || 3).toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
boolean_binary_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
c += 1;
|
||||
(function() {
|
||||
c = 1 + c;
|
||||
} || 9).toString();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
c += 1;
|
||||
(function() {
|
||||
c = 1 + c;
|
||||
} || 9).toString();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
inner_lvalues: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = 10;
|
||||
var a = (--b || a || 3).toString(), c = --b + -a;
|
||||
console.log(null, a, b);
|
||||
}
|
||||
expect: {
|
||||
var a, b = 10;
|
||||
var a = (--b || a || 3).toString(), c = --b + -a;
|
||||
console.log(null, a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
double_def: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = x, a = a && y;
|
||||
a();
|
||||
}
|
||||
expect: {
|
||||
var a = x;
|
||||
(a = a && y)();
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_single_reference: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
for (var b in x) {
|
||||
var a = b;
|
||||
b(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
for (var b in x)
|
||||
b(a = b);
|
||||
}
|
||||
}
|
||||
|
||||
unused_orig: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
console.log(function(b) {
|
||||
var a;
|
||||
var c = b;
|
||||
for (var d in c) {
|
||||
var a = c[0];
|
||||
return --b + a;
|
||||
}
|
||||
try {
|
||||
} catch (e) {
|
||||
--b + a;
|
||||
}
|
||||
a && a.NaN;
|
||||
}([2]), a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
console.log(function(b) {
|
||||
var c = b;
|
||||
for (var d in c) {
|
||||
var a = c[0];
|
||||
return --b + a;
|
||||
}
|
||||
a && a.NaN;
|
||||
}([2]), a);
|
||||
}
|
||||
expect_stdout: "3 1"
|
||||
}
|
||||
|
||||
issue_315: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(s) {
|
||||
var w, _i, _len, _ref, _results;
|
||||
_ref = s.trim().split(" ");
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
w = _ref[_i];
|
||||
_results.push(w.toLowerCase());
|
||||
}
|
||||
return _results;
|
||||
}("test"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var w, _i, _len, _ref, _results;
|
||||
for (_results = [], _i = 0, _len = (_ref = "test".trim().split(" ")).length; _i < _len ; _i++)
|
||||
w = _ref[_i], _results.push(w.toLowerCase());
|
||||
return _results;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
lvalues_def: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
var a = b++, b = +function() {}();
|
||||
a && a[a++];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
var a = b++, b = +void 0;
|
||||
a && a[a++];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
compound_assignment: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
a = 1;
|
||||
a += a + 2;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = 1;
|
||||
a += a + 2;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "4"
|
||||
}
|
||||
|
||||
issue_2187_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function(foo) {
|
||||
foo();
|
||||
var a = 2;
|
||||
console.log(a);
|
||||
}(function() {
|
||||
console.log(a);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
!function(foo) {
|
||||
foo();
|
||||
var a = 2;
|
||||
console.log(a);
|
||||
}(function() {
|
||||
console.log(a);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2187_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var b = 1;
|
||||
console.log(function(a) {
|
||||
return a && ++b;
|
||||
}(b--));
|
||||
}
|
||||
expect: {
|
||||
var b = 1;
|
||||
console.log(function(a) {
|
||||
return b-- && ++b;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2187_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var b = 1;
|
||||
console.log(function(a) {
|
||||
return a && ++b;
|
||||
}(b--));
|
||||
}
|
||||
expect: {
|
||||
var b = 1;
|
||||
console.log(b-- && ++b);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -979,12 +979,12 @@ delete_conditional_1: {
|
||||
console.log(delete (1 ? 0 / 0 : x));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((NaN, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -1006,12 +1006,12 @@ delete_conditional_2: {
|
||||
console.log(delete (0 ? x : 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((Infinity, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((NaN, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
166
test/compress/const.js
Normal file
166
test/compress/const.js
Normal file
@@ -0,0 +1,166 @@
|
||||
issue_1191: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function foo(rot) {
|
||||
const rotTol = 5;
|
||||
if (rot < -rotTol || rot > rotTol)
|
||||
bar();
|
||||
baz();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(rot) {
|
||||
(rot < -5 || rot > 5) && bar();
|
||||
baz();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1194: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function f1() {const a = "X"; return a + a;}
|
||||
function f2() {const aa = "X"; return aa + aa;}
|
||||
function f3() {const aaa = "X"; return aaa + aaa;}
|
||||
}
|
||||
expect: {
|
||||
function f1(){return"XX"}
|
||||
function f2(){return"XX"}
|
||||
function f3(){return"XX"}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1396: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function foo(a) {
|
||||
const VALUE = 1;
|
||||
console.log(2 | VALUE);
|
||||
console.log(VALUE + 1);
|
||||
console.log(VALUE);
|
||||
console.log(a & VALUE);
|
||||
}
|
||||
function bar() {
|
||||
const s = "01234567890123456789";
|
||||
console.log(s + s + s + s + s);
|
||||
|
||||
const CONSTANT = "abc";
|
||||
console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(a) {
|
||||
console.log(3);
|
||||
console.log(2);
|
||||
console.log(1);
|
||||
console.log(1 & a);
|
||||
}
|
||||
function bar() {
|
||||
const s = "01234567890123456789";
|
||||
console.log(s + s + s + s + s);
|
||||
|
||||
console.log("abcabcabcabcabc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unused_regexp_literal: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
}
|
||||
input: {
|
||||
function f(){ var a = /b/; }
|
||||
}
|
||||
expect: {
|
||||
function f(){}
|
||||
}
|
||||
}
|
||||
|
||||
regexp_literal_not_const: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
(function(){
|
||||
var result;
|
||||
const s = 'acdabcdeabbb';
|
||||
const REGEXP_LITERAL = /ab*/g;
|
||||
while (result = REGEXP_LITERAL.exec(s)) {
|
||||
console.log(result[0]);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var result;
|
||||
const REGEXP_LITERAL = /ab*/g;
|
||||
while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -31,7 +31,7 @@ dead_code_2_should_warn: {
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
throw "foo";
|
||||
// completely discarding the `if` would introduce some
|
||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||
// we copy any declarations to the upper scope.
|
||||
@@ -46,60 +46,16 @@ dead_code_2_should_warn: {
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
throw "foo";
|
||||
var x;
|
||||
function g(){};
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_2_should_warn_strict: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
// completely discarding the `if` would introduce some
|
||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||
// we copy any declarations to the upper scope.
|
||||
if (x) {
|
||||
y();
|
||||
var x;
|
||||
function g(){};
|
||||
// but nested declarations should not be kept.
|
||||
(function(){
|
||||
var q;
|
||||
function y(){};
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
var x;
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more: {
|
||||
@@ -122,7 +78,6 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
foo();
|
||||
var moo;
|
||||
}
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
var foo;
|
||||
@@ -131,46 +86,133 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
// as for the for, it should keep:
|
||||
var x = 10, y;
|
||||
var moo;
|
||||
bar();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more_strict: {
|
||||
dead_code_const_declaration: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
reduce_vars : true,
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
var unused;
|
||||
const CONST_FOO = false;
|
||||
if (CONST_FOO) {
|
||||
console.log("unreachable");
|
||||
var foo;
|
||||
var moo;
|
||||
function bar() {}
|
||||
}
|
||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
||||
asdf();
|
||||
foo();
|
||||
var moo;
|
||||
}
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo;
|
||||
// nothing for the while
|
||||
// as for the for, it should keep:
|
||||
var x = 10, y;
|
||||
var unused;
|
||||
const CONST_FOO = !1;
|
||||
var moo;
|
||||
bar();
|
||||
function bar() {}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dead_code_const_annotation: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
toplevel : true,
|
||||
};
|
||||
input: {
|
||||
var unused;
|
||||
/** @const */ var CONST_FOO_ANN = false;
|
||||
if (CONST_FOO_ANN) {
|
||||
console.log("unreachable");
|
||||
var moo;
|
||||
function bar() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var unused;
|
||||
var CONST_FOO_ANN = !1;
|
||||
var moo;
|
||||
function bar() {}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dead_code_const_annotation_regex: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : 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;
|
||||
CONST_FOO_ANN && console.log('reachable');
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dead_code_const_annotation_complex_scope: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
toplevel : true,
|
||||
};
|
||||
input: {
|
||||
var unused_var;
|
||||
/** @const */ var test = 'test';
|
||||
// @const
|
||||
var CONST_FOO_ANN = false;
|
||||
var unused_var_2;
|
||||
if (CONST_FOO_ANN) {
|
||||
console.log("unreachable");
|
||||
var moo;
|
||||
function bar() {}
|
||||
}
|
||||
if (test === 'test') {
|
||||
var beef = 'good';
|
||||
/** @const */ var meat = 'beef';
|
||||
var pork = 'bad';
|
||||
if (meat === 'pork') {
|
||||
console.log('also unreachable');
|
||||
} else if (pork === 'good') {
|
||||
console.log('reached, not const');
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var unused_var;
|
||||
var test = 'test';
|
||||
var CONST_FOO_ANN = !1;
|
||||
var unused_var_2;
|
||||
var moo;
|
||||
function bar() {}
|
||||
var beef = 'good';
|
||||
var meat = 'beef';
|
||||
var pork = 'bad';
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
try_catch_finally: {
|
||||
|
||||
@@ -649,6 +649,37 @@ drop_value: {
|
||||
}
|
||||
}
|
||||
|
||||
const_assign: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
const b = 2;
|
||||
return 1 + b;
|
||||
}
|
||||
|
||||
function g() {
|
||||
const b = 2;
|
||||
b = 3;
|
||||
return 1 + b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
function g() {
|
||||
const b = 2;
|
||||
b = 3;
|
||||
return 1 + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
cascade: true,
|
||||
@@ -751,12 +782,12 @@ issue_1583: {
|
||||
expect: {
|
||||
function m(t) {
|
||||
(function(e) {
|
||||
t = e();
|
||||
})(function() {
|
||||
return (function(a) {
|
||||
return a;
|
||||
})(function(a) {});
|
||||
});
|
||||
t = (function() {
|
||||
return (function(a) {
|
||||
return a;
|
||||
})(function(a) {});
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,6 +816,10 @@ issue_1709: {
|
||||
var x = 1;
|
||||
return x;
|
||||
}(),
|
||||
function y() {
|
||||
const y = 2;
|
||||
return y;
|
||||
}(),
|
||||
function z() {
|
||||
function z() {}
|
||||
return z;
|
||||
@@ -797,6 +832,10 @@ issue_1709: {
|
||||
var x = 1;
|
||||
return x;
|
||||
}(),
|
||||
function() {
|
||||
const y = 2;
|
||||
return y;
|
||||
}(),
|
||||
function() {
|
||||
function z() {}
|
||||
return z;
|
||||
@@ -896,8 +935,7 @@ issue_1715_3: {
|
||||
try {
|
||||
console;
|
||||
} catch (a) {
|
||||
var a;
|
||||
x();
|
||||
var a = x();
|
||||
}
|
||||
}
|
||||
f();
|
||||
@@ -992,33 +1030,6 @@ delete_assign_2: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
drop_var: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(a, b);
|
||||
var a = 1, b = 2;
|
||||
console.log(a, b);
|
||||
var a = 3;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
console.log(a, b);
|
||||
var a = 1, b = 2;
|
||||
console.log(a, b);
|
||||
a = 3;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined undefined",
|
||||
"1 2",
|
||||
"3 2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1830_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
@@ -1054,102 +1065,27 @@ issue_1830_2: {
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_1838: {
|
||||
reassign_const: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var b = a;
|
||||
while (c);
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
"function f() {",
|
||||
" for (a; c; ) ;",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
var_catch_toplevel: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
a--;
|
||||
try {
|
||||
a++;
|
||||
} catch(a) {
|
||||
if (a) var a;
|
||||
var a = 10;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
a--;
|
||||
try {
|
||||
a++;
|
||||
} catch(a) {
|
||||
var a;
|
||||
}
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2105: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
cascade: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function(factory) {
|
||||
factory();
|
||||
}( function() {
|
||||
return function(fn) {
|
||||
fn()().prop();
|
||||
}( function() {
|
||||
function bar() {
|
||||
var quux = function() {
|
||||
console.log("PASS");
|
||||
}, foo = function() {
|
||||
console.log;
|
||||
quux();
|
||||
};
|
||||
return { prop: foo };
|
||||
}
|
||||
return bar;
|
||||
} );
|
||||
});
|
||||
function f() {
|
||||
const a = 1;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var quux = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
return {
|
||||
prop: function() {
|
||||
console.log;
|
||||
quux();
|
||||
}
|
||||
};
|
||||
})().prop();
|
||||
function f() {
|
||||
const a = 1;
|
||||
return a = 2, a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -644,19 +644,17 @@ unsafe_prototype_function: {
|
||||
call_args: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
const a = 1;
|
||||
console.log(a);
|
||||
+function(a) {
|
||||
return a;
|
||||
}(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
const a = 1;
|
||||
console.log(1);
|
||||
+(1, 1);
|
||||
}
|
||||
@@ -666,20 +664,19 @@ call_args: {
|
||||
call_args_drop_param: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
const a = 1;
|
||||
console.log(a);
|
||||
+function(a) {
|
||||
return a;
|
||||
}(a, b);
|
||||
}
|
||||
expect: {
|
||||
const a = 1;
|
||||
console.log(1);
|
||||
+(b, 1);
|
||||
}
|
||||
@@ -782,15 +779,13 @@ unsafe_charAt_noop: {
|
||||
input: {
|
||||
console.log(
|
||||
s.charAt(0),
|
||||
"string".charAt(x),
|
||||
(typeof x).charAt()
|
||||
"string".charAt(x)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
s.charAt(0),
|
||||
"string".charAt(x),
|
||||
(typeof x)[0]
|
||||
"string".charAt(x)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -927,12 +922,12 @@ delete_binary_1: {
|
||||
console.log(delete (true && (0 / 0)));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((NaN, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -953,12 +948,12 @@ delete_binary_2: {
|
||||
console.log(delete (false || (0 / 0)));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((Infinity, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((NaN, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -1041,31 +1036,3 @@ issue_1964_2: {
|
||||
}
|
||||
expect_stdout: "b"
|
||||
}
|
||||
|
||||
array_slice_index: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log([1,2,3].slice(1)[1]);
|
||||
}
|
||||
expect: {
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
string_charCodeAt: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo".charCodeAt("bar".length));
|
||||
}
|
||||
expect: {
|
||||
console.log(NaN);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ iifes_returning_constants_keep_fargs_true: {
|
||||
join_vars : true,
|
||||
reduce_vars : true,
|
||||
cascade : true,
|
||||
inline : true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return -1.23; }());
|
||||
@@ -57,7 +56,6 @@ iifes_returning_constants_keep_fargs_false: {
|
||||
join_vars : true,
|
||||
reduce_vars : true,
|
||||
cascade : true,
|
||||
inline : true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return -1.23; }());
|
||||
@@ -84,7 +82,6 @@ issue_485_crashing_1530: {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
@@ -115,8 +112,9 @@ issue_1841_1: {
|
||||
expect: {
|
||||
var b = 10;
|
||||
!function() {
|
||||
for (var key in "hi")
|
||||
for (var key in "hi") {
|
||||
b = 42;
|
||||
}
|
||||
}(--b);
|
||||
console.log(b);
|
||||
}
|
||||
@@ -141,370 +139,11 @@ issue_1841_2: {
|
||||
expect: {
|
||||
var b = 10;
|
||||
!function(arg) {
|
||||
for (var key in "hi")
|
||||
for (var key in "hi") {
|
||||
arg.baz, b = 42;
|
||||
}
|
||||
}(--b);
|
||||
console.log(b);
|
||||
}
|
||||
expect_exact: "42"
|
||||
}
|
||||
|
||||
function_returning_constant_literal: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
toplevel: true,
|
||||
evaluate: true,
|
||||
cascade: true,
|
||||
unused: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
function greeter() {
|
||||
return { message: 'Hello there' };
|
||||
}
|
||||
var greeting = greeter();
|
||||
console.log(greeting.message);
|
||||
}
|
||||
expect: {
|
||||
console.log("Hello there");
|
||||
}
|
||||
expect_stdout: "Hello there"
|
||||
}
|
||||
|
||||
hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
}
|
||||
input: {
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
function f() {}
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
function g() {}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
function g() {}
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1 'function' 'function'",
|
||||
"2 'function' 'function'",
|
||||
"4 'function' 'function'",
|
||||
"5 'function' 'function'",
|
||||
"6 'function' 'function'",
|
||||
]
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
hoist_funs_strict: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
function f() {}
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
function g() {}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function g() {}
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
function f() {}
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1 'undefined' 'function'",
|
||||
"2 'undefined' 'function'",
|
||||
"4 'function' 'function'",
|
||||
"5 'function' 'function'",
|
||||
"6 'undefined' 'function'",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_203: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
unsafe_Func: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var m = {};
|
||||
var fn = Function("require", "module", "exports", "module.exports = 42;");
|
||||
fn(null, m, m.exports);
|
||||
console.log(m.exports);
|
||||
}
|
||||
expect: {
|
||||
var m = {};
|
||||
var fn = Function("n,o", "o.exports=42");
|
||||
fn(null, m, m.exports);
|
||||
console.log(m.exports);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
no_webkit: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2084: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
!function() {
|
||||
!function(c) {
|
||||
c = 1 + c;
|
||||
var c = 0;
|
||||
function f14(a_1) {
|
||||
if (c = 1 + c, 0 !== 23..toString())
|
||||
c = 1 + c, a_1 && (a_1[0] = 0);
|
||||
}
|
||||
f14();
|
||||
}(-1);
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
!function(c) {
|
||||
c = 1 + c,
|
||||
c = 1 + (c = 0),
|
||||
0 !== 23..toString() && (c = 1 + c);
|
||||
}(-1),
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_2097: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (e) {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
}
|
||||
f(1);
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (e) {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
}(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2101: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
a = {};
|
||||
console.log(function() {
|
||||
return function() {
|
||||
return this.a;
|
||||
}();
|
||||
}() === function() {
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
a = {};
|
||||
console.log(function() {
|
||||
return this.a;
|
||||
}() === a);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
inner_ref: {
|
||||
options = {
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return function() {
|
||||
return a;
|
||||
}();
|
||||
}(1), function(a) {
|
||||
return function(a) {
|
||||
return a;
|
||||
}();
|
||||
}(2));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return a;
|
||||
}(1), function(a) {
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "1 undefined"
|
||||
}
|
||||
|
||||
issue_2107: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
!function() {
|
||||
c++;
|
||||
}(c++ + new function() {
|
||||
this.a = 0;
|
||||
var a = (c = c + 1) + (c = 1 + c);
|
||||
return c++ + a;
|
||||
}());
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
c++, new function() {
|
||||
this.a = 0, c = 1 + (c += 1), c++;
|
||||
}(), c++, console.log(c);
|
||||
}
|
||||
expect_stdout: "5"
|
||||
}
|
||||
|
||||
issue_2114_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
!function(a) {
|
||||
a = 0;
|
||||
}([ {
|
||||
0: c = c + 1,
|
||||
length: c = 1 + c
|
||||
}, typeof void function a() {
|
||||
var b = function f1(a) {
|
||||
}(b && (b.b += (c = c + 1, 0)));
|
||||
}() ]);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
c = 1 + (c += 1), function() {
|
||||
var b = void (b && (b.b += (c += 1, 0)));
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_2114_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
!function(a) {
|
||||
a = 0;
|
||||
}([ {
|
||||
0: c = c + 1,
|
||||
length: c = 1 + c
|
||||
}, typeof void function a() {
|
||||
var b = function f1(a) {
|
||||
}(b && (b.b += (c = c + 1, 0)));
|
||||
}() ]);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
c = 1 + (c += 1), function() {
|
||||
var b = void (b && (b.b += (c += 1, 0)));
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ mixed: {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var FOO = { BAR: 0 };
|
||||
const FOO = { BAR: 0 };
|
||||
console.log(FOO.BAR);
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
@@ -130,7 +130,7 @@ mixed: {
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect: {
|
||||
var FOO = { BAR: 0 };
|
||||
const FOO = { BAR: 0 };
|
||||
console.log("moo");
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
@@ -160,38 +160,3 @@ issue_1801: {
|
||||
console.log(!0);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1986: {
|
||||
options = {
|
||||
global_defs: {
|
||||
"@alert": "console.log",
|
||||
},
|
||||
}
|
||||
input: {
|
||||
alert(42);
|
||||
}
|
||||
expect: {
|
||||
console.log(42);
|
||||
}
|
||||
}
|
||||
|
||||
issue_2167: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
"@isDevMode": "function(){}",
|
||||
},
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (isDevMode()) {
|
||||
greetOverlord();
|
||||
}
|
||||
doWork();
|
||||
}
|
||||
expect: {
|
||||
doWork();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,27 +302,3 @@ issue_1437_conditionals: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_512: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
if (b()) {
|
||||
c();
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
if (!b()) throw e;
|
||||
c();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,137 +116,3 @@ non_hoisted_function_after_return_2b: {
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar();
|
||||
not_called1();
|
||||
} else {
|
||||
return baz();
|
||||
not_called2();
|
||||
}
|
||||
function bar() { return 7; }
|
||||
return not_reached;
|
||||
function UnusedFunction() {}
|
||||
function baz() { return 8; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return x ? bar() : baz();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "8 7"
|
||||
expect_warnings: [
|
||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:131,16]',
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:134,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:137,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:138,21]"
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
var a = not_called(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b = not_called(2);
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) { return 7 - x; }
|
||||
function nope() {}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:173,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:173,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:176,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:176,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:173,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:180,21]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:181,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:176,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:178,16]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b;
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) { return 7 - x; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
// duplicate warnings no longer emitted
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:225,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:225,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:227,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:227,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
const_declaration: {
|
||||
options = {
|
||||
evaluate: true
|
||||
};
|
||||
|
||||
input: {
|
||||
const goog = goog || {};
|
||||
}
|
||||
expect: {
|
||||
const goog = goog || {};
|
||||
}
|
||||
}
|
||||
|
||||
const_pragma: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -1,91 +1,90 @@
|
||||
multiple_functions: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window );
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
single_function: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( window );
|
||||
function f() {}
|
||||
|
||||
if ( window );
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
deeply_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
if ( !document ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
function h() {}
|
||||
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window )
|
||||
if (document);
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
not_hoisted_when_already_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( foo ) function f() {}
|
||||
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
@@ -95,70 +94,3 @@ not_hoisted_when_already_nested: {
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
defun_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
if (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_else_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
else return;
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
issue_1321_no_debug: {
|
||||
mangle_props = {
|
||||
keep_quoted: true
|
||||
ignore_quoted: true
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
@@ -10,16 +10,16 @@ issue_1321_no_debug: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.o = 1;
|
||||
x["a"] = 2 * x.o;
|
||||
console.log(x.o, x["a"]);
|
||||
x.b = 1;
|
||||
x["a"] = 2 * x.b;
|
||||
console.log(x.b, x["a"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_debug: {
|
||||
mangle_props = {
|
||||
keep_quoted: true,
|
||||
ignore_quoted: true,
|
||||
debug: ""
|
||||
}
|
||||
input: {
|
||||
@@ -30,16 +30,16 @@ issue_1321_debug: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.o = 1;
|
||||
x["_$foo$_"] = 2 * x.o;
|
||||
console.log(x.o, x["_$foo$_"]);
|
||||
x.a = 1;
|
||||
x["_$foo$_"] = 2 * x.a;
|
||||
console.log(x.a, x["_$foo$_"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_with_quoted: {
|
||||
mangle_props = {
|
||||
keep_quoted: false
|
||||
ignore_quoted: false
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
@@ -49,9 +49,9 @@ issue_1321_with_quoted: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.o = 1;
|
||||
x["x"] = 2 * x.o;
|
||||
console.log(x.o, x["x"]);
|
||||
x.a = 1;
|
||||
x["b"] = 2 * x.a;
|
||||
console.log(x.a, x["b"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ typeof_eq_undefined: {
|
||||
typeof_eq_undefined_ie8: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
ie8: true,
|
||||
screw_ie8: false
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
screw_ie8: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
@@ -16,10 +16,10 @@ screw_ie8: {
|
||||
|
||||
support_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
@@ -85,3 +85,15 @@ unsafe_undefined: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
runtime_error: {
|
||||
input: {
|
||||
const a = 1;
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
const a = 1;
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ chained_evaluation_1: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
f(1).bar = 1;
|
||||
var c;
|
||||
c = f(1);
|
||||
c.bar = 1;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
@@ -44,8 +46,9 @@ chained_evaluation_2: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
var b = "long piece of string";
|
||||
f(b).bar = b;
|
||||
var c, b = "long piece of string";
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
mangle_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -22,11 +22,11 @@ mangle_catch: {
|
||||
|
||||
mangle_catch_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -44,11 +44,11 @@ mangle_catch_ie8: {
|
||||
|
||||
mangle_catch_var: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -66,11 +66,11 @@ mangle_catch_var: {
|
||||
|
||||
mangle_catch_var_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
|
||||
|
||||
mangle_catch_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -110,11 +110,11 @@ mangle_catch_toplevel: {
|
||||
|
||||
mangle_catch_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
|
||||
|
||||
mangle_catch_var_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -154,11 +154,11 @@ mangle_catch_var_toplevel: {
|
||||
|
||||
mangle_catch_var_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
|
||||
|
||||
mangle_catch_redef_1: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -198,11 +198,11 @@ mangle_catch_redef_1: {
|
||||
|
||||
mangle_catch_redef_1_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
|
||||
|
||||
mangle_catch_redef_1_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
|
||||
|
||||
mangle_catch_redef_1_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
|
||||
|
||||
mangle_catch_redef_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -285,11 +285,11 @@ mangle_catch_redef_2: {
|
||||
|
||||
mangle_catch_redef_2_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
@@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
|
||||
|
||||
mangle_catch_redef_2_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
@@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
|
||||
|
||||
mangle_catch_redef_2_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function_iife_catch: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
@@ -21,7 +21,7 @@ function_iife_catch: {
|
||||
|
||||
function_iife_catch_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
@@ -42,7 +42,7 @@ function_iife_catch_ie8: {
|
||||
|
||||
function_catch_catch: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var o = 0;
|
||||
@@ -70,7 +70,7 @@ function_catch_catch: {
|
||||
|
||||
function_catch_catch_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var o = 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ numeric_literal: {
|
||||
' 42: 2,',
|
||||
' "42": 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' a: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' "1e+42": 8',
|
||||
@@ -92,7 +92,7 @@ numeric_literal: {
|
||||
'',
|
||||
'console.log(obj[42], obj["42"]);',
|
||||
'',
|
||||
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
||||
'',
|
||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||
]
|
||||
@@ -173,32 +173,32 @@ identifier: {
|
||||
}
|
||||
expect: {
|
||||
var obj = {
|
||||
e: 1,
|
||||
t: 2,
|
||||
n: 3,
|
||||
a: 4,
|
||||
i: 5,
|
||||
o: 6,
|
||||
r: 7,
|
||||
l: 8,
|
||||
s: 9,
|
||||
c: 10,
|
||||
f: 11,
|
||||
u: 12,
|
||||
d: 13,
|
||||
h: 14,
|
||||
p: 15,
|
||||
b: 16,
|
||||
v: 17,
|
||||
w: 18,
|
||||
y: 19,
|
||||
g: 20,
|
||||
m: 21,
|
||||
k: 22,
|
||||
x: 23,
|
||||
j: 24,
|
||||
z: 25,
|
||||
q: 26,
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
e: 5,
|
||||
f: 6,
|
||||
g: 7,
|
||||
h: 8,
|
||||
i: 9,
|
||||
j: 10,
|
||||
k: 11,
|
||||
l: 12,
|
||||
m: 13,
|
||||
n: 14,
|
||||
o: 15,
|
||||
p: 16,
|
||||
q: 17,
|
||||
r: 18,
|
||||
s: 19,
|
||||
t: 20,
|
||||
u: 21,
|
||||
v: 22,
|
||||
w: 23,
|
||||
x: 24,
|
||||
y: 25,
|
||||
z: 26,
|
||||
A: 27,
|
||||
B: 28,
|
||||
C: 29,
|
||||
@@ -229,11 +229,11 @@ identifier: {
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
aa: 57,
|
||||
ba: 58,
|
||||
ca: 59,
|
||||
da: 60,
|
||||
ea: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
unary_prefix: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -11,6 +10,10 @@ unary_prefix: {
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect_exact: "console.log(-2/3);"
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return -2 / 3;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ mixed: {
|
||||
}
|
||||
}
|
||||
input: {
|
||||
var ENV = 3;
|
||||
const ENV = 3;
|
||||
var FOO = 4;
|
||||
f(ENV * 10);
|
||||
--FOO;
|
||||
@@ -49,7 +49,7 @@ mixed: {
|
||||
x = DEBUG;
|
||||
}
|
||||
expect: {
|
||||
var ENV = 3;
|
||||
const ENV = 3;
|
||||
var FOO = 4;
|
||||
f(10);
|
||||
--FOO;
|
||||
@@ -60,7 +60,7 @@ mixed: {
|
||||
x = 0;
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,14]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||
|
||||
@@ -1,493 +0,0 @@
|
||||
collapse_vars_constants: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(x) {
|
||||
var a = 4, b = x.prop, c = 5, d = sideeffect1(), e = sideeffect2();
|
||||
return b + (function() { return d - a * e - c; })();
|
||||
}
|
||||
function f2(x) {
|
||||
var a = 4, b = x.prop, c = 5, not_used = sideeffect1(), e = sideeffect2();
|
||||
return b + (function() { return -a * e - c; })();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1(x) {
|
||||
var b = x.prop, d = sideeffect1(), e = sideeffect2();
|
||||
return b + (d - 4 * e - 5);
|
||||
}
|
||||
function f2(x) {
|
||||
var b = x.prop;
|
||||
sideeffect1();
|
||||
return b + (-4 * sideeffect2() - 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f5(b) {
|
||||
var a = function() {
|
||||
return b;
|
||||
}();
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f5(1));
|
||||
}
|
||||
expect: {
|
||||
function f5(b) {
|
||||
var a = b;
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f5(1));
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
ref_scope: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
var a = c++, b = b /= a;
|
||||
return function() {
|
||||
return a;
|
||||
}() + b;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = b /= a = c++;
|
||||
return a + b;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
safe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
unsafe: false,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var a, c;
|
||||
console.log(function(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}(1)());
|
||||
}
|
||||
expect: {
|
||||
var a, c;
|
||||
console.log(a ? b : c ? d : void 0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? foo(true) : bar(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? foo(true) : bar(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))()()();'
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
};
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
this.x = a;
|
||||
console.log(this);
|
||||
};
|
||||
}(7))();
|
||||
}
|
||||
expect: {
|
||||
new function() {
|
||||
this.x = 7,
|
||||
console.log(this);
|
||||
}();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1288_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
};
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
(function f() {})();
|
||||
}
|
||||
if (!x) {
|
||||
(function() {
|
||||
x = {};
|
||||
})();
|
||||
}
|
||||
if (y)
|
||||
(function() {})();
|
||||
else
|
||||
(function(z) {
|
||||
return z;
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w;
|
||||
x || (x = {});
|
||||
y;
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_in_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(a, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
x(a, b, c, d);
|
||||
}
|
||||
x(a, b, c, d);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in x(1, b, c)) {
|
||||
var c = 3, d = 4;
|
||||
x(1, b, c, d);
|
||||
}
|
||||
x(1, b, c, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
return g(a + 1);
|
||||
})(2);
|
||||
}
|
||||
expect: {
|
||||
g(3);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1758: {
|
||||
options = {
|
||||
inline: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(c) {
|
||||
var undefined = 42;
|
||||
return function() {
|
||||
c--;
|
||||
c--, c.toString();
|
||||
return;
|
||||
}();
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(c) {
|
||||
var undefined = 42;
|
||||
return c--, c--, void c.toString();
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
wrap_iife: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
}
|
||||
|
||||
wrap_iife_in_expression: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
expect_exact: 'foo=bar();'
|
||||
}
|
||||
|
||||
wrap_iife_in_return_call: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return (function() {
|
||||
console.log('test')
|
||||
})();
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))();'
|
||||
}
|
||||
|
||||
pure_annotation_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(function() {
|
||||
console.log("hello");
|
||||
}());
|
||||
}
|
||||
expect_exact: ""
|
||||
}
|
||||
|
||||
pure_annotation_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(function(n) {
|
||||
console.log("hello", n);
|
||||
}(42));
|
||||
}
|
||||
expect_exact: ""
|
||||
}
|
||||
|
||||
drop_fargs: {
|
||||
options = {
|
||||
cascade: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
keep_fargs: {
|
||||
options = {
|
||||
cascade: true,
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
@@ -159,7 +159,7 @@ negate_iife_4: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
(function(){ return t })() ? console.log(true) : console.log(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -183,7 +183,7 @@ negate_iife_5: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -207,7 +207,7 @@ negate_iife_5_off: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,37 @@
|
||||
dont_reuse_prop: {
|
||||
mangle_props = {
|
||||
regex: /asd/
|
||||
}
|
||||
};
|
||||
|
||||
input: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.a = 123;
|
||||
obj.asd = 256;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.a = 123;
|
||||
obj.b = 256;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
}
|
||||
|
||||
unmangleable_props_should_always_be_reserved: {
|
||||
mangle_props = {
|
||||
regex: /asd/
|
||||
}
|
||||
};
|
||||
|
||||
input: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.asd = 256;
|
||||
obj.a = 123;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.b = 256;
|
||||
obj.a = 123;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
}
|
||||
}
|
||||
@@ -146,6 +146,50 @@ parse_do_while_without_semicolon: {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
keep_collapse_const_in_own_block_scope: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true
|
||||
}
|
||||
input: {
|
||||
var i=2;
|
||||
const c=5;
|
||||
while(i--)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var i=2;
|
||||
const c=5;
|
||||
for(;i--;)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
keep_collapse_const_in_own_block_scope_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true
|
||||
}
|
||||
input: {
|
||||
const c=5;
|
||||
var i=2; // Moves to loop, while it did not in previous test
|
||||
while(i--)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
const c=5;
|
||||
for(var i=2;i--;)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
options = {
|
||||
loops: true,
|
||||
@@ -201,7 +245,7 @@ issue_1532: {
|
||||
issue_186: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -220,7 +264,7 @@ issue_186: {
|
||||
issue_186_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -239,7 +283,7 @@ issue_186_ie8: {
|
||||
issue_186_beautify: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -266,7 +310,7 @@ issue_186_beautify: {
|
||||
issue_186_beautify_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -296,7 +340,7 @@ issue_186_bracketize: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -316,7 +360,7 @@ issue_186_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -336,7 +380,7 @@ issue_186_beautify_bracketize: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
@@ -368,7 +412,7 @@ issue_186_beautify_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
||||
@@ -22,25 +22,27 @@ negate_iife_1_off: {
|
||||
|
||||
negate_iife_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
negate_iife: true
|
||||
};
|
||||
input: {
|
||||
(function(){ return {} })().x = 10; // should not transform this one
|
||||
}
|
||||
expect: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
expect_exact: "({}).x=10;"
|
||||
}
|
||||
|
||||
negate_iife_2_side_effects: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return {} })().x = 10; // should not transform this one
|
||||
}
|
||||
expect: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
expect_exact: "({}).x=10;"
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
@@ -60,7 +62,6 @@ negate_iife_3_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
@@ -103,7 +104,6 @@ negate_iife_3_off_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
eval_let_6: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: ""
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
eval_let_4: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: SyntaxError("Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")
|
||||
node_version: "4"
|
||||
}
|
||||
|
||||
eval_let_0: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: SyntaxError("Unexpected identifier")
|
||||
node_version: "<=0.12"
|
||||
}
|
||||
@@ -13,7 +13,7 @@ keep_properties: {
|
||||
dot_properties: {
|
||||
options = {
|
||||
properties: true,
|
||||
ie8: true,
|
||||
screw_ie8: false
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
@@ -36,7 +36,7 @@ dot_properties: {
|
||||
dot_properties_es5: {
|
||||
options = {
|
||||
properties: true,
|
||||
ie8: false,
|
||||
screw_ie8: true
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
@@ -125,7 +125,7 @@ evaluate_string_length: {
|
||||
|
||||
mangle_properties: {
|
||||
mangle_props = {
|
||||
keep_quoted: false
|
||||
ignore_quoted: false
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
@@ -135,11 +135,11 @@ mangle_properties: {
|
||||
a['run']({color: "blue", foo: "baz"});
|
||||
}
|
||||
expect: {
|
||||
a["o"] = "bar";
|
||||
a.a = "red";
|
||||
x = {r: 10};
|
||||
a.b(x.r, a.o);
|
||||
a['b']({a: "blue", o: "baz"});
|
||||
a["a"] = "bar";
|
||||
a.b = "red";
|
||||
x = {c: 10};
|
||||
a.d(x.c, a.a);
|
||||
a['d']({b: "blue", a: "baz"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ mangle_unquoted_properties: {
|
||||
properties: false
|
||||
}
|
||||
mangle_props = {
|
||||
keep_quoted: true
|
||||
ignore_quoted: true
|
||||
}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
@@ -177,16 +177,16 @@ mangle_unquoted_properties: {
|
||||
function f1() {
|
||||
a["foo"] = "bar";
|
||||
a.color = "red";
|
||||
a.o = 2;
|
||||
x = {"bar": 10, f: 7};
|
||||
a.f = 9;
|
||||
a.b = 2;
|
||||
x = {"bar": 10, c: 7};
|
||||
a.c = 9;
|
||||
}
|
||||
function f2() {
|
||||
a.foo = "bar";
|
||||
a['color'] = "red";
|
||||
x = {bar: 10, f: 7};
|
||||
a.f = 9;
|
||||
a.o = 3;
|
||||
x = {bar: 10, c: 7};
|
||||
a.c = 9;
|
||||
a.b = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,12 +233,12 @@ mangle_debug_suffix: {
|
||||
}
|
||||
}
|
||||
|
||||
mangle_debug_suffix_keep_quoted: {
|
||||
mangle_debug_suffix_ignore_quoted: {
|
||||
options = {
|
||||
properties: false
|
||||
}
|
||||
mangle_props = {
|
||||
keep_quoted: true,
|
||||
ignore_quoted: true,
|
||||
debug: "XYZ",
|
||||
reserved: []
|
||||
}
|
||||
|
||||
@@ -178,210 +178,3 @@ impure_getter_2: {
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_2110_1: {
|
||||
options = {
|
||||
cascade: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function f() {}
|
||||
function g() {
|
||||
return this;
|
||||
}
|
||||
f.g = g;
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function f() {}
|
||||
return f.g = function() {
|
||||
return this;
|
||||
}, f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2110_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function f() {}
|
||||
function g() {
|
||||
return this;
|
||||
}
|
||||
f.g = g;
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function f() {}
|
||||
f.g = function() {
|
||||
return this;
|
||||
};
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
set_immutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
1..foo += "";
|
||||
if (1..foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_immutable_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_immutable_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
1..foo += "";
|
||||
if (1..foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_4: {
|
||||
options = {
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_mutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function a() {
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function a() {
|
||||
if (a.foo += "") console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_mutable_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
!function a() {
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function a() {
|
||||
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ reduce_vars: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
inline : true,
|
||||
global_defs : {
|
||||
C : 0
|
||||
},
|
||||
@@ -54,7 +53,9 @@ reduce_vars: {
|
||||
console.log(a - 5);
|
||||
eval("console.log(a);");
|
||||
})(eval);
|
||||
"yes";
|
||||
(function() {
|
||||
return "yes";
|
||||
})();
|
||||
console.log(A + 1);
|
||||
}
|
||||
expect_stdout: true
|
||||
@@ -65,7 +66,7 @@ modified: {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
unused : true,
|
||||
unused : true
|
||||
}
|
||||
input: {
|
||||
function f0() {
|
||||
@@ -135,11 +136,12 @@ modified: {
|
||||
}
|
||||
|
||||
function f2() {
|
||||
3;
|
||||
var b = 2;
|
||||
b = 3;
|
||||
console.log(1 + b);
|
||||
console.log(b + 3);
|
||||
console.log(4);
|
||||
console.log(6);
|
||||
console.log(4);
|
||||
console.log(7);
|
||||
console.log(1 + b + 3);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
@@ -388,11 +390,12 @@ passes: {
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
3;
|
||||
var b = 2;
|
||||
b = 3;
|
||||
console.log(1 + b);
|
||||
console.log(b + 3);
|
||||
console.log(4);
|
||||
console.log(6);
|
||||
console.log(4);
|
||||
console.log(7);
|
||||
console.log(1 + b + 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,7 +588,7 @@ inner_var_label: {
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_1: {
|
||||
inner_var_for: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
@@ -614,29 +617,6 @@ inner_var_for_1: {
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a = 1;
|
||||
for (var b = 1; --b;) var a = 2;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
a = 1;
|
||||
for (var b = 1; --b;) var a = 2;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
inner_var_for_in_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -1033,7 +1013,6 @@ defun_inline_2: {
|
||||
defun_inline_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
@@ -1056,7 +1035,6 @@ defun_inline_3: {
|
||||
|
||||
defun_call: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -1083,7 +1061,6 @@ defun_call: {
|
||||
|
||||
defun_redefine: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -1116,7 +1093,6 @@ defun_redefine: {
|
||||
|
||||
func_inline: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -1143,7 +1119,6 @@ func_inline: {
|
||||
|
||||
func_modified: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -1317,47 +1292,19 @@ iife_func_side_effects: {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
console.log("x");
|
||||
}
|
||||
function y() {
|
||||
console.log("y");
|
||||
}
|
||||
function z() {
|
||||
console.log("z");
|
||||
}
|
||||
(function(a, b, c) {
|
||||
function y() {
|
||||
console.log("FAIL");
|
||||
}
|
||||
return y + b();
|
||||
return b();
|
||||
})(x(), function() {
|
||||
return y();
|
||||
}, z());
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
console.log("x");
|
||||
}
|
||||
function y() {
|
||||
console.log("y");
|
||||
}
|
||||
function z() {
|
||||
console.log("z");
|
||||
}
|
||||
(function(a, b, c) {
|
||||
return function() {
|
||||
console.log("FAIL");
|
||||
} + b();
|
||||
})(x(), function() {
|
||||
return y();
|
||||
}, z());
|
||||
return y();
|
||||
}();
|
||||
})(x(), 0, z());
|
||||
}
|
||||
expect_stdout: [
|
||||
"x",
|
||||
"z",
|
||||
"y",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1595_1: {
|
||||
@@ -1707,7 +1654,7 @@ redefine_arguments_1: {
|
||||
return typeof arguments;
|
||||
}
|
||||
function g() {
|
||||
return "number";
|
||||
return"number";
|
||||
}
|
||||
function h(x) {
|
||||
var arguments = x;
|
||||
@@ -1721,7 +1668,6 @@ redefine_arguments_1: {
|
||||
redefine_arguments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
@@ -1747,7 +1693,9 @@ redefine_arguments_2: {
|
||||
console.log(function() {
|
||||
var arguments;
|
||||
return typeof arguments;
|
||||
}(), "number", function(x) {
|
||||
}(), function() {
|
||||
return"number";
|
||||
}(), function(x) {
|
||||
var arguments = x;
|
||||
return typeof arguments;
|
||||
}());
|
||||
@@ -1758,7 +1706,6 @@ redefine_arguments_2: {
|
||||
redefine_arguments_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
@@ -1835,7 +1782,6 @@ redefine_farg_1: {
|
||||
redefine_farg_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
@@ -1861,7 +1807,9 @@ redefine_farg_2: {
|
||||
console.log(function(a) {
|
||||
var a;
|
||||
return typeof a;
|
||||
}([]), "number",function(a, b) {
|
||||
}([]), function() {
|
||||
return "number";
|
||||
}(),function(a, b) {
|
||||
var a = b;
|
||||
return typeof a;
|
||||
}([]));
|
||||
@@ -1872,7 +1820,6 @@ redefine_farg_2: {
|
||||
redefine_farg_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
@@ -1899,7 +1846,10 @@ redefine_farg_3: {
|
||||
console.log(function(a) {
|
||||
var a;
|
||||
return typeof a;
|
||||
}([]), "number", "undefined");
|
||||
}([]), "number", function(a) {
|
||||
var a = void 0;
|
||||
return typeof a;
|
||||
}([]));
|
||||
}
|
||||
expect_stdout: "object number undefined"
|
||||
}
|
||||
@@ -2019,6 +1969,7 @@ pure_getters_2: {
|
||||
var a = a && a.b;
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
var a = a && a.b;
|
||||
}
|
||||
}
|
||||
@@ -2063,176 +2014,14 @@ catch_var: {
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
var_assign_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
a = 2;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
console.log(2);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
var_assign_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
if (a = 2) console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
if (2) console.log(2);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
var_assign_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
while (a = 2);
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a;
|
||||
while (a = 2);
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
var_assign_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function a() {
|
||||
a = 2;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function a() {
|
||||
a = 2,
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
var_assign_5: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
!function(b) {
|
||||
a = 2;
|
||||
console.log(a, b);
|
||||
}(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a;
|
||||
!function(b) {
|
||||
a = 2,
|
||||
console.log(a, b);
|
||||
}(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "2 undefined"
|
||||
}
|
||||
|
||||
var_assign_6: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a = function(){}(a = 1);
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a = function(){}(a = 1);
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
immutable: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a = "test";
|
||||
console.log(a.indexOf("e"));
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
console.log("test".indexOf("e"));
|
||||
}();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_1814_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
const a = 42;
|
||||
!function() {
|
||||
var b = a;
|
||||
!function(a) {
|
||||
@@ -2241,6 +2030,7 @@ issue_1814_1: {
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
const a = 42;
|
||||
!function() {
|
||||
!function(a) {
|
||||
console.log(a++, 42);
|
||||
@@ -2254,11 +2044,10 @@ issue_1814_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "32";
|
||||
const a = "32";
|
||||
!function() {
|
||||
var b = a + 1;
|
||||
!function(a) {
|
||||
@@ -2267,6 +2056,7 @@ issue_1814_2: {
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
const a = "32";
|
||||
!function() {
|
||||
!function(a) {
|
||||
console.log(a++, "321");
|
||||
@@ -2307,173 +2097,6 @@ try_abort: {
|
||||
expect_stdout: "1 undefined"
|
||||
}
|
||||
|
||||
boolean_binary_assign: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
void 0 && (a = 1);
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a;
|
||||
void 0;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
cond_assign: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a;
|
||||
void 0 ? (a = 1) : 0;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a;
|
||||
void 0 ? (a = 1) : 0;
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
iife_assign: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
var a = 1, b = 0;
|
||||
!function() {
|
||||
b++;
|
||||
return;
|
||||
a = 2;
|
||||
}();
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
var a = 1, b = 0;
|
||||
!function() {
|
||||
b++;
|
||||
return;
|
||||
a = 2;
|
||||
}();
|
||||
console.log(a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_1850_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1850_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: "funcs",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
(function() {
|
||||
console.log(a, a, a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1850_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: "vars",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1850_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log(a, a, a);
|
||||
}
|
||||
var a = 1;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
(function() {
|
||||
console.log(a, a, a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1865: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -2575,28 +2198,3 @@ accessor: {
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
for_in_prop: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = {
|
||||
foo: function() {
|
||||
for (this.b in [1, 2]);
|
||||
}
|
||||
};
|
||||
a.foo();
|
||||
console.log(a.b);
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
foo: function() {
|
||||
for (this.b in [1, 2]);
|
||||
}
|
||||
};
|
||||
a.foo();
|
||||
console.log(a.b);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
console_log: {
|
||||
input: {
|
||||
console.log("%% %s");
|
||||
console.log("%% %s", "%s");
|
||||
}
|
||||
expect: {
|
||||
console.log("%% %s");
|
||||
console.log("%% %s", "%s");
|
||||
}
|
||||
expect_stdout: [
|
||||
"%% %s",
|
||||
"% %s",
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
do_screw: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
@@ -14,10 +14,10 @@ do_screw: {
|
||||
|
||||
dont_screw: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
@@ -28,7 +28,7 @@ dont_screw: {
|
||||
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
@@ -38,7 +38,7 @@ do_screw_constants: {
|
||||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
@@ -47,15 +47,9 @@ dont_screw_constants: {
|
||||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
options = { screw_ie8: true };
|
||||
mangle = { screw_ie8: true };
|
||||
beautify = { screw_ie8: true };
|
||||
input: {
|
||||
good = function(e){
|
||||
return function(error){
|
||||
@@ -81,15 +75,9 @@ do_screw_try_catch: {
|
||||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
input: {
|
||||
bad = function(e){
|
||||
return function(error){
|
||||
@@ -115,15 +103,9 @@ dont_screw_try_catch: {
|
||||
}
|
||||
|
||||
do_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
options = { screw_ie8: true };
|
||||
mangle = { screw_ie8: true };
|
||||
beautify = { screw_ie8: true };
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
@@ -150,15 +132,9 @@ do_screw_try_catch_undefined: {
|
||||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
@@ -188,11 +164,11 @@ reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -220,10 +196,10 @@ reduce_vars: {
|
||||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -239,10 +215,10 @@ issue_1586_1: {
|
||||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -255,73 +231,3 @@ issue_1586_2: {
|
||||
}
|
||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_2120_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (t) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (t) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2120_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ issue_1758: {
|
||||
console.log(function(c) {
|
||||
var undefined = 42;
|
||||
return function() {
|
||||
return c--, c--, void c.toString();
|
||||
return c--, c--, c.toString(), void 0;
|
||||
}();
|
||||
}());
|
||||
}
|
||||
@@ -481,12 +481,12 @@ delete_seq_1: {
|
||||
console.log(delete (1, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((0 / 0, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -505,12 +505,12 @@ delete_seq_2: {
|
||||
console.log(delete (1, 2, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((0 / 0, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -530,12 +530,12 @@ delete_seq_3: {
|
||||
console.log(delete (1, 2, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log((void 0, !0));
|
||||
console.log((void 0, !0));
|
||||
console.log((Infinity, !0));
|
||||
console.log((1 / 0, !0));
|
||||
console.log((NaN, !0));
|
||||
console.log((0 / 0, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -606,127 +606,31 @@ delete_seq_6: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log(!0);
|
||||
console.log((a, !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
side_effects: {
|
||||
reassign_const: {
|
||||
options = {
|
||||
cascade: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
0, a(), 1, b(), 2, c(), 3;
|
||||
function f() {
|
||||
const a = 1;
|
||||
a++;
|
||||
return a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
a(), b(), c();
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_1: {
|
||||
options = {
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
a -= 42;
|
||||
if (a < 0) a = 0;
|
||||
b.a = a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(a -= 42) < 0 && (a = 0), b.a = a;
|
||||
function f() {
|
||||
const a = 1;
|
||||
return a++, a;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
b = a,
|
||||
!a + (b += a) || (b += a),
|
||||
b = a,
|
||||
b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
b = a,
|
||||
!a + (b += a) || (b += a),
|
||||
b = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_3: {
|
||||
options = {
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
"foo" ^ (b += a),
|
||||
b ? false : (b = a) ? -1 : (b -= a) - (b ^= a),
|
||||
a-- || !a,
|
||||
a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
!(b += a) && ((b = a) || (b -= a, b ^= a)),
|
||||
--a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_27: {
|
||||
options = {
|
||||
cascade: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(jQuery) {
|
||||
var $;
|
||||
$ = jQuery;
|
||||
$("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
expect: {
|
||||
(function(jQuery) {
|
||||
jQuery("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
}
|
||||
|
||||
issue_2062: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a || (a++, a--), a++, --a && a.var;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -8,12 +8,3 @@ octal_escape_sequence: {
|
||||
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
||||
}
|
||||
}
|
||||
|
||||
issue_1929: {
|
||||
input: {
|
||||
function f(s) {
|
||||
return s.split(/[\\/]/);
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
exports["Compressor"] = Compressor;
|
||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||
exports["OutputStream"] = OutputStream;
|
||||
exports["SourceMap"] = SourceMap;
|
||||
exports["TreeWalker"] = TreeWalker;
|
||||
exports["base54"] = base54;
|
||||
exports["defaults"] = defaults;
|
||||
exports["mangle_properties"] = mangle_properties;
|
||||
exports["minify"] = minify;
|
||||
exports["parse"] = parse;
|
||||
exports["string_template"] = string_template;
|
||||
exports["tokenizer"] = tokenizer;
|
||||
exports["is_identifier"] = is_identifier;
|
||||
@@ -1,31 +0,0 @@
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
try {
|
||||
fs.mkdirSync("./tmp");
|
||||
} catch (e) {
|
||||
if (e.code != "EEXIST") throw e;
|
||||
}
|
||||
|
||||
function local(url) {
|
||||
return path.join("./tmp", encodeURIComponent(url));
|
||||
}
|
||||
|
||||
function read(url) {
|
||||
return fs.createReadStream(local(url));
|
||||
}
|
||||
|
||||
module.exports = function(url, callback) {
|
||||
var result = read(url);
|
||||
result.on("error", function(e) {
|
||||
if (e.code != "ENOENT") return callback(e);
|
||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||
if (res.statusCode !== 200) return callback(res);
|
||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
||||
callback(null, read(url));
|
||||
}));
|
||||
});
|
||||
}).on("open", function() {
|
||||
callback(null, result);
|
||||
});
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
function f(x) {
|
||||
delete 42;
|
||||
delete (0, x);
|
||||
delete null;
|
||||
delete x;
|
||||
}
|
||||
|
||||
function g(x) {
|
||||
"use strict";
|
||||
delete 42;
|
||||
delete (0, x);
|
||||
delete null;
|
||||
delete x;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
var a, b = [1, 2];
|
||||
for (1, 2, a in b) {
|
||||
console.log(a, b[a]);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
var c = [1, 2];
|
||||
for (var a, b in c) {
|
||||
console.log(a, c[a]);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
function f(arguments) {
|
||||
}
|
||||
|
||||
function g(arguments) {
|
||||
"use strict";
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
function arguments() {
|
||||
}
|
||||
|
||||
function eval() {
|
||||
"use strict";
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
!function eval() {
|
||||
}();
|
||||
|
||||
!function arguments() {
|
||||
"use strict";
|
||||
}();
|
||||
@@ -1,8 +0,0 @@
|
||||
function f() {
|
||||
try {} catch (eval) {}
|
||||
}
|
||||
|
||||
function g() {
|
||||
"use strict";
|
||||
try {} catch (eval) {}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
function f() {
|
||||
var eval;
|
||||
}
|
||||
|
||||
function g() {
|
||||
"use strict";
|
||||
var eval;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
console.log(x);
|
||||
@@ -1 +0,0 @@
|
||||
{"version": 3,"sources": ["index.js"],"mappings": ";"}
|
||||
@@ -1,5 +0,0 @@
|
||||
function test(callback) {
|
||||
'aaaaaaaaaaaaaaaa';
|
||||
callback(err, data);
|
||||
callback(err, data);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
function test(a){
|
||||
"aaaaaaaaaaaaaaaa"
|
||||
;a(err,data),a(err,data)
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7QUFDVjtDQUNBQSxFQUFTQyxJQUFLQyxNQUNkRixFQUFTQyxJQUFLQyJ9
|
||||
@@ -1,2 +1,2 @@
|
||||
new function(){console.log(3)};
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxHQUFyQyxZQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var site = "http://browserbench.org/JetStream";
|
||||
var site = "http://browserbench.org/JetStream/";
|
||||
if (typeof phantom == "undefined") {
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
@@ -11,69 +11,45 @@ if (typeof phantom == "undefined") {
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
var args = process.argv.slice(2);
|
||||
var debug = args.indexOf("--debug");
|
||||
if (debug >= 0) {
|
||||
args.splice(debug, 1);
|
||||
debug = true;
|
||||
} else {
|
||||
debug = false;
|
||||
}
|
||||
if (!args.length) {
|
||||
args.push("-mcb", "beautify=false,webkit");
|
||||
args.push("-mc", "warnings=false");
|
||||
}
|
||||
args.push("--timings");
|
||||
args.push("--stats");
|
||||
var child_process = require("child_process");
|
||||
var fetch = require("./fetch");
|
||||
try {
|
||||
require("phantomjs-prebuilt");
|
||||
} catch(e) {
|
||||
child_process.execSync("npm install phantomjs-prebuilt@2.1.14");
|
||||
}
|
||||
var http = require("http");
|
||||
var server = http.createServer(function(request, response) {
|
||||
request.resume();
|
||||
var url = site + request.url;
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
response.writeHead(200, {
|
||||
"Content-Type": {
|
||||
css: "text/css",
|
||||
js: "application/javascript",
|
||||
png: "image/png"
|
||||
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
||||
});
|
||||
if (/\.js$/.test(url)) {
|
||||
var stderr = "";
|
||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||
silent: true
|
||||
}).on("exit", function(code) {
|
||||
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
||||
console.log(stderr);
|
||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||
});
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
stderr += data;
|
||||
}).setEncoding("utf8");
|
||||
uglifyjs.stdout.pipe(response);
|
||||
res.pipe(uglifyjs.stdin);
|
||||
} else {
|
||||
res.pipe(response);
|
||||
}
|
||||
var url = decodeURIComponent(request.url.slice(1));
|
||||
var stderr = "";
|
||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||
silent: true
|
||||
}).on("exit", function(code) {
|
||||
console.log("uglifyjs", url.indexOf(site) == 0 ? url.slice(site.length) : url, args.join(" "));
|
||||
console.log(stderr);
|
||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||
});
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
stderr += data;
|
||||
}).setEncoding("utf8");
|
||||
uglifyjs.stdout.pipe(response);
|
||||
http.get(url, function(res) {
|
||||
res.pipe(uglifyjs.stdin);
|
||||
});
|
||||
}).listen().on("listening", function() {
|
||||
var phantomjs = require("phantomjs-prebuilt");
|
||||
var program = phantomjs.exec(process.argv[1], server.address().port);
|
||||
program.stdout.pipe(process.stdout);
|
||||
program.stderr.pipe(process.stderr);
|
||||
program.on("exit", function(code) {
|
||||
server.close();
|
||||
if (code) throw new Error("JetStream failed!");
|
||||
console.log("JetStream completed successfully.");
|
||||
});
|
||||
}).listen();
|
||||
server.on("listening", function() {
|
||||
var port = server.address().port;
|
||||
if (debug) {
|
||||
console.log("http://localhost:" + port + "/");
|
||||
} else {
|
||||
child_process.exec("npm install phantomjs-prebuilt@2.1.14 --no-save", function(error) {
|
||||
if (error) throw error;
|
||||
var program = require("phantomjs-prebuilt").exec(process.argv[1], port);
|
||||
program.stdout.pipe(process.stdout);
|
||||
program.stderr.pipe(process.stderr);
|
||||
program.on("exit", function(code) {
|
||||
server.close();
|
||||
if (code) throw new Error("JetStream failed!");
|
||||
console.log("JetStream completed successfully.");
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
server.timeout = 0;
|
||||
} else {
|
||||
@@ -87,6 +63,10 @@ if (typeof phantom == "undefined") {
|
||||
phantom.exit(1);
|
||||
};
|
||||
var url = "http://localhost:" + require("system").args[1] + "/";
|
||||
page.onResourceRequested = function(requestData, networkRequest) {
|
||||
if (/\.js$/.test(requestData.url))
|
||||
networkRequest.changeUrl(url + encodeURIComponent(requestData.url));
|
||||
}
|
||||
page.onConsoleMessage = function(msg) {
|
||||
if (/Error:/i.test(msg)) {
|
||||
console.error(msg);
|
||||
@@ -97,8 +77,8 @@ if (typeof phantom == "undefined") {
|
||||
phantom.exit();
|
||||
}
|
||||
};
|
||||
page.open(url, function(status) {
|
||||
if (status != "success") phantom.exit(1);
|
||||
page.open(site, function(status) {
|
||||
if (status != "success") phantomjs.exit(1);
|
||||
page.evaluate(function() {
|
||||
JetStream.switchToQuick();
|
||||
JetStream.start();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Accessor tokens", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("arguments", function() {
|
||||
|
||||
@@ -2,14 +2,10 @@ var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
|
||||
function read(path) {
|
||||
return readFileSync(path, "utf8");
|
||||
}
|
||||
|
||||
describe("bin/uglifyjs", function () {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("should produce a functional build when using --self", function (done) {
|
||||
this.timeout(30000);
|
||||
this.timeout(15000);
|
||||
|
||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||
|
||||
@@ -19,14 +15,12 @@ describe("bin/uglifyjs", function () {
|
||||
eval(stdout);
|
||||
|
||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||
var result = WrappedUglifyJS.minify("foo([true,,2+3]);");
|
||||
assert.strictEqual(result.error, undefined);
|
||||
assert.strictEqual(result.code, "foo([!0,,5]);");
|
||||
assert.strictEqual(true, WrappedUglifyJS.parse('foo;') instanceof WrappedUglifyJS.AST_Node);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should be able to filter comments correctly with `--comments all`", function (done) {
|
||||
it("Should be able to filter comments correctly with `--comment all`", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
@@ -56,18 +50,18 @@ describe("bin/uglifyjs", function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should append source map to output when using --source-map url=inline", function (done) {
|
||||
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
||||
it("Should append source map to output when using --source-map-inline", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DIn0=\n");
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should not append source map to output when not using --source-map url=inline", function (done) {
|
||||
it("should not append source map to output when not using --source-map-inline", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
@@ -77,23 +71,6 @@ describe("bin/uglifyjs", function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should not consider source map file content as source map file name (issue #2082)", function (done) {
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-2082/sample.js",
|
||||
"--source-map", "content=test/input/issue-2082/sample.js.map",
|
||||
"--source-map", "url=inline",
|
||||
].join(" ");
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
|
||||
var stderrLines = stderr.split('\n');
|
||||
assert.strictEqual(stderrLines[0], 'INFO: Using input source map: test/input/issue-2082/sample.js.map');
|
||||
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle only)", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
||||
|
||||
@@ -160,7 +137,7 @@ describe("bin/uglifyjs", function () {
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
||||
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/default.js", "utf8"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -170,59 +147,55 @@ describe("bin/uglifyjs", function () {
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, read("test/input/issue-1482/bracketize.js"));
|
||||
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/bracketize.js", "utf8"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should process inline source map", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-520/input.js -mc toplevel --source-map content=inline,url=inline";
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js -mc toplevel --in-source-map inline --source-map-inline';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, read("test/input/issue-520/output.js"));
|
||||
assert.strictEqual(stdout, readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should warn for missing inline source map", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --in-source-map inline';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
|
||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should fail with multiple input and inline source map", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-520/input.js test/input/issue-520/output.js --source-map content=inline,url=inline";
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js test/input/issue-520/output.js --in-source-map inline --source-map-inline';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
|
||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with singular input\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should fail with acorn and inline source map", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --acorn';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --spidermonkey';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -235,7 +208,7 @@ describe("bin/uglifyjs", function () {
|
||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
||||
assert.strictEqual(lines[1], "function f(a{}");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -248,7 +221,7 @@ describe("bin/uglifyjs", function () {
|
||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
||||
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
||||
assert.strictEqual(lines[2], "\t\t \t ^");
|
||||
assert.strictEqual(lines[3], "ERROR: Invalid syntax: 0abc");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Invalid syntax: 0abc");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -261,7 +234,7 @@ describe("bin/uglifyjs", function () {
|
||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
||||
assert.strictEqual(lines[1], "foo, bar(");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -274,7 +247,17 @@ describe("bin/uglifyjs", function () {
|
||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should support hyphen as shorthand", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep-fnames=true';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -288,7 +271,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/assign_1.js:1,18",
|
||||
"console.log(1 || 5--);",
|
||||
" ^",
|
||||
"ERROR: Invalid use of -- operator"
|
||||
"SyntaxError: Invalid use of -- operator"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -303,7 +286,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/assign_2.js:1,32",
|
||||
"console.log(2 || (Math.random() /= 2));",
|
||||
" ^",
|
||||
"ERROR: Invalid assignment"
|
||||
"SyntaxError: Invalid assignment"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -318,7 +301,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/assign_3.js:1,17",
|
||||
"console.log(3 || ++this);",
|
||||
" ^",
|
||||
"ERROR: Invalid use of ++ operator"
|
||||
"SyntaxError: Invalid use of ++ operator"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -333,7 +316,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/assign_4.js:1,0",
|
||||
"++null",
|
||||
"^",
|
||||
"ERROR: Invalid use of ++ operator"
|
||||
"SyntaxError: Invalid use of ++ operator"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -348,7 +331,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/dot_1.js:1,2",
|
||||
"a.=",
|
||||
" ^",
|
||||
"ERROR: Unexpected token: operator (=)"
|
||||
"SyntaxError: Unexpected token: operator (=)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -363,7 +346,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/dot_2.js:1,0",
|
||||
"%.a;",
|
||||
"^",
|
||||
"ERROR: Unexpected token: operator (%)"
|
||||
"SyntaxError: Unexpected token: operator (%)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -378,7 +361,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/dot_3.js:1,2",
|
||||
"a./();",
|
||||
" ^",
|
||||
"ERROR: Unexpected token: operator (/)"
|
||||
"SyntaxError: Unexpected token: operator (/)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -393,97 +376,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/object.js:1,13",
|
||||
"console.log({%: 1});",
|
||||
" ^",
|
||||
"ERROR: Unexpected token: operator (%)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (delete x)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/delete.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/delete.js:13,11",
|
||||
" delete x;",
|
||||
" ^",
|
||||
"ERROR: Calling delete on expression not allowed in strict mode"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (function g(arguments))", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/function_1.js:4,11",
|
||||
"function g(arguments) {",
|
||||
" ^",
|
||||
"ERROR: Unexpected arguments in strict mode"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (function eval())", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/function_2.js:4,9",
|
||||
"function eval() {",
|
||||
" ^",
|
||||
"ERROR: Unexpected eval in strict mode"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (iife arguments())", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/function_3.js:4,10",
|
||||
"!function arguments() {",
|
||||
" ^",
|
||||
"ERROR: Unexpected arguments in strict mode"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (catch(eval))", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/try.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/try.js:7,18",
|
||||
" try {} catch (eval) {}",
|
||||
" ^",
|
||||
"ERROR: Unexpected eval in strict mode"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (var eval)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/var.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/var.js:7,8",
|
||||
" var eval;",
|
||||
" ^",
|
||||
"ERROR: Unexpected eval in strict mode"
|
||||
"SyntaxError: Unexpected token: operator (%)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -498,7 +391,7 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/else.js:1,7",
|
||||
"if (0) else 1;",
|
||||
" ^",
|
||||
"ERROR: Unexpected token: keyword (else)"
|
||||
"SyntaxError: Unexpected token: keyword (else)"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
@@ -513,104 +406,9 @@ describe("bin/uglifyjs", function () {
|
||||
"Parse error at test/input/invalid/return.js:1,0",
|
||||
"return 42;",
|
||||
"^",
|
||||
"ERROR: 'return' outside of function"
|
||||
"SyntaxError: 'return' outside of function"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (for-in init)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/for-in_1.js:2,5",
|
||||
"for (1, 2, a in b) {",
|
||||
" ^",
|
||||
"ERROR: Invalid left-hand side in for..in loop"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (for-in var)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||
"Parse error at test/input/invalid/for-in_2.js:2,5",
|
||||
"for (var a, b in c) {",
|
||||
" ^",
|
||||
"ERROR: Only one variable declaration allowed in for..in loop"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should handle literal string as source map input", function(done) {
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1236/simple.js",
|
||||
"--source-map",
|
||||
'content="' + read_map() + '",url=inline'
|
||||
].join(" ");
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, [
|
||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
|
||||
function read_map() {
|
||||
var map = JSON.parse(read("./test/input/issue-1236/simple.js.map"));
|
||||
delete map.sourcesContent;
|
||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||
}
|
||||
});
|
||||
it("Should dump AST as JSON", function(done) {
|
||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
var ast = JSON.parse(stdout);
|
||||
assert.strictEqual(ast._class, "AST_Toplevel");
|
||||
assert.ok(Array.isArray(ast.body));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should print supported options on invalid option syntax", function(done) {
|
||||
var command = uglifyjscmd + " test/input/comments/filter.js -b ascii-only";
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `ascii-only` is not a supported option/.test(stderr), stderr);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --mangle reserved=[]", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-505/input.js -m reserved=[callback]';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --mangle reserved=false", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-505/input.js -m reserved=false';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("comment filters", function() {
|
||||
@@ -75,6 +75,7 @@ describe("comment filters", function() {
|
||||
|
||||
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;");
|
||||
@@ -82,6 +83,7 @@ describe("comment filters", function() {
|
||||
|
||||
it("Should handle preamble without shebang correctly", function() {
|
||||
var code = UglifyJS.minify("var x = 10;", {
|
||||
fromString: true,
|
||||
output: { preamble: "/* Build */" }
|
||||
}).code;
|
||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../node");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Comment", function() {
|
||||
it("Should recognize eol of single line comments", function() {
|
||||
@@ -20,7 +20,7 @@ describe("Comment", function() {
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i]);
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
}, fail, tests[i]);
|
||||
}
|
||||
});
|
||||
@@ -43,7 +43,7 @@ describe("Comment", function() {
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i]);
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
}, fail, tests[i]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,7 +6,9 @@ describe("comment before constant", function() {
|
||||
|
||||
it("Should test comment before constant is retained and output after mangle.", function() {
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: { collapse_vars: false, reduce_vars: false },
|
||||
mangle: {},
|
||||
output: { comments: true },
|
||||
});
|
||||
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
||||
@@ -14,9 +16,12 @@ describe("comment before constant", function() {
|
||||
|
||||
it("Should test code works when comments disabled.", function() {
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: { collapse_vars: false, reduce_vars: false },
|
||||
mangle: {},
|
||||
output: { comments: false },
|
||||
});
|
||||
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../node");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Directives", function() {
|
||||
it ("Should allow tokenizer to store directives state", function() {
|
||||
@@ -197,7 +197,7 @@ describe("Directives", function() {
|
||||
assert.strictEqual(
|
||||
uglify.minify(
|
||||
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
||||
{output: {beautify: true, quote_style: 3}, compress: false}
|
||||
{fromString: true, output: {beautify: true, quote_style: 3}, compress: false}
|
||||
).code,
|
||||
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
||||
);
|
||||
@@ -225,7 +225,7 @@ describe("Directives", function() {
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i][0], {compress: false, mangle: false}).code,
|
||||
uglify.minify(tests[i][0], {fromString: true, quote_style: 3, compress: false, mangle: false}).code,
|
||||
tests[i][1],
|
||||
tests[i][0]
|
||||
);
|
||||
@@ -234,7 +234,7 @@ describe("Directives", function() {
|
||||
|
||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||
var code = uglify.minify('"use strict";"use\\x20strict";',
|
||||
{output: {semicolons: false}, compress: false}
|
||||
{fromString: true, output: {semicolons: false}, compress: false}
|
||||
).code;
|
||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
||||
});
|
||||
@@ -340,7 +340,7 @@ describe("Directives", function() {
|
||||
];
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
||||
uglify.minify(tests[i][0], {fromString: true, output:{quote_style: tests[i][1]}, compress: false}).code,
|
||||
tests[i][2],
|
||||
tests[i][0] + " using mode " + tests[i][1]
|
||||
);
|
||||
@@ -372,7 +372,7 @@ describe("Directives", function() {
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i][0]).code,
|
||||
uglify.minify(tests[i][0], {fromString: true}).code,
|
||||
tests[i][1],
|
||||
tests[i][0]
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Getters and setters", function() {
|
||||
|
||||
@@ -1,80 +1,58 @@
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var path = require("path");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
|
||||
describe("bin/uglifyjs with input file globs", function() {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("bin/uglifyjs with one input file extension glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/foo.*" -cm';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);\n');
|
||||
done();
|
||||
});
|
||||
describe("minify() with input file globs", function() {
|
||||
it("minify() with one input file glob string.", function() {
|
||||
var result = Uglify.minify("test/input/issue-1242/foo.*");
|
||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
||||
});
|
||||
it("bin/uglifyjs with one input file name glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/b*.es5" -cm';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function bar(n){return 3*n}function baz(n){return n/2}\n');
|
||||
done();
|
||||
});
|
||||
it("minify() with an array of one input file glob.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/b*.es5",
|
||||
]);
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
||||
});
|
||||
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=2';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'var print=console.log.bind(console);print("qux",9,6),print("Foo:",22);\n');
|
||||
done();
|
||||
it("minify() with an array of multiple input file globs.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/???.es5",
|
||||
"test/input/issue-1242/*.js",
|
||||
], {
|
||||
compress: { toplevel: true }
|
||||
});
|
||||
assert.strictEqual(result.code, 'var print=console.log.bind(console),a=function(n){return 3*n}(3),b=function(n){return n/2}(12);print("qux",a,b),function(n){print("Foo:",2*n)}(11);');
|
||||
});
|
||||
it("should throw with non-matching glob string", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
|
||||
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.ok(/^ERROR: ENOENT/.test(stderr));
|
||||
done();
|
||||
});
|
||||
it("should throw with non-matching glob string", function() {
|
||||
var glob = "test/input/issue-1242/blah.*";
|
||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
||||
assert.throws(function() {
|
||||
Uglify.minify(glob);
|
||||
}, "should throw file not found");
|
||||
});
|
||||
it('"?" in glob string should not match "/"', function(done) {
|
||||
var command = uglifyjscmd + ' "test/input?issue-1242/foo.*"';
|
||||
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.ok(/^ERROR: ENOENT/.test(stderr));
|
||||
done();
|
||||
});
|
||||
it('"?" in glob string should not match "/"', function() {
|
||||
var glob = "test/input?issue-1242/foo.*";
|
||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
||||
assert.throws(function() {
|
||||
Uglify.minify(glob);
|
||||
}, "should throw file not found");
|
||||
});
|
||||
it("should handle special characters in glob string", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1632/^{*}[???](*)+$.??" -cm';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "console.log(x);\n");
|
||||
done();
|
||||
});
|
||||
it("should handle special characters in glob string", function() {
|
||||
var result = Uglify.minify("test/input/issue-1632/^{*}[???](*)+$.??");
|
||||
assert.strictEqual(result.code, "console.log(x);");
|
||||
});
|
||||
it("should handle array of glob strings - matching and otherwise", function(done) {
|
||||
it("should handle array of glob strings - matching and otherwise", function() {
|
||||
var dir = "test/input/issue-1242";
|
||||
var command = uglifyjscmd + ' "' + [
|
||||
var matches = Uglify.simple_glob([
|
||||
path.join(dir, "b*.es5"),
|
||||
path.join(dir, "z*.es5"),
|
||||
path.join(dir, "*.js")
|
||||
].join('" "') + '"';
|
||||
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.ok(/^ERROR: ENOENT.*?z\*\.es5/.test(stderr));
|
||||
done();
|
||||
});
|
||||
path.join(dir, "*.js"),
|
||||
]);
|
||||
assert.strictEqual(matches.length, 4);
|
||||
assert.strictEqual(matches[0], path.join(dir, "bar.es5"));
|
||||
assert.strictEqual(matches[1], path.join(dir, "baz.es5"));
|
||||
assert.strictEqual(matches[2], path.join(dir, "z*.es5"));
|
||||
assert.strictEqual(matches[3], path.join(dir, "qux.js"));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,12 @@ describe("Huge number of comments.", function() {
|
||||
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
|
||||
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
|
||||
js += "x; }";
|
||||
var result = Uglify.minify(js, { mangle: false });
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
mangle: false,
|
||||
compress: {}
|
||||
});
|
||||
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ describe("input sourcemaps", function() {
|
||||
transpilemap = sourceMap || getMap();
|
||||
|
||||
var result = Uglify.minify(transpiled, {
|
||||
sourceMap: {
|
||||
content: transpilemap
|
||||
}
|
||||
fromString: true,
|
||||
inSourceMap: transpilemap,
|
||||
outSourceMap: true
|
||||
});
|
||||
|
||||
map = new SourceMapConsumer(result.map);
|
||||
|
||||
@@ -2,37 +2,29 @@ var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("let", function() {
|
||||
it("Should not produce reserved keywords as variable name in mangle", function(done) {
|
||||
it("Should not produce `let` as a variable name in mangle", function(done) {
|
||||
this.timeout(10000);
|
||||
|
||||
// Produce a lot of variables in a function and run it through mangle.
|
||||
var s = '"dddddeeeeelllllooooottttt"; function foo() {';
|
||||
for (var i = 0; i < 18000; i++) {
|
||||
var s = '"use strict"; function foo() {';
|
||||
for (var i = 0; i < 21000; ++i) {
|
||||
s += "var v" + i + "=0;";
|
||||
}
|
||||
s += '}';
|
||||
var result = Uglify.minify(s, {compress: false});
|
||||
var result = Uglify.minify(s, {fromString: true, compress: false});
|
||||
|
||||
// Verify that select keywords and reserved keywords not produced
|
||||
[
|
||||
"do",
|
||||
"let",
|
||||
"var",
|
||||
].forEach(function(name) {
|
||||
assert.strictEqual(result.code.indexOf("var " + name + "="), -1);
|
||||
});
|
||||
assert.strictEqual(result.code.indexOf("var let="), -1);
|
||||
assert.strictEqual(result.code.indexOf("var do="), -1);
|
||||
assert.strictEqual(result.code.indexOf("var var="), -1);
|
||||
|
||||
// Verify that the variable names that appeared immediately before
|
||||
// and after the erroneously generated variable name still exist
|
||||
// and after the erroneously generated `let` variable name still exist
|
||||
// to show the test generated enough symbols.
|
||||
[
|
||||
"to", "eo",
|
||||
"eet", "fet",
|
||||
"rar", "oar",
|
||||
].forEach(function(name) {
|
||||
assert.ok(result.code.indexOf("var " + name + "=") >= 0);
|
||||
});
|
||||
assert(result.code.indexOf("var ket=") >= 0);
|
||||
assert(result.code.indexOf("var met=") >= 0);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
var Uglify = require("../node");
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("line-endings", function() {
|
||||
var options = {
|
||||
compress: false,
|
||||
fromString: true,
|
||||
mangle: false,
|
||||
compress: false,
|
||||
output: {
|
||||
beautify: false,
|
||||
comments: /^!/,
|
||||
|
||||
@@ -6,41 +6,43 @@ describe("Input file as map", function() {
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = Uglify.minify(jsMap, {sourceMap: true});
|
||||
var result = Uglify.minify(jsMap, {fromString: true, outSourceMap: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||
assert.strictEqual(map.file, undefined);
|
||||
|
||||
result = Uglify.minify(jsMap);
|
||||
assert.strictEqual(result.map, undefined);
|
||||
result = Uglify.minify(jsMap, {fromString: true, outFileName: 'out.js'});
|
||||
assert.strictEqual(result.map, null);
|
||||
|
||||
result = Uglify.minify(jsMap, {sourceMap: {filename: 'out.js'}});
|
||||
result = Uglify.minify(jsMap, {fromString: true, outFileName: 'out.js', outSourceMap: true});
|
||||
map = JSON.parse(result.map);
|
||||
assert.strictEqual(map.file, 'out.js');
|
||||
});
|
||||
|
||||
it("Should accept array of strings", function() {
|
||||
it("Should accept array of objects and strings", function() {
|
||||
var jsSeq = [
|
||||
'var foo = {"x": 1, y: 2, \'z\': 3};',
|
||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = Uglify.minify(jsSeq, {sourceMap: true});
|
||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.deepEqual(map.sources, ['0', '1']);
|
||||
assert.strictEqual(map.sources[0], '/scripts/foo.js');
|
||||
});
|
||||
|
||||
it("Should correctly include source", function() {
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = Uglify.minify(jsMap, {sourceMap: {includeSources: true}});
|
||||
var jsSeq = [
|
||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true, sourceMapIncludeSources: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};']);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};', 'var bar = 15;']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,83 +1,19 @@
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
var run_code = require("../sandbox").run_code;
|
||||
|
||||
function read(path) {
|
||||
return readFileSync(path, "utf8");
|
||||
}
|
||||
|
||||
describe("minify", function() {
|
||||
it("Should test basic sanity of minify with default options", function() {
|
||||
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
|
||||
var result = Uglify.minify(js);
|
||||
var result = Uglify.minify(js, {fromString: true});
|
||||
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
|
||||
});
|
||||
|
||||
it("Should skip inherited keys from `files`", function() {
|
||||
var files = Object.create({ skip: this });
|
||||
files[0] = "alert(1 + 1)";
|
||||
var result = Uglify.minify(files);
|
||||
assert.strictEqual(result.code, "alert(2);");
|
||||
});
|
||||
|
||||
it("Should work with mangle.cache", function() {
|
||||
var cache = {};
|
||||
var original = "";
|
||||
var compressed = "";
|
||||
[
|
||||
"bar.es5",
|
||||
"baz.es5",
|
||||
"foo.es5",
|
||||
"qux.js",
|
||||
].forEach(function(file) {
|
||||
var code = read("test/input/issue-1242/" + file);
|
||||
var result = Uglify.minify(code, {
|
||||
mangle: {
|
||||
cache: cache,
|
||||
toplevel: true
|
||||
}
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
compressed += result.code;
|
||||
});
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
|
||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}function c(o){l("Foo:",2*o)}var l=console.log.bind(console);var f=n(3),i=r(12);l("qux",f,i),c(11);');
|
||||
assert.strictEqual(run_code(compressed), run_code(original));
|
||||
});
|
||||
|
||||
it("Should work with nameCache", function() {
|
||||
var cache = {};
|
||||
var original = "";
|
||||
var compressed = "";
|
||||
[
|
||||
"bar.es5",
|
||||
"baz.es5",
|
||||
"foo.es5",
|
||||
"qux.js",
|
||||
].forEach(function(file) {
|
||||
var code = read("test/input/issue-1242/" + file);
|
||||
var result = Uglify.minify(code, {
|
||||
mangle: {
|
||||
toplevel: true
|
||||
},
|
||||
nameCache: cache
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
compressed += result.code;
|
||||
});
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
|
||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}function c(o){l("Foo:",2*o)}var l=console.log.bind(console);var f=n(3),i=r(12);l("qux",f,i),c(11);');
|
||||
assert.strictEqual(run_code(compressed), run_code(original));
|
||||
});
|
||||
|
||||
describe("keep_quoted_props", function() {
|
||||
it("Should preserve quotes in object literals", function() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
output: {
|
||||
fromString: true, output: {
|
||||
keep_quoted_props: true
|
||||
}});
|
||||
assert.strictEqual(result.code, 'var foo={"x":1,y:2,"z":3};');
|
||||
@@ -86,7 +22,7 @@ describe("minify", function() {
|
||||
it("Should preserve quote styles when quote_style is 3", function() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
output: {
|
||||
fromString: true, output: {
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3
|
||||
}});
|
||||
@@ -96,7 +32,7 @@ describe("minify", function() {
|
||||
it("Should not preserve quotes in object literals when disabled", function() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
output: {
|
||||
fromString: true, output: {
|
||||
keep_quoted_props: false,
|
||||
quote_style: 3
|
||||
}});
|
||||
@@ -108,13 +44,12 @@ describe("minify", function() {
|
||||
it("Shouldn't mangle quoted properties", function() {
|
||||
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: {
|
||||
properties: false
|
||||
},
|
||||
mangle: {
|
||||
properties: {
|
||||
keep_quoted: true
|
||||
}
|
||||
mangleProperties: {
|
||||
ignore_quoted: true
|
||||
},
|
||||
output: {
|
||||
keep_quoted_props: true,
|
||||
@@ -128,12 +63,10 @@ describe("minify", function() {
|
||||
|
||||
describe("inSourceMap", function() {
|
||||
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() {
|
||||
var result = Uglify.minify(read("./test/input/issue-1236/simple.js"), {
|
||||
sourceMap: {
|
||||
content: read("./test/input/issue-1236/simple.js.map"),
|
||||
filename: "simple.min.js",
|
||||
includeSources: true
|
||||
}
|
||||
var result = Uglify.minify('./test/input/issue-1236/simple.js', {
|
||||
outSourceMap: "simple.min.js.map",
|
||||
inSourceMap: "./test/input/issue-1236/simple.js.map",
|
||||
sourceMapIncludeSources: true
|
||||
});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
@@ -144,12 +77,10 @@ describe("minify", function() {
|
||||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||
});
|
||||
it("Should process inline source map", function() {
|
||||
var code = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
||||
var code = Uglify.minify("./test/input/issue-520/input.js", {
|
||||
compress: { toplevel: true },
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true
|
||||
}).code + "\n";
|
||||
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||
});
|
||||
@@ -160,13 +91,11 @@ describe("minify", function() {
|
||||
warnings.push(txt);
|
||||
};
|
||||
try {
|
||||
var result = Uglify.minify(read("./test/input/issue-1323/sample.js"), {
|
||||
var result = Uglify.minify("./test/input/issue-1323/sample.js", {
|
||||
inSourceMap: "inline",
|
||||
mangle: false,
|
||||
sourceMap: {
|
||||
content: "inline"
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.code, "var bar=function(){return function(bar){return bar}}();");
|
||||
assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
|
||||
assert.strictEqual(warnings.length, 1);
|
||||
assert.strictEqual(warnings[0], "inline source map not found");
|
||||
} finally {
|
||||
@@ -174,54 +103,50 @@ describe("minify", function() {
|
||||
}
|
||||
});
|
||||
it("Should fail with multiple input and inline source map", function() {
|
||||
var result = Uglify.minify([
|
||||
read("./test/input/issue-520/input.js"),
|
||||
read("./test/input/issue-520/output.js")
|
||||
], {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
assert.throws(function() {
|
||||
Uglify.minify([
|
||||
"./test/input/issue-520/input.js",
|
||||
"./test/input/issue-520/output.js"
|
||||
], {
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should fail with SpiderMonkey and inline source map", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify("./test/input/issue-520/input.js", {
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true,
|
||||
spidermonkey: true
|
||||
});
|
||||
});
|
||||
var err = result.error;
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "Error: inline source map only works with singular input");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sourceMapInline", function() {
|
||||
it("should append source map to output js when sourceMapInline is enabled", function() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
sourceMap: {
|
||||
url: "inline"
|
||||
}
|
||||
fromString: true,
|
||||
sourceMapInline: true
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIj8iXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsR0FBSUEsR0FBSSxTQUFTQyxHQUFPLE1BQU9BIn0=");
|
||||
});
|
||||
it("should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
fromString: true
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};");
|
||||
});
|
||||
it("should work with max_line_len", function() {
|
||||
var result = Uglify.minify(read("./test/input/issue-505/input.js"), {
|
||||
output: {
|
||||
max_line_len: 20
|
||||
},
|
||||
sourceMap: {
|
||||
url: "inline"
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.error, undefined);
|
||||
assert.strictEqual(result.code, read("./test/input/issue-505/output.js"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("#__PURE__", function() {
|
||||
it("should drop #__PURE__ hint after use", function() {
|
||||
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
||||
fromString: true,
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
@@ -232,6 +157,7 @@ describe("minify", function() {
|
||||
});
|
||||
it("should not drop #__PURE__ hint if function is retained", function() {
|
||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||
fromString: true,
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
@@ -243,41 +169,27 @@ describe("minify", function() {
|
||||
});
|
||||
|
||||
describe("JS_Parse_Error", function() {
|
||||
it("should return syntax error", function() {
|
||||
var result = Uglify.minify("function f(a{}");
|
||||
var err = result.error;
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||
assert.strictEqual(err.filename, "0");
|
||||
assert.strictEqual(err.line, 1);
|
||||
assert.strictEqual(err.col, 12);
|
||||
it("should throw syntax error", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify("function f(a{}", { fromString: true });
|
||||
}, function(err) {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||
assert.strictEqual(err.filename, 0);
|
||||
assert.strictEqual(err.line, 1);
|
||||
assert.strictEqual(err.col, 12);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("global_defs", function() {
|
||||
it("should throw for non-trivial expressions", function() {
|
||||
var result = Uglify.minify("alert(42);", {
|
||||
compress: {
|
||||
global_defs: {
|
||||
"@alert": "debugger"
|
||||
}
|
||||
}
|
||||
});
|
||||
var err = result.error;
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
||||
describe("Compressor", function() {
|
||||
it("should be backward compatible with ast.transform(compressor)", function() {
|
||||
var ast = Uglify.parse("function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
||||
ast.figure_out_scope();
|
||||
ast = ast.transform(Uglify.Compressor());
|
||||
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
||||
});
|
||||
it("should skip inherited properties", function() {
|
||||
var foo = Object.create({ skip: this });
|
||||
foo.bar = 42;
|
||||
var result = Uglify.minify("alert(FOO);", {
|
||||
compress: {
|
||||
global_defs: {
|
||||
FOO: foo
|
||||
}
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.code, "alert({bar:42});");
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
@@ -34,6 +34,7 @@ describe("New", function() {
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i], {
|
||||
fromString: true,
|
||||
output: {beautify: true},
|
||||
compress: false,
|
||||
mangle: false
|
||||
@@ -75,6 +76,7 @@ describe("New", function() {
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i], {
|
||||
fromString: true,
|
||||
output: {beautify: false},
|
||||
compress: false,
|
||||
mangle: false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../node");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Number literals", function () {
|
||||
it("Should not allow legacy octal literals in strict mode", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require("../../");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("operator", function() {
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
var assert = require("assert");
|
||||
var semver = require("semver");
|
||||
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", 1, 2 ]
|
||||
stdio: "ignore"
|
||||
}).on("exit", function(code) {
|
||||
clearInterval(id);
|
||||
assert.strictEqual(code, 0);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
describe("test/benchmark.js", function() {
|
||||
this.timeout(10 * 60 * 1000);
|
||||
this.timeout(5 * 60 * 1000);
|
||||
[
|
||||
"-b",
|
||||
"-b bracketize",
|
||||
@@ -33,17 +36,18 @@ describe("test/benchmark.js", function() {
|
||||
});
|
||||
});
|
||||
|
||||
if (semver.satisfies(process.version, "0.12")) return;
|
||||
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",
|
||||
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||
"-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");
|
||||
args.push("-b", "beautify=false,webkit");
|
||||
run(process.argv[0], args, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,9 @@ describe("screw-ie8", function () {
|
||||
}\
|
||||
console.log('undefined is ' + undefined);\
|
||||
return b === undefined;\
|
||||
};"
|
||||
};", {
|
||||
fromString: true
|
||||
}
|
||||
).code,
|
||||
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
|
||||
);
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var uglify = require("../node");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("spidermonkey export/import sanity test", function() {
|
||||
it("should produce a functional build when using --self with spidermonkey", function(done) {
|
||||
this.timeout(60000);
|
||||
it("should produce a functional build when using --self with spidermonkey", function (done) {
|
||||
this.timeout(20000);
|
||||
|
||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
||||
uglifyjs + " -p spidermonkey -cm";
|
||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
||||
uglifyjs + " --spidermonkey -cm";
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
eval(stdout);
|
||||
assert.strictEqual(typeof SpiderUglify, "object");
|
||||
var result = SpiderUglify.minify("foo([true,,2+3]);");
|
||||
assert.strictEqual(result.error, undefined);
|
||||
assert.strictEqual(result.code, "foo([!0,,5]);");
|
||||
|
||||
var ast = SpiderUglify.parse("foo([true,,2+3]);");
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
ast.figure_out_scope();
|
||||
ast = SpiderUglify.Compressor({}).compress(ast);
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
var stream = SpiderUglify.OutputStream({});
|
||||
ast.print(stream);
|
||||
var code = stream.toString();
|
||||
assert.strictEqual(code, "foo([!0,,5]);");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../node");
|
||||
var UglifyJS = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("String literals", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../node");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("With", function() {
|
||||
it("Should throw syntaxError when using with statement in strict mode", function() {
|
||||
|
||||
@@ -6,14 +6,20 @@ var ufuzz = require("./ufuzz");
|
||||
var UglifyJS = require("..");
|
||||
|
||||
function try_beautify(code) {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true
|
||||
}
|
||||
});
|
||||
var beautified;
|
||||
try {
|
||||
beautified = UglifyJS.minify(code, {
|
||||
fromString: true,
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
beautified = { error: ex };
|
||||
}
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(beautified.error.stack);
|
||||
@@ -25,10 +31,17 @@ function try_beautify(code) {
|
||||
}
|
||||
|
||||
function test(original, estree, description) {
|
||||
var transformed = UglifyJS.minify(UglifyJS.AST_Node.from_mozilla_ast(estree), {
|
||||
compress: false,
|
||||
mangle: false
|
||||
});
|
||||
var transformed;
|
||||
try {
|
||||
transformed = UglifyJS.minify(estree, {
|
||||
fromString: true,
|
||||
compress: false,
|
||||
mangle: false,
|
||||
spidermonkey: true
|
||||
});
|
||||
} catch (ex) {
|
||||
transformed = { error: ex };
|
||||
}
|
||||
if (transformed.error || original !== transformed.code) {
|
||||
console.log("//=============================================================");
|
||||
console.log("// !!!!!! Failed... round", round);
|
||||
@@ -52,13 +65,14 @@ var num_iterations = ufuzz.num_iterations;
|
||||
for (var round = 1; round <= num_iterations; round++) {
|
||||
process.stdout.write(round + " of " + num_iterations + "\r");
|
||||
var code = ufuzz.createTopLevelCode();
|
||||
var uglified = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true
|
||||
}
|
||||
});
|
||||
var uglified = {
|
||||
ast: UglifyJS.parse(code),
|
||||
code: UglifyJS.minify(code, {
|
||||
fromString: true,
|
||||
compress: false,
|
||||
mangle: false
|
||||
}).code
|
||||
};
|
||||
test(uglified.code, uglified.ast.to_mozilla_ast(), "AST_Node.to_mozilla_ast()");
|
||||
try {
|
||||
test(uglified.code, acorn.parse(code), "acorn.parse()");
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
var fs = require("fs");
|
||||
|
||||
new Function("MOZ_SourceMap", "exports", require("../tools/node").FILES.map(function(file) {
|
||||
if (/exports\.js$/.test(file)) file = require.resolve("./exports");
|
||||
return fs.readFileSync(file, "utf8");
|
||||
}).join("\n\n"))(require("source-map"), exports);
|
||||
@@ -1,11 +1,10 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
var U = require("./node");
|
||||
var U = require("../tools/node");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var assert = require("assert");
|
||||
var sandbox = require("./sandbox");
|
||||
var semver = require("semver");
|
||||
|
||||
var tests_dir = path.dirname(module.filename);
|
||||
var failures = 0;
|
||||
@@ -86,6 +85,7 @@ function run_compress_tests() {
|
||||
log_start_file(file);
|
||||
function test_case(test) {
|
||||
log_test(test.name);
|
||||
U.base54.reset();
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
@@ -100,6 +100,9 @@ function run_compress_tests() {
|
||||
quote_style: 3,
|
||||
keep_quoted_props: true
|
||||
});
|
||||
if (test.mangle_props) {
|
||||
input = U.mangle_properties(input, test.mangle_props);
|
||||
}
|
||||
var options = U.defaults(test.options, {
|
||||
warnings: false
|
||||
});
|
||||
@@ -114,16 +117,10 @@ function run_compress_tests() {
|
||||
var cmp = new U.Compressor(options, true);
|
||||
var output = cmp.compress(input);
|
||||
output.figure_out_scope(test.mangle);
|
||||
if (test.mangle || test.mangle_props) {
|
||||
U.base54.reset();
|
||||
output.compute_char_frequency(test.mangle);
|
||||
}
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
}
|
||||
if (test.mangle_props) {
|
||||
output = U.mangle_properties(output, test.mangle_props);
|
||||
}
|
||||
output = make_code(output, output_options);
|
||||
if (expect != output) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
||||
@@ -167,8 +164,7 @@ function run_compress_tests() {
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout
|
||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
if (test.expect_stdout) {
|
||||
var stdout = sandbox.run_code(input_code);
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = stdout;
|
||||
@@ -278,14 +274,7 @@ function parse_test(file) {
|
||||
if (node instanceof U.AST_LabeledStatement) {
|
||||
var label = node.label;
|
||||
assert.ok(
|
||||
[
|
||||
"input",
|
||||
"expect",
|
||||
"expect_exact",
|
||||
"expect_warnings",
|
||||
"expect_stdout",
|
||||
"node_version",
|
||||
].indexOf(label.name) >= 0,
|
||||
["input", "expect", "expect_exact", "expect_warnings", "expect_stdout"].indexOf(label.name) >= 0,
|
||||
tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
@@ -293,25 +282,11 @@ function parse_test(file) {
|
||||
})
|
||||
);
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
if (label.name == "expect_exact") {
|
||||
test[label.name] = read_string(stat);
|
||||
} else if (label.name == "expect_stdout") {
|
||||
var body = stat.body;
|
||||
if (body instanceof U.AST_Boolean) {
|
||||
test[label.name] = body.value;
|
||||
} else if (body instanceof U.AST_Call) {
|
||||
var ctor = global[body.expression.name];
|
||||
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
return node.value;
|
||||
}));
|
||||
if (stat.TYPE == "SimpleStatement" && stat.body instanceof U.AST_Boolean) {
|
||||
test[label.name] = stat.body.value;
|
||||
} else {
|
||||
test[label.name] = read_string(stat) + "\n";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
var semver = require("semver");
|
||||
var vm = require("vm");
|
||||
|
||||
function safe_log(arg, level) {
|
||||
@@ -19,25 +18,23 @@ function safe_log(arg, level) {
|
||||
|
||||
var FUNC_TOSTRING = [
|
||||
"Function.prototype.toString = Function.prototype.valueOf = function() {",
|
||||
" var id = 100000;",
|
||||
" var id = 0;",
|
||||
" return function() {",
|
||||
' if (this === Array) return "[Function: Array]";',
|
||||
' if (this === Object) return "[Function: Object]";',
|
||||
" var i = this.name;",
|
||||
' if (typeof i != "number") {',
|
||||
" i = ++id;",
|
||||
].concat(Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable ? [
|
||||
' Object.defineProperty(this, "name", {',
|
||||
" get: function() {",
|
||||
" return i;",
|
||||
" }",
|
||||
" });",
|
||||
] : [], [
|
||||
" }",
|
||||
' return "[Function: " + i + "]";',
|
||||
" }",
|
||||
"}();",
|
||||
]).join("\n");
|
||||
].join("\n");
|
||||
exports.run_code = function(code) {
|
||||
var stdout = "";
|
||||
var original_write = process.stdout.write;
|
||||
@@ -52,10 +49,7 @@ exports.run_code = function(code) {
|
||||
"}();",
|
||||
].join("\n"), {
|
||||
console: {
|
||||
log: function(msg) {
|
||||
if (arguments.length == 1 && typeof msg == "string") {
|
||||
return console.log("%s", msg);
|
||||
}
|
||||
log: function() {
|
||||
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
||||
return safe_log(arg, 3);
|
||||
}));
|
||||
@@ -69,7 +63,7 @@ exports.run_code = function(code) {
|
||||
process.stdout.write = original_write;
|
||||
}
|
||||
};
|
||||
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
||||
exports.same_stdout = ~process.version.lastIndexOf("v0.12.", 0) ? function(expected, actual) {
|
||||
if (typeof expected != typeof actual) return false;
|
||||
if (typeof expected != "string") {
|
||||
if (expected.name != actual.name) return false;
|
||||
|
||||
@@ -26,11 +26,11 @@ module.exports = function () {
|
||||
}
|
||||
|
||||
function source_map(js) {
|
||||
return JSON.parse(UglifyJS.minify(js, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
sourceMap: true
|
||||
}).map);
|
||||
var source_map = UglifyJS.SourceMap();
|
||||
var stream = UglifyJS.OutputStream({ source_map: source_map });
|
||||
var parsed = UglifyJS.parse(js);
|
||||
parsed.print(stream);
|
||||
return JSON.parse(source_map.toString());
|
||||
}
|
||||
|
||||
// Run standalone
|
||||
|
||||
222
test/ufuzz.js
222
test/ufuzz.js
@@ -102,23 +102,23 @@ for (var i = 2; i < process.argv.length; ++i) {
|
||||
case '--help':
|
||||
case '-h':
|
||||
case '-?':
|
||||
println('** UglifyJS fuzzer help **');
|
||||
println('Valid options (optional):');
|
||||
println('<number>: generate this many cases (if used must be first arg)');
|
||||
println('-v: print every generated test case');
|
||||
println('-V: print every 100th generated test case');
|
||||
println('-t <int>: generate this many toplevels per run (more take longer)');
|
||||
println('-r <int>: maximum recursion depth for generator (higher takes longer)');
|
||||
println('-s1 <statement name>: force the first level statement to be this one (see list below)');
|
||||
println('-s2 <statement name>: force the second level statement to be this one (see list below)');
|
||||
println('--no-catch-redef: do not redefine catch variables');
|
||||
println('--no-directive: do not generate directives');
|
||||
println('--use-strict: generate "use strict"');
|
||||
println('--stmt-depth-from-func: reset statement depth counter at each function, counts from global otherwise');
|
||||
println('--only-stmt <statement names>: a comma delimited white list of statements that may be generated');
|
||||
println('--without-stmt <statement names>: a comma delimited black list of statements never to generate');
|
||||
println('List of accepted statement names: ' + Object.keys(STMT_ARG_TO_ID));
|
||||
println('** UglifyJS fuzzer exiting **');
|
||||
console.log('** UglifyJS fuzzer help **');
|
||||
console.log('Valid options (optional):');
|
||||
console.log('<number>: generate this many cases (if used must be first arg)');
|
||||
console.log('-v: print every generated test case');
|
||||
console.log('-V: print every 100th generated test case');
|
||||
console.log('-t <int>: generate this many toplevels per run (more take longer)');
|
||||
console.log('-r <int>: maximum recursion depth for generator (higher takes longer)');
|
||||
console.log('-s1 <statement name>: force the first level statement to be this one (see list below)');
|
||||
console.log('-s2 <statement name>: force the second level statement to be this one (see list below)');
|
||||
console.log('--no-catch-redef: do not redefine catch variables');
|
||||
console.log('--no-directive: do not generate directives');
|
||||
console.log('--use-strict: generate "use strict"');
|
||||
console.log('--stmt-depth-from-func: reset statement depth counter at each function, counts from global otherwise');
|
||||
console.log('--only-stmt <statement names>: a comma delimited white list of statements that may be generated');
|
||||
console.log('--without-stmt <statement names>: a comma delimited black list of statements never to generate');
|
||||
console.log('List of accepted statement names: ' + Object.keys(STMT_ARG_TO_ID));
|
||||
console.log('** UglifyJS fuzzer exiting **');
|
||||
return 0;
|
||||
default:
|
||||
// first arg may be a number.
|
||||
@@ -941,104 +941,113 @@ if (require.main !== module) {
|
||||
return;
|
||||
}
|
||||
|
||||
function println(msg) {
|
||||
if (typeof msg != "undefined") process.stdout.write(msg);
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
|
||||
function errorln(msg) {
|
||||
if (typeof msg != "undefined") process.stderr.write(msg);
|
||||
process.stderr.write("\n");
|
||||
}
|
||||
|
||||
function try_beautify(code, result, printfn) {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
},
|
||||
});
|
||||
if (beautified.error) {
|
||||
printfn("// !!! beautify failed !!!");
|
||||
printfn(beautified.error.stack);
|
||||
} else if (sandbox.same_stdout(sandbox.run_code(beautified.code), result)) {
|
||||
printfn("// (beautified)");
|
||||
printfn(beautified.code);
|
||||
return;
|
||||
function try_beautify(code, result) {
|
||||
try {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
fromString: true,
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
},
|
||||
}).code;
|
||||
if (sandbox.same_stdout(sandbox.run_code(beautified), result)) {
|
||||
console.log("// (beautified)");
|
||||
console.log(beautified);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(e.stack);
|
||||
}
|
||||
printfn("//");
|
||||
printfn(code);
|
||||
console.log("//");
|
||||
console.log(code);
|
||||
}
|
||||
|
||||
var default_options = UglifyJS.default_options();
|
||||
function infer_options(ctor) {
|
||||
try {
|
||||
ctor({ 0: 0 });
|
||||
} catch (e) {
|
||||
return e.defs;
|
||||
}
|
||||
}
|
||||
|
||||
var default_options = {
|
||||
compress: infer_options(UglifyJS.Compressor),
|
||||
mangle: {
|
||||
"cache": null,
|
||||
"eval": false,
|
||||
"ie8": false,
|
||||
"keep_fnames": false,
|
||||
"toplevel": false,
|
||||
},
|
||||
output: infer_options(UglifyJS.OutputStream),
|
||||
};
|
||||
|
||||
function log_suspects(minify_options, component) {
|
||||
var options = component in minify_options ? minify_options[component] : true;
|
||||
if (!options) return;
|
||||
if (typeof options != "object") options = {};
|
||||
var defs = default_options[component];
|
||||
var suspects = Object.keys(defs).filter(function(name) {
|
||||
if ((name in options ? options : defs)[name]) {
|
||||
options = UglifyJS.defaults(options, default_options[component]);
|
||||
var suspects = Object.keys(default_options[component]).filter(function(name) {
|
||||
if (options[name]) {
|
||||
var m = JSON.parse(JSON.stringify(minify_options));
|
||||
var o = JSON.parse(JSON.stringify(options));
|
||||
o[name] = false;
|
||||
m[component] = o;
|
||||
var result = UglifyJS.minify(original_code, m);
|
||||
if (result.error) {
|
||||
errorln("Error testing options." + component + "." + name);
|
||||
errorln(result.error.stack);
|
||||
} else {
|
||||
var r = sandbox.run_code(result.code);
|
||||
try {
|
||||
var r = sandbox.run_code(UglifyJS.minify(original_code, m).code);
|
||||
return sandbox.same_stdout(original_result, r);
|
||||
} catch (e) {
|
||||
console.log("Error testing options." + component + "." + name);
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (suspects.length > 0) {
|
||||
errorln("Suspicious " + component + " options:");
|
||||
console.log("Suspicious", component, "options:");
|
||||
suspects.forEach(function(name) {
|
||||
errorln(" " + name);
|
||||
console.log(" " + name);
|
||||
});
|
||||
errorln();
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
|
||||
function log(options) {
|
||||
if (!ok) errorln('\n\n\n\n\n\n!!!!!!!!!!\n\n\n');
|
||||
errorln("//=============================================================");
|
||||
if (!ok) errorln("// !!!!!! Failed... round " + round);
|
||||
errorln("// original code");
|
||||
try_beautify(original_code, original_result, errorln);
|
||||
errorln();
|
||||
errorln();
|
||||
errorln("//-------------------------------------------------------------");
|
||||
if (!ok) console.log('\n\n\n\n\n\n!!!!!!!!!!\n\n\n');
|
||||
console.log("//=============================================================");
|
||||
if (!ok) console.log("// !!!!!! Failed... round", round);
|
||||
console.log("// original code");
|
||||
try_beautify(original_code, original_result);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("//-------------------------------------------------------------");
|
||||
if (typeof uglify_code == "string") {
|
||||
errorln("// uglified code");
|
||||
try_beautify(uglify_code, uglify_result, errorln);
|
||||
errorln();
|
||||
errorln();
|
||||
errorln("original result:");
|
||||
errorln(typeof original_result == "string" ? original_result : original_result.stack);
|
||||
errorln("uglified result:");
|
||||
errorln(typeof uglify_result == "string" ? uglify_result : uglify_result.stack);
|
||||
console.log("// uglified code");
|
||||
try_beautify(uglify_code, uglify_result);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("original result:");
|
||||
console.log(original_result);
|
||||
console.log("uglified result:");
|
||||
console.log(uglify_result);
|
||||
} else {
|
||||
errorln("// !!! uglify failed !!!");
|
||||
errorln(uglify_code.stack);
|
||||
console.log("// !!! uglify failed !!!");
|
||||
console.log(uglify_code.stack);
|
||||
if (typeof original_result != "string") {
|
||||
errorln();
|
||||
errorln();
|
||||
errorln("original stacktrace:");
|
||||
errorln(original_result.stack);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("original stacktrace:");
|
||||
console.log(original_result.stack);
|
||||
}
|
||||
}
|
||||
errorln("minify(options):");
|
||||
console.log("minify(options):");
|
||||
options = JSON.parse(options);
|
||||
errorln(JSON.stringify(options, null, 2));
|
||||
errorln();
|
||||
console.log(options);
|
||||
console.log();
|
||||
if (!ok && typeof uglify_code == "string") {
|
||||
Object.keys(default_options).forEach(log_suspects.bind(null, options));
|
||||
errorln("!!!!!! Failed... round " + round);
|
||||
console.log("!!!!!! Failed... round", round);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,7 +1055,10 @@ var fallback_options = [ JSON.stringify({
|
||||
compress: false,
|
||||
mangle: false
|
||||
}) ];
|
||||
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||
var minify_options = require("./ufuzz.json").map(function(options) {
|
||||
options.fromString = true;
|
||||
return JSON.stringify(options);
|
||||
});
|
||||
var original_code, original_result;
|
||||
var uglify_code, uglify_result, ok;
|
||||
for (var round = 1; round <= num_iterations; round++) {
|
||||
@@ -1055,32 +1067,34 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
original_code = createTopLevelCode();
|
||||
original_result = sandbox.run_code(original_code);
|
||||
(typeof original_result != "string" ? fallback_options : minify_options).forEach(function(options) {
|
||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options));
|
||||
if (!uglify_code.error) {
|
||||
uglify_code = uglify_code.code;
|
||||
try {
|
||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options)).code;
|
||||
} catch (e) {
|
||||
uglify_code = e;
|
||||
}
|
||||
|
||||
ok = typeof uglify_code == "string";
|
||||
if (ok) {
|
||||
uglify_result = sandbox.run_code(uglify_code);
|
||||
ok = sandbox.same_stdout(original_result, uglify_result);
|
||||
} else {
|
||||
uglify_code = uglify_code.error;
|
||||
if (typeof original_result != "string") {
|
||||
ok = uglify_code.name == original_result.name;
|
||||
}
|
||||
} else if (typeof original_result != "string") {
|
||||
ok = uglify_code.name == original_result.name;
|
||||
}
|
||||
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
||||
else if (typeof original_result != "string") {
|
||||
println("//=============================================================");
|
||||
println("// original code");
|
||||
try_beautify(original_code, original_result, println);
|
||||
println();
|
||||
println();
|
||||
println("original result:");
|
||||
println(original_result.stack);
|
||||
println();
|
||||
console.log("//=============================================================");
|
||||
console.log("// original code");
|
||||
try_beautify(original_code, original_result);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("original result:");
|
||||
console.log(original_result);
|
||||
console.log();
|
||||
}
|
||||
if (!ok && isFinite(num_iterations)) {
|
||||
println();
|
||||
console.log();
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
println();
|
||||
console.log();
|
||||
|
||||
@@ -11,12 +11,20 @@
|
||||
"compress": false
|
||||
},
|
||||
{
|
||||
"compress": {
|
||||
"warnings": false
|
||||
},
|
||||
"mangle": false
|
||||
},
|
||||
{},
|
||||
{
|
||||
"compress": {
|
||||
"toplevel": true
|
||||
"warnings": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"compress": {
|
||||
"toplevel": true,
|
||||
"warnings": false
|
||||
},
|
||||
"mangle": {
|
||||
"toplevel": true
|
||||
@@ -25,7 +33,8 @@
|
||||
{
|
||||
"compress": {
|
||||
"keep_fargs": false,
|
||||
"passes": 3
|
||||
"passes": 3,
|
||||
"warnings": false
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
11204
tools/domprops.json
11204
tools/domprops.json
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user