Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d758a216b | ||
|
|
af13f8dd2c | ||
|
|
88423f2574 | ||
|
|
ee632a5519 | ||
|
|
dfe47bcc42 | ||
|
|
6d3dcaa59e | ||
|
|
1bc0df1569 | ||
|
|
a98ba994bd | ||
|
|
cd671221c5 | ||
|
|
bce3919748 | ||
|
|
61b66e83f1 | ||
|
|
a5db8cd14c | ||
|
|
2021c2fa3e | ||
|
|
484d3fd8c7 | ||
|
|
3bf8699f95 | ||
|
|
58c24f8007 | ||
|
|
e61bc34eb1 | ||
|
|
8b2cfd45fa | ||
|
|
ae9f56be10 | ||
|
|
9aed0e3a73 | ||
|
|
88850a6e05 | ||
|
|
9e881407bd | ||
|
|
3188db7b90 | ||
|
|
a82ca62b66 | ||
|
|
e9465717ab | ||
|
|
e89031f1af | ||
|
|
596fad182e | ||
|
|
ed69adedcd | ||
|
|
1dbf7d4a3a | ||
|
|
2a9d0fc6fb | ||
|
|
45db96679e | ||
|
|
1d15f51238 | ||
|
|
ed7c82fa5e | ||
|
|
3b273cecac | ||
|
|
d764b6cc3b | ||
|
|
08c4729eb4 | ||
|
|
5561d3e7f3 | ||
|
|
491d6ce1d5 | ||
|
|
cd55eeb77c | ||
|
|
3230952d57 | ||
|
|
df3bb8028a | ||
|
|
28b7b15da1 | ||
|
|
aa37b19698 | ||
|
|
02e889e449 | ||
|
|
486ce00b8e | ||
|
|
eb481cee8c | ||
|
|
fbc9d8009b | ||
|
|
04fd3d90f8 | ||
|
|
a489f8cb5e | ||
|
|
e2e4b7fb37 | ||
|
|
c97ad98f92 | ||
|
|
b24eb22c6b | ||
|
|
06ba4e2ce8 | ||
|
|
0eb4577a82 | ||
|
|
43498769f0 | ||
|
|
60c0bc1e6b | ||
|
|
6a5c63e1e3 | ||
|
|
d47ea77811 | ||
|
|
7840746bd9 |
4
.github/workflows/ufuzz.yml
vendored
4
.github/workflows/ufuzz.yml
vendored
@@ -17,13 +17,13 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add 10 && nvs use 10'; do
|
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add 8 && nvs use 8'; do
|
||||||
cd ~/.nvs
|
cd ~/.nvs
|
||||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
cd -
|
cd -
|
||||||
done
|
done
|
||||||
. ~/.nvs/nvs.sh --version
|
. ~/.nvs/nvs.sh --version
|
||||||
nvs use 10
|
nvs use 8
|
||||||
node --version
|
node --version
|
||||||
npm config set audit false
|
npm config set audit false
|
||||||
npm config set optional false
|
npm config set optional false
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
build: off
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
test_script:
|
|
||||||
- echo No longer in use
|
|
||||||
492
bin/uglifyjs
492
bin/uglifyjs
@@ -8,185 +8,252 @@ require("../tools/exit");
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var program = require("commander");
|
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {};
|
||||||
compress: false,
|
var short_forms = {
|
||||||
mangle: false
|
b: "beautify",
|
||||||
|
c: "compress",
|
||||||
|
d: "define",
|
||||||
|
e: "enclose",
|
||||||
|
h: "help",
|
||||||
|
m: "mangle",
|
||||||
|
o: "output",
|
||||||
|
O: "output-opts",
|
||||||
|
p: "parse",
|
||||||
|
v: "version",
|
||||||
|
V: "version",
|
||||||
};
|
};
|
||||||
program.version(info.name + " " + info.version);
|
var args = process.argv.slice(2);
|
||||||
program.parseArgv = program.parse;
|
var paths = [];
|
||||||
program.parse = undefined;
|
var output, nameCache;
|
||||||
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
var specified = {};
|
||||||
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
while (args.length) {
|
||||||
var text = [];
|
var arg = args.shift();
|
||||||
var toplevels = [];
|
if (arg[0] != "-") {
|
||||||
var padding = "";
|
paths.push(arg);
|
||||||
var options = UglifyJS.default_options();
|
} else if (arg == "--") {
|
||||||
for (var name in options) {
|
paths = paths.concat(args);
|
||||||
var option = options[name];
|
break;
|
||||||
if (option && typeof option == "object") {
|
} else if (arg[1] == "-") {
|
||||||
text.push("--" + ({
|
process_option(arg.slice(2));
|
||||||
output: "beautify",
|
} else [].forEach.call(arg.slice(1), function(letter, index, arg) {
|
||||||
sourceMap: "source-map",
|
if (!(letter in short_forms)) fatal("invalid option -" + letter);
|
||||||
}[name] || name) + " options:");
|
process_option(short_forms[letter], index + 1 < arg.length);
|
||||||
text.push(format_object(option));
|
|
||||||
text.push("");
|
|
||||||
} else {
|
|
||||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
|
||||||
toplevels.push([ {
|
|
||||||
keep_fnames: "keep-fnames",
|
|
||||||
nameCache: "name-cache",
|
|
||||||
}[name] || name, option ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toplevels.forEach(function(tokens) {
|
|
||||||
text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
|
||||||
});
|
});
|
||||||
return text.join("\n");
|
}
|
||||||
};
|
|
||||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
function process_option(name, no_value) {
|
||||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
specified[name] = true;
|
||||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
switch (name) {
|
||||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
case "help":
|
||||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
switch (read_value()) {
|
||||||
program.option("-O, --output-opts [options]", "Output options (beautify disabled).", parse_js());
|
case "ast":
|
||||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
print(UglifyJS.describe_ast());
|
||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
break;
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
case "options":
|
||||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
var text = [];
|
||||||
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed everything in a big function, with configurable argument(s) & value(s).");
|
var toplevels = [];
|
||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
var padding = "";
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
var defaults = UglifyJS.default_options();
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
for (var name in defaults) {
|
||||||
program.option("--rename", "Force symbol expansion.");
|
var option = defaults[name];
|
||||||
program.option("--no-rename", "Disable symbol expansion.");
|
if (option && typeof option == "object") {
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
text.push("--" + ({
|
||||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
|
output: "beautify",
|
||||||
program.option("--timings", "Display operations run time on STDERR.");
|
sourceMap: "source-map",
|
||||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
}[name] || name) + " options:");
|
||||||
program.option("--validate", "Perform validation during AST manipulations.");
|
text.push(format_object(option));
|
||||||
program.option("--verbose", "Print diagnostic messages.");
|
text.push("");
|
||||||
program.option("--warn", "Print warning messages.");
|
} else {
|
||||||
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||||
program.option("--reduce-test", "Reduce a standalone `console.log` based test case.");
|
toplevels.push([ {
|
||||||
program.arguments("[files...]").parseArgv(process.argv);
|
keep_fnames: "keep-fnames",
|
||||||
if (program.configFile) {
|
nameCache: "name-cache",
|
||||||
options = JSON.parse(read_file(program.configFile));
|
}[name] || name, option ]);
|
||||||
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
|
}
|
||||||
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
|
}
|
||||||
expression: true
|
toplevels.forEach(function(tokens) {
|
||||||
}).value;
|
text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||||
|
});
|
||||||
|
print(text.join("\n"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print([
|
||||||
|
"Usage: uglifyjs [files...] [options]",
|
||||||
|
"",
|
||||||
|
"Options:",
|
||||||
|
" -h, --help Print usage information.",
|
||||||
|
" `--help options` for details on available options.",
|
||||||
|
" -v, -V, --version Print version number.",
|
||||||
|
" -p, --parse <options> Specify parser options.",
|
||||||
|
" -c, --compress [options] Enable compressor/specify compressor options.",
|
||||||
|
" -m, --mangle [options] Mangle names/specify mangler options.",
|
||||||
|
" --mangle-props [options] Mangle properties/specify mangler options.",
|
||||||
|
" -b, --beautify [options] Beautify output/specify output options.",
|
||||||
|
" -O, --output-opts <options> Output options (beautify disabled).",
|
||||||
|
" -o, --output <file> Output file (default STDOUT).",
|
||||||
|
" --comments [filter] Preserve copyright comments in the output.",
|
||||||
|
" --config-file <file> Read minify() options from JSON file.",
|
||||||
|
" -d, --define <expr>[=value] Global definitions.",
|
||||||
|
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
|
||||||
|
" --ie8 Support non-standard Internet Explorer 8.",
|
||||||
|
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||||
|
" --name-cache <file> File to hold mangled name mappings.",
|
||||||
|
" --rename Force symbol expansion.",
|
||||||
|
" --no-rename Disable symbol expansion.",
|
||||||
|
" --self Build UglifyJS as a library (implies --wrap UglifyJS)",
|
||||||
|
" --source-map [options] Enable source map/specify source map options.",
|
||||||
|
" --timings Display operations run time on STDERR.",
|
||||||
|
" --toplevel Compress and/or mangle variables in toplevel scope.",
|
||||||
|
" --validate Perform validation during AST manipulations.",
|
||||||
|
" --verbose Print diagnostic messages.",
|
||||||
|
" --warn Print warning messages.",
|
||||||
|
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
|
||||||
|
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
|
||||||
|
].join("\n"));
|
||||||
|
}
|
||||||
|
process.exit();
|
||||||
|
case "version":
|
||||||
|
print(info.name + " " + info.version);
|
||||||
|
process.exit();
|
||||||
|
case "config-file":
|
||||||
|
var config = JSON.parse(read_file(read_value(true)));
|
||||||
|
if (config.mangle && config.mangle.properties && config.mangle.properties.regex) {
|
||||||
|
config.mangle.properties.regex = UglifyJS.parse(config.mangle.properties.regex, {
|
||||||
|
expression: true,
|
||||||
|
}).value;
|
||||||
|
}
|
||||||
|
for (var key in config) if (!(key in options)) options[key] = config[key];
|
||||||
|
break;
|
||||||
|
case "compress":
|
||||||
|
case "mangle":
|
||||||
|
options[name] = parse_js(read_value(), options[name]);
|
||||||
|
break;
|
||||||
|
case "source-map":
|
||||||
|
options.sourceMap = parse_js(read_value(), options.sourceMap);
|
||||||
|
break;
|
||||||
|
case "enclose":
|
||||||
|
options[name] = read_value();
|
||||||
|
break;
|
||||||
|
case "ie8":
|
||||||
|
case "timings":
|
||||||
|
case "toplevel":
|
||||||
|
case "validate":
|
||||||
|
options[name] = true;
|
||||||
|
break;
|
||||||
|
case "keep-fnames":
|
||||||
|
options.keep_fnames = true;
|
||||||
|
break;
|
||||||
|
case "wrap":
|
||||||
|
options[name] = read_value(true);
|
||||||
|
break;
|
||||||
|
case "verbose":
|
||||||
|
options.warnings = "verbose";
|
||||||
|
break;
|
||||||
|
case "warn":
|
||||||
|
if (!options.warnings) options.warnings = true;
|
||||||
|
break;
|
||||||
|
case "beautify":
|
||||||
|
options.output = parse_js(read_value(), options.output);
|
||||||
|
if (!("beautify" in options.output)) options.output.beautify = true;
|
||||||
|
break;
|
||||||
|
case "output-opts":
|
||||||
|
options.output = parse_js(read_value(true), options.output);
|
||||||
|
break;
|
||||||
|
case "comments":
|
||||||
|
if (typeof options.output != "object") options.output = {};
|
||||||
|
options.output.comments = read_value();
|
||||||
|
if (options.output.comments === true) options.output.comments = "some";
|
||||||
|
break;
|
||||||
|
case "define":
|
||||||
|
if (typeof options.compress != "object") options.compress = {};
|
||||||
|
options.compress.global_defs = parse_js(read_value(true), options.compress.global_defs, "define");
|
||||||
|
break;
|
||||||
|
case "mangle-props":
|
||||||
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
|
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
|
||||||
|
break;
|
||||||
|
case "name-cache":
|
||||||
|
nameCache = read_value(true);
|
||||||
|
options.nameCache = JSON.parse(read_file(nameCache, "{}"));
|
||||||
|
break;
|
||||||
|
case "output":
|
||||||
|
output = read_value(true);
|
||||||
|
break;
|
||||||
|
case "parse":
|
||||||
|
options.parse = parse_js(read_value(true), options.parse);
|
||||||
|
break;
|
||||||
|
case "rename":
|
||||||
|
options.rename = true;
|
||||||
|
break;
|
||||||
|
case "no-rename":
|
||||||
|
options.rename = false;
|
||||||
|
break;
|
||||||
|
case "reduce-test":
|
||||||
|
case "self":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatal("invalid option --" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_value(required) {
|
||||||
|
if (no_value || !args.length || args[0][0] == "-") {
|
||||||
|
if (required) fatal("missing option argument for --" + name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return args.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
if (!output && options.sourceMap && options.sourceMap.url != "inline") fatal("cannot write source map to STDOUT");
|
||||||
fatal("cannot write source map to STDOUT");
|
if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot be used with --output-opts");
|
||||||
}
|
[ "compress", "mangle" ].forEach(function(name) {
|
||||||
[
|
if (!(name in options)) options[name] = false;
|
||||||
"compress",
|
|
||||||
"enclose",
|
|
||||||
"ie8",
|
|
||||||
"mangle",
|
|
||||||
"sourceMap",
|
|
||||||
"toplevel",
|
|
||||||
"validate",
|
|
||||||
"wrap"
|
|
||||||
].forEach(function(name) {
|
|
||||||
if (name in program) {
|
|
||||||
options[name] = program[name];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (program.verbose) {
|
if (options.mangle && options.mangle.properties) {
|
||||||
options.warnings = "verbose";
|
if (options.mangle.properties.domprops) {
|
||||||
} else if (program.warn) {
|
delete options.mangle.properties.domprops;
|
||||||
options.warnings = true;
|
} else {
|
||||||
|
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
||||||
|
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
|
||||||
|
require("../tools/domprops").forEach(function(name) {
|
||||||
|
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (output == "ast") options.output = {
|
||||||
|
ast: true,
|
||||||
|
code: false,
|
||||||
|
};
|
||||||
|
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
|
||||||
|
&& options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
|
fatal("inline source map only works with built-in parser");
|
||||||
}
|
}
|
||||||
if (options.warnings) {
|
if (options.warnings) {
|
||||||
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
|
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
|
||||||
delete options.warnings;
|
delete options.warnings;
|
||||||
}
|
}
|
||||||
if (program.beautify) {
|
|
||||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
|
||||||
if (!("beautify" in options.output)) {
|
|
||||||
options.output.beautify = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (program.outputOpts) {
|
|
||||||
if (program.beautify) fatal("--beautify cannot be used with --output-opts");
|
|
||||||
options.output = typeof program.outputOpts == "object" ? program.outputOpts : {};
|
|
||||||
}
|
|
||||||
if (program.comments) {
|
|
||||||
if (typeof options.output != "object") options.output = {};
|
|
||||||
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
|
||||||
}
|
|
||||||
if (program.define) {
|
|
||||||
if (typeof options.compress != "object") options.compress = {};
|
|
||||||
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
|
||||||
for (var expr in program.define) {
|
|
||||||
options.compress.global_defs[expr] = program.define[expr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (program.keepFnames) {
|
|
||||||
options.keep_fnames = true;
|
|
||||||
}
|
|
||||||
if (program.mangleProps) {
|
|
||||||
if (program.mangleProps.domprops) {
|
|
||||||
delete program.mangleProps.domprops;
|
|
||||||
} else {
|
|
||||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
|
||||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
|
||||||
require("../tools/domprops").forEach(function(name) {
|
|
||||||
UglifyJS.push_uniq(program.mangleProps.reserved, name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
|
||||||
options.mangle.properties = program.mangleProps;
|
|
||||||
}
|
|
||||||
if (program.nameCache) {
|
|
||||||
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
|
||||||
}
|
|
||||||
if (program.output == "ast") {
|
|
||||||
options.output = {
|
|
||||||
ast: true,
|
|
||||||
code: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (program.parse) {
|
|
||||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
|
||||||
options.parse = program.parse;
|
|
||||||
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
|
||||||
fatal("inline source map only works with built-in parser");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (~program.rawArgs.indexOf("--rename")) {
|
|
||||||
options.rename = true;
|
|
||||||
} else if (!program.rename) {
|
|
||||||
options.rename = false;
|
|
||||||
}
|
|
||||||
var convert_path = function(name) {
|
var convert_path = function(name) {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
if (typeof options.sourceMap == "object" && "base" in options.sourceMap) {
|
||||||
convert_path = function() {
|
convert_path = function() {
|
||||||
var base = program.sourceMap.base;
|
var base = options.sourceMap.base;
|
||||||
delete options.sourceMap.base;
|
delete options.sourceMap.base;
|
||||||
return function(name) {
|
return function(name) {
|
||||||
return path.relative(base, name);
|
return path.relative(base, name);
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
if (program.self) {
|
if (specified["self"]) {
|
||||||
if (program.args.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||||
if (!options.wrap) options.wrap = "UglifyJS";
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
paths = UglifyJS.FILES;
|
||||||
files[convert_path(name)] = read_file(name);
|
}
|
||||||
});
|
if (paths.length) {
|
||||||
run();
|
simple_glob(paths).forEach(function(name) {
|
||||||
} else if (program.args.length) {
|
|
||||||
simple_glob(program.args).forEach(function(name) {
|
|
||||||
files[convert_path(name)] = read_file(name);
|
files[convert_path(name)] = read_file(name);
|
||||||
});
|
});
|
||||||
run();
|
run();
|
||||||
@@ -207,15 +274,14 @@ function convert_ast(fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
var content = program.sourceMap && program.sourceMap.content;
|
var content = options.sourceMap && options.sourceMap.content;
|
||||||
if (content && content != "inline") {
|
if (content && content != "inline") {
|
||||||
UglifyJS.AST_Node.info("Using input source map: " + content);
|
UglifyJS.AST_Node.info("Using input source map: " + content);
|
||||||
options.sourceMap.content = read_file(content, content);
|
options.sourceMap.content = read_file(content, content);
|
||||||
}
|
}
|
||||||
if (program.timings) options.timings = true;
|
|
||||||
try {
|
try {
|
||||||
if (program.parse) {
|
if (options.parse) {
|
||||||
if (program.parse.acorn) {
|
if (options.parse.acorn) {
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
return require("acorn").parse(files[name], {
|
return require("acorn").parse(files[name], {
|
||||||
locations: true,
|
locations: true,
|
||||||
@@ -223,7 +289,7 @@ function run() {
|
|||||||
sourceFile: name
|
sourceFile: name
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (program.parse.spidermonkey) {
|
} else if (options.parse.spidermonkey) {
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
var obj = JSON.parse(files[name]);
|
var obj = JSON.parse(files[name]);
|
||||||
if (!toplevel) return obj;
|
if (!toplevel) return obj;
|
||||||
@@ -235,17 +301,17 @@ function run() {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
if (program.reduceTest) {
|
var result;
|
||||||
// load on demand - assumes dev tree checked out
|
if (specified["reduce-test"]) {
|
||||||
|
// load on demand - assumes cloned repository
|
||||||
var reduce_test = require("../test/reduce");
|
var reduce_test = require("../test/reduce");
|
||||||
var testcase = files[0] || files[Object.keys(files)[0]];
|
if (Object.keys(files).length != 1) fatal("can only test on a single file");
|
||||||
var result = reduce_test(testcase, options, {
|
result = reduce_test(files[Object.keys(files)[0]], options, {
|
||||||
log: print_error,
|
log: print_error,
|
||||||
verbose: true,
|
verbose: true,
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
result = UglifyJS.minify(files, options);
|
||||||
var result = UglifyJS.minify(files, options);
|
|
||||||
}
|
}
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
var ex = result.error;
|
var ex = result.error;
|
||||||
@@ -275,10 +341,8 @@ function run() {
|
|||||||
print_error(format_object(ex.defs));
|
print_error(format_object(ex.defs));
|
||||||
}
|
}
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (output == "ast") {
|
||||||
if (!options.compress && !options.mangle) {
|
if (!options.compress && !options.mangle) result.ast.figure_out_scope({});
|
||||||
result.ast.figure_out_scope({});
|
|
||||||
}
|
|
||||||
print(JSON.stringify(result.ast, function(key, value) {
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
if (value) switch (key) {
|
if (value) switch (key) {
|
||||||
case "thedef":
|
case "thedef":
|
||||||
@@ -304,26 +368,22 @@ function run() {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}, 2));
|
}, 2));
|
||||||
} else if (program.output == "spidermonkey") {
|
} else if (output == "spidermonkey") {
|
||||||
print(JSON.stringify(UglifyJS.minify(result.code, {
|
print(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
ast: true,
|
||||||
code: false
|
code: false
|
||||||
}
|
},
|
||||||
}).ast.to_mozilla_ast(), null, 2));
|
}).ast.to_mozilla_ast(), null, 2));
|
||||||
} else if (program.output) {
|
} else if (output) {
|
||||||
fs.writeFileSync(program.output, result.code);
|
fs.writeFileSync(output, result.code);
|
||||||
if (result.map) {
|
if (result.map) fs.writeFileSync(output + ".map", result.map);
|
||||||
fs.writeFileSync(program.output + ".map", result.map);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
print(result.code);
|
print(result.code);
|
||||||
}
|
}
|
||||||
if (program.nameCache) {
|
if (nameCache) fs.writeFileSync(nameCache, JSON.stringify(options.nameCache));
|
||||||
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
|
||||||
}
|
|
||||||
if (result.timings) for (var phase in result.timings) {
|
if (result.timings) for (var phase in result.timings) {
|
||||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||||
}
|
}
|
||||||
@@ -379,47 +439,45 @@ function read_file(path, default_value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_js(flag) {
|
function parse_js(value, options, flag) {
|
||||||
return function(value, options) {
|
if (!options || typeof options != "object") options = {};
|
||||||
options = options || {};
|
if (typeof value == "string") try {
|
||||||
try {
|
UglifyJS.parse(value, {
|
||||||
UglifyJS.parse(value, {
|
expression: true
|
||||||
expression: true
|
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
var name = node.left.print_to_string();
|
||||||
var name = node.left.print_to_string();
|
var value = node.right;
|
||||||
var value = node.right;
|
if (flag) {
|
||||||
if (flag) {
|
options[name] = value;
|
||||||
options[name] = value;
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
} else if (value instanceof UglifyJS.AST_Array) {
|
options[name] = value.elements.map(to_string);
|
||||||
options[name] = value.elements.map(to_string);
|
} else {
|
||||||
} else {
|
options[name] = to_string(value);
|
||||||
options[name] = to_string(value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
return true;
|
||||||
var name = node.print_to_string();
|
|
||||||
options[name] = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
|
||||||
|
|
||||||
function to_string(value) {
|
|
||||||
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
|
|
||||||
quote_keys: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} catch (ex) {
|
|
||||||
if (flag) {
|
|
||||||
fatal("cannot parse arguments for '" + flag + "': " + value);
|
|
||||||
} else {
|
|
||||||
options[value] = null;
|
|
||||||
}
|
}
|
||||||
|
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
||||||
|
var name = node.print_to_string();
|
||||||
|
options[name] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||||
|
|
||||||
|
function to_string(value) {
|
||||||
|
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
|
||||||
|
quote_keys: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} catch (ex) {
|
||||||
|
if (flag) {
|
||||||
|
fatal("cannot parse arguments for '" + flag + "': " + value);
|
||||||
|
} else {
|
||||||
|
options[value] = null;
|
||||||
}
|
}
|
||||||
return options;
|
|
||||||
}
|
}
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
function skip_key(key) {
|
function skip_key(key) {
|
||||||
|
|||||||
14
lib/ast.js
14
lib/ast.js
@@ -120,6 +120,20 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
ctor.prototype._validate.call(this);
|
ctor.prototype._validate.call(this);
|
||||||
} while (ctor = ctor.BASE);
|
} while (ctor = ctor.BASE);
|
||||||
},
|
},
|
||||||
|
validate_ast: function() {
|
||||||
|
var marker = {};
|
||||||
|
this.walk(new TreeWalker(function(node) {
|
||||||
|
if (node.validate_visited === marker) {
|
||||||
|
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
||||||
|
type: "AST_" + node.TYPE,
|
||||||
|
file: node.start.file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
node.validate_visited = marker;
|
||||||
|
}));
|
||||||
|
},
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
(AST_Node.log_function = function(fn, verbose) {
|
(AST_Node.log_function = function(fn, verbose) {
|
||||||
|
|||||||
813
lib/compress.js
813
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -178,13 +178,17 @@ function minify(files, options) {
|
|||||||
toplevel = toplevel[action](option);
|
toplevel = toplevel[action](option);
|
||||||
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
||||||
});
|
});
|
||||||
|
if (options.validate) toplevel.validate_ast();
|
||||||
if (timings) timings.rename = Date.now();
|
if (timings) timings.rename = Date.now();
|
||||||
if (options.rename) {
|
if (options.rename) {
|
||||||
toplevel.figure_out_scope(options.mangle);
|
toplevel.figure_out_scope(options.mangle);
|
||||||
toplevel.expand_names(options.mangle);
|
toplevel.expand_names(options.mangle);
|
||||||
}
|
}
|
||||||
if (timings) timings.compress = Date.now();
|
if (timings) timings.compress = Date.now();
|
||||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
if (options.compress) {
|
||||||
|
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
|
if (options.validate) toplevel.validate_ast();
|
||||||
|
}
|
||||||
if (timings) timings.scope = Date.now();
|
if (timings) timings.scope = Date.now();
|
||||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||||
if (timings) timings.mangle = Date.now();
|
if (timings) timings.mangle = Date.now();
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ function OutputStream(options) {
|
|||||||
|| (ch == "/" && ch == prev)
|
|| (ch == "/" && ch == prev)
|
||||||
|| ((ch == "+" || ch == "-") && ch == last)
|
|| ((ch == "+" || ch == "-") && ch == last)
|
||||||
|| str == "--" && last == "!"
|
|| str == "--" && last == "!"
|
||||||
|
|| str == "in" && prev == "/"
|
||||||
|| last == "--" && ch == ">") {
|
|| last == "--" && ch == ">") {
|
||||||
OUTPUT += " ";
|
OUTPUT += " ";
|
||||||
current_col++;
|
current_col++;
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
} else {
|
} else {
|
||||||
new_def = scope.def_variable(node);
|
new_def = scope.def_variable(node);
|
||||||
}
|
}
|
||||||
|
old_def.defun = new_def.scope;
|
||||||
old_def.orig.concat(old_def.references).forEach(function(node) {
|
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||||
node.thedef = new_def;
|
node.thedef = new_def;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
@@ -543,11 +544,8 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
|||||||
var redef = def.redefined();
|
var redef = def.redefined();
|
||||||
var name = redef ? redef.rename || redef.name : next_name();
|
var name = redef ? redef.rename || redef.name : next_name();
|
||||||
def.rename = name;
|
def.rename = name;
|
||||||
def.orig.forEach(function(sym) {
|
def.orig.concat(def.references).forEach(function(sym) {
|
||||||
sym.name = name;
|
if (sym.definition() === def) sym.name = name;
|
||||||
});
|
|
||||||
def.references.forEach(function(sym) {
|
|
||||||
sym.name = name;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.9.4",
|
"version": "3.10.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -22,9 +22,6 @@
|
|||||||
"tools",
|
"tools",
|
||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
|
||||||
"commander": "~2.20.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~7.1.0",
|
"acorn": "~7.1.0",
|
||||||
"semver": "~6.3.0"
|
"semver": "~6.3.0"
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ function test_case(test) {
|
|||||||
quote_style: 3,
|
quote_style: 3,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
input.validate_ast();
|
||||||
U.parse(input_code);
|
U.parse(input_code);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log([
|
log([
|
||||||
@@ -315,8 +316,8 @@ function test_case(test) {
|
|||||||
output = U.mangle_properties(output, test.mangle.properties);
|
output = U.mangle_properties(output, test.mangle.properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output = make_code(output, output_options);
|
var output_code = make_code(output, output_options);
|
||||||
if (expect != output) {
|
if (expect != output_code) {
|
||||||
log([
|
log([
|
||||||
"!!! failed",
|
"!!! failed",
|
||||||
"---INPUT---",
|
"---INPUT---",
|
||||||
@@ -329,14 +330,15 @@ function test_case(test) {
|
|||||||
"",
|
"",
|
||||||
].join("\n"), {
|
].join("\n"), {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
output: output,
|
output: output_code,
|
||||||
expected: expect
|
expected: expect
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// expect == output
|
// expect == output
|
||||||
try {
|
try {
|
||||||
U.parse(output);
|
output.validate_ast();
|
||||||
|
U.parse(output_code);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log([
|
log([
|
||||||
"!!! Test matched expected result but cannot parse output",
|
"!!! Test matched expected result but cannot parse output",
|
||||||
@@ -350,7 +352,7 @@ function test_case(test) {
|
|||||||
"",
|
"",
|
||||||
].join("\n"), {
|
].join("\n"), {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
output: output,
|
output: output_code,
|
||||||
error: ex,
|
error: ex,
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
@@ -409,7 +411,7 @@ function test_case(test) {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
actual = run_code(output, toplevel);
|
actual = run_code(output_code, toplevel);
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! failed",
|
"!!! failed",
|
||||||
|
|||||||
@@ -243,20 +243,18 @@ issue_3273: {
|
|||||||
arguments: true,
|
arguments: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(a, a);
|
console.log(a, a);
|
||||||
a++;
|
a++;
|
||||||
console.log(a, a);
|
console.log(a, a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
@@ -264,26 +262,43 @@ issue_3273: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3273_no_call_arg: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
arguments[0] = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
arguments[0] = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3273_reduce_vars: {
|
issue_3273_reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(a, a);
|
console.log(a, a);
|
||||||
a++;
|
a++;
|
||||||
console.log(a, a);
|
console.log(a, a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
@@ -296,22 +311,20 @@ issue_3273_local_strict: {
|
|||||||
arguments: true,
|
arguments: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
@@ -325,22 +338,20 @@ issue_3273_local_strict_reduce_vars: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
(function(a) {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
@@ -354,21 +365,19 @@ issue_3273_global_strict: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
"use strict";
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
@@ -383,21 +392,19 @@ issue_3273_global_strict_reduce_vars: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
"use strict";
|
||||||
function f(a) {
|
(function(a) {
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
arguments[0]++;
|
arguments[0]++;
|
||||||
console.log(arguments[0], a);
|
console.log(arguments[0], a);
|
||||||
}
|
})(0);
|
||||||
f(0);
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"0 0",
|
"0 0",
|
||||||
|
|||||||
@@ -407,3 +407,57 @@ issue_3429_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3949_1: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b = b >> 2;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b >>= 2;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "110"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_2: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b = 5 & b;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b &= 5;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "100"
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ collapse_vars_side_effects_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f1() {
|
function f1() {
|
||||||
var s = "abcdef", i = 2;
|
var s = "abcdef", i = 2;
|
||||||
console.log.bind(console)(s.charAt(i++), s.charAt(i++), s.charAt(i++), 7);
|
console.log.bind(console)(s.charAt(i++), s.charAt(i++), s.charAt(4), 7);
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
var s = "abcdef", i = 2;
|
var s = "abcdef", i = 2;
|
||||||
@@ -74,13 +74,14 @@ collapse_vars_side_effects_1: {
|
|||||||
log = console.log.bind(console),
|
log = console.log.bind(console),
|
||||||
x = s.charAt(i++),
|
x = s.charAt(i++),
|
||||||
y = s.charAt(i++);
|
y = s.charAt(i++);
|
||||||
log(x, s.charAt(i++), y, 7);
|
log(x, s.charAt(4), y, 7);
|
||||||
}
|
}
|
||||||
function f4() {
|
function f4() {
|
||||||
var i = 10,
|
var i = 10;
|
||||||
x = i += 2,
|
i += 2,
|
||||||
y = i += 3;
|
i += 3,
|
||||||
console.log.bind(console)(x, i += 4, y, 19);
|
i += 4;
|
||||||
|
console.log.bind(console)(12, 19, 15, 19);
|
||||||
}
|
}
|
||||||
f1(), f2(), f3(), f4();
|
f1(), f2(), f3(), f4();
|
||||||
}
|
}
|
||||||
@@ -916,7 +917,7 @@ collapse_vars_lvalues_drop_assign: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collapse_vars_misc1: {
|
collapse_vars_misc: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -970,8 +971,8 @@ collapse_vars_misc1: {
|
|||||||
function f7() { var b = window.a * window.z; return b + b }
|
function f7() { var b = window.a * window.z; return b + b }
|
||||||
function f8() { var b = window.a * window.z; return b + (5 + b) }
|
function f8() { var b = window.a * window.z; return b + (5 + b) }
|
||||||
function f9() { var b = window.a * window.z; return bar() || b }
|
function f9() { var b = window.a * window.z; return bar() || b }
|
||||||
function f10(x) { var a = 5; return a += 3; }
|
function f10(x) { return 8; }
|
||||||
function f11(x) { var a = 5; return a += 2; }
|
function f11(x) { return 7; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3000,8 +3001,7 @@ issue_2298: {
|
|||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
(function() {
|
(function() {
|
||||||
var a = undefined;
|
0;
|
||||||
var undefined = a++;
|
|
||||||
try {
|
try {
|
||||||
!function(b) {
|
!function(b) {
|
||||||
(void 0)[1] = "foo";
|
(void 0)[1] = "foo";
|
||||||
@@ -3835,20 +3835,19 @@ issue_2436_3: {
|
|||||||
}(o));
|
}(o));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
console.log(function(c) {
|
console.log(function(c) {
|
||||||
o = {
|
({
|
||||||
a: 3,
|
a: 3,
|
||||||
b: 4,
|
b: 4,
|
||||||
};
|
});
|
||||||
return {
|
return {
|
||||||
x: c.a,
|
x: c.a,
|
||||||
y: c.b,
|
y: c.b,
|
||||||
};
|
};
|
||||||
}(o));
|
}({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -4070,16 +4069,15 @@ issue_2436_10: {
|
|||||||
}(o).join(" "));
|
}(o).join(" "));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
function f(n) {
|
function f(n) {
|
||||||
o = { b: 3 };
|
({ b: 3 });
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
console.log([
|
console.log([
|
||||||
(c = o).a,
|
(c = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}).a,
|
||||||
f(c.b),
|
f(c.b),
|
||||||
c.b,
|
c.b,
|
||||||
].join(" "));
|
].join(" "));
|
||||||
@@ -6890,6 +6888,30 @@ sequence_in_iife_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "foo", b = 42;
|
var a = "foo", b = 42;
|
||||||
|
b = a;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence_in_iife_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo", b = 42;
|
||||||
|
(function() {
|
||||||
|
var c = (b = a, b);
|
||||||
|
})();
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
console.log(a, a);
|
console.log(a, a);
|
||||||
}
|
}
|
||||||
expect_stdout: "foo foo"
|
expect_stdout: "foo foo"
|
||||||
@@ -7955,7 +7977,7 @@ mangleable_var: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3884: {
|
issue_3884_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -7973,9 +7995,33 @@ issue_3884: {
|
|||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 100;
|
var a = 100, b = 1;
|
||||||
++a;
|
b <<= ++a;
|
||||||
console.log(a, 32);
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "101 32"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3884_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 100, b = 1;
|
||||||
|
{
|
||||||
|
a++ + a || a;
|
||||||
|
b <<= a;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(101, 32);
|
||||||
}
|
}
|
||||||
expect_stdout: "101 32"
|
expect_stdout: "101 32"
|
||||||
}
|
}
|
||||||
@@ -8108,3 +8154,166 @@ issue_3908: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3927: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
console.log(function(b) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (a + (b = "PASS", true)) return;
|
||||||
|
b.p;
|
||||||
|
} finally {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
console.log(function(b) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (a + (b = "PASS", true)) return;
|
||||||
|
b.p;
|
||||||
|
} finally {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
operator_in: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = "PASS";
|
||||||
|
0 in null;
|
||||||
|
log("FAIL", a);
|
||||||
|
} catch (e) {}
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = "PASS";
|
||||||
|
0 in null;
|
||||||
|
log("FAIL", a);
|
||||||
|
} catch (e) {}
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3971: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0 == typeof f, b = 0;
|
||||||
|
{
|
||||||
|
var a = void (a++ + (b |= a));
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0 == typeof f, b = 0;
|
||||||
|
var a = void (b |= ++a);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3976: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
(function(a) {
|
||||||
|
function g() {
|
||||||
|
if ((a = 0) || f(0)) {
|
||||||
|
f();
|
||||||
|
} else {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
if (h(a = 0));
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
void 0;
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4012: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (b) {
|
||||||
|
a = "PASS";
|
||||||
|
if (--b)
|
||||||
|
return;
|
||||||
|
if (3);
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (b) {
|
||||||
|
a = "PASS";
|
||||||
|
if (--b)
|
||||||
|
return;
|
||||||
|
if (3);
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ collapse_vars_lvalues_drop_assign: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collapse_vars_misc1: {
|
collapse_vars_misc: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
@@ -1169,27 +1169,175 @@ redundant_assignments: {
|
|||||||
expect_stdout: "PASS PASS"
|
expect_stdout: "PASS PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
self_assignments: {
|
self_assignments_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = "PASS", b = 0, l = [ "FAIL", "PASS" ], o = { p: "PASS" };
|
var a = "PASS";
|
||||||
a = a;
|
a = a;
|
||||||
l[0] = l[0];
|
console.log(a);
|
||||||
l[b] = l[b];
|
|
||||||
l[b++] = l[b++];
|
|
||||||
o.p = o.p;
|
|
||||||
console.log(a, b, l[0], o.p);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "PASS", b = 0, l = [ "FAIL", "PASS" ], o = { p: "PASS" };
|
var a = "PASS";
|
||||||
a;
|
a;
|
||||||
l[0];
|
console.log(a);
|
||||||
l[b];
|
|
||||||
l[b++] = l[b++];
|
|
||||||
o.p;
|
|
||||||
console.log(a, b, l[0], o.p);
|
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS 2 PASS PASS"
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_assignments_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "q", o = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
o.p = o.p;
|
||||||
|
o[a] = o[a];
|
||||||
|
console.log(o.p, o[a]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "q", o = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(o.p, o[a]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_assignments_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "q", o = {
|
||||||
|
p: "FAIL",
|
||||||
|
get q() {
|
||||||
|
return "PASS";
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
this.p = v;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.p = o.p;
|
||||||
|
o[a] = o[a];
|
||||||
|
console.log(o.p, o[a]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "q", o = {
|
||||||
|
p: "FAIL",
|
||||||
|
get q() {
|
||||||
|
return "PASS";
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
this.p = v;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.p = o.p;
|
||||||
|
o[a] = o[a];
|
||||||
|
console.log(o.p, o[a]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_assignments_4: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var i = 0, l = [ "PASS" ];
|
||||||
|
l[0] = l[0];
|
||||||
|
l[i] = l[i];
|
||||||
|
console.log(l[0], i);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var i = 0, l = [ "PASS" ];
|
||||||
|
console.log(l[0], i);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_assignments_5: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var i = 0, l = [ "FAIL", "PASS" ];
|
||||||
|
l[0] = l[0];
|
||||||
|
l[i] = l[i];
|
||||||
|
l[i++] = l[i++];
|
||||||
|
console.log(l[0], i);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var i = 0, l = [ "FAIL", "PASS" ];
|
||||||
|
l[0];
|
||||||
|
l[0];
|
||||||
|
l[0] = l[1];
|
||||||
|
console.log(l[0], 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_assignments_6: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(o.p = o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3967: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = 0 in (a = "PASS");
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = 0 in (a = "PASS");
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2285,7 +2285,7 @@ issue_3598: {
|
|||||||
try {
|
try {
|
||||||
(function() {
|
(function() {
|
||||||
a = "PASS";
|
a = "PASS";
|
||||||
var c = (void (c.p = 0))[!1];
|
(void ((void 0).p = 0))[!1];
|
||||||
})();
|
})();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
console.log(a);
|
console.log(a);
|
||||||
@@ -2557,11 +2557,294 @@ issue_3899: {
|
|||||||
console.log(typeof a);
|
console.log(typeof a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
++a;
|
function a() {
|
||||||
var a = function() {
|
|
||||||
return 2;
|
return 2;
|
||||||
};
|
}
|
||||||
console.log(typeof a);
|
console.log(typeof a);
|
||||||
}
|
}
|
||||||
expect_stdout: "function"
|
expect_stdout: "function"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cross_scope_assign_chain: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = 0;
|
||||||
|
(function() {
|
||||||
|
a = b;
|
||||||
|
a++;
|
||||||
|
while (b++);
|
||||||
|
})();
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 0;
|
||||||
|
(function() {
|
||||||
|
a = b;
|
||||||
|
a++;
|
||||||
|
while (b++);
|
||||||
|
})();
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_if_assign_read: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
var b;
|
||||||
|
do {
|
||||||
|
b = "FAIL";
|
||||||
|
if (Array.isArray(a)) {
|
||||||
|
b = a[0];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
} while (!console);
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
var b;
|
||||||
|
do {
|
||||||
|
"FAIL";
|
||||||
|
if (Array.isArray(a)) {
|
||||||
|
b = a[0];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
} while (!console);
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3951: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = console.log("PASS");
|
||||||
|
console.log(a);
|
||||||
|
a = "0";
|
||||||
|
console.log(a.p = 0);
|
||||||
|
a && a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = console.log("PASS");
|
||||||
|
console.log(a);
|
||||||
|
a = "0";
|
||||||
|
console.log(a.p = 0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3956: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
function f(b) {
|
||||||
|
console.log(b);
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
var c = f(c += 0);
|
||||||
|
(function(d) {
|
||||||
|
console.log(d);
|
||||||
|
})(console.log(a) ^ 1, c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c, d;
|
||||||
|
c += 0,
|
||||||
|
console.log(NaN),
|
||||||
|
d = 1 ^ console.log(1),
|
||||||
|
console.log(d);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"NaN",
|
||||||
|
"1",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3962_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
function f(b, c) {
|
||||||
|
do {
|
||||||
|
var d = console + e, e = 0..toString() === b;
|
||||||
|
} while (0);
|
||||||
|
if (c) console.log("PASS");
|
||||||
|
}
|
||||||
|
var a = f(a--, 1);
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
a = (function(c) {
|
||||||
|
do {
|
||||||
|
console;
|
||||||
|
0..toString();
|
||||||
|
} while (0);
|
||||||
|
if (c) console.log("PASS");
|
||||||
|
}((a--, 1)), 0);
|
||||||
|
void 0;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3962_2: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
function f(b, c) {
|
||||||
|
do {
|
||||||
|
var d = console + e, e = 0..toString() === b;
|
||||||
|
} while (0);
|
||||||
|
if (c) console.log("PASS");
|
||||||
|
}
|
||||||
|
var a = f(a--, 1);
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
a = (function(c) {
|
||||||
|
do {
|
||||||
|
console;
|
||||||
|
0..toString();
|
||||||
|
} while (0);
|
||||||
|
if (c) console.log("PASS");
|
||||||
|
}((a--, 1)), 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3986: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
b = b && 0;
|
||||||
|
})(b *= a);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
b = b && 0;
|
||||||
|
})(b *= a);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4017: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
console.log(function f() {
|
||||||
|
var b = c &= 0;
|
||||||
|
var c = a++ + (A = a);
|
||||||
|
var d = c && c[f];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
console.log(function() {
|
||||||
|
c &= 0;
|
||||||
|
var c = (a++, A = a, 0);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4025: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0, c = 0, d = a++;
|
||||||
|
try {
|
||||||
|
var e = console.log(c), f = b;
|
||||||
|
} finally {
|
||||||
|
var d = b = 1, d = c + 1;
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
console.log(a, b, d);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var d, c = 0;
|
||||||
|
try {
|
||||||
|
console.log(c);
|
||||||
|
} finally {
|
||||||
|
d = c + 1;
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
console.log(1, 1, d);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1 1 1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -558,34 +558,51 @@ unsafe_array: {
|
|||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
var a = "PASS";
|
||||||
[1, , 3][1],
|
Array.prototype[1] = a;
|
||||||
[1, 2, 3, a] + 1,
|
console.log([, ].length);
|
||||||
[1, 2, 3, 4] + 1,
|
console.log("" + [, , ]);
|
||||||
[1, 2, 3, a][0] + 1,
|
console.log([1, , 3][1]);
|
||||||
[1, 2, 3, 4][0] + 1,
|
console.log([1, 2, 3, a] + 1);
|
||||||
[1, 2, 3, 4][6 - 5] + 1,
|
console.log([1, 2, 3, 4] + 1);
|
||||||
[1, , 3, 4][6 - 5] + 1,
|
console.log([1, 2, 3, a][0] + 1);
|
||||||
[[1, 2], [3, 4]][0] + 1,
|
console.log([1, 2, 3, 4][0] + 1);
|
||||||
[[1, 2], [3, 4]][6 - 5][1] + 1,
|
console.log([1, 2, 3, 4][6 - 5] + 1);
|
||||||
[[1, 2], , [3, 4]][6 - 5][1] + 1
|
console.log([1, , 3, 4][6 - 5] + 1);
|
||||||
);
|
console.log([[1, 2], [3, 4]][0] + 1);
|
||||||
|
console.log([[1, 2], [3, 4]][6 - 5][1] + 1);
|
||||||
|
console.log([[1, 2], , [3, 4]][6 - 5][1] + 1);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(
|
var a = "PASS";
|
||||||
void 0,
|
Array.prototype[1] = a;
|
||||||
[1, 2, 3, a] + 1,
|
console.log([, ].length);
|
||||||
"1,2,3,41",
|
console.log("" + [, , ]);
|
||||||
[1, 2, 3, a][0] + 1,
|
console.log([1, , 3][1]);
|
||||||
2,
|
console.log([1, 2, 3, a] + 1);
|
||||||
3,
|
console.log("1,2,3,41");
|
||||||
NaN,
|
console.log([1, 2, 3, a][0] + 1);
|
||||||
"1,21",
|
console.log(2);
|
||||||
5,
|
console.log(3);
|
||||||
(void 0)[1] + 1
|
console.log([1, , 3, 4][1] + 1);
|
||||||
);
|
console.log("1,21");
|
||||||
|
console.log(5);
|
||||||
|
console.log([[1, 2], , [3, 4]][1][1] + 1);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
",PASS",
|
||||||
|
"PASS",
|
||||||
|
"1,2,3,PASS1",
|
||||||
|
"1,2,3,41",
|
||||||
|
"2",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"PASS1",
|
||||||
|
"1,21",
|
||||||
|
"5",
|
||||||
|
"A1",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_string: {
|
unsafe_string: {
|
||||||
@@ -1579,9 +1596,9 @@ issue_2968_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = "FAIL";
|
var c = "FAIL";
|
||||||
(function() {
|
(function() {
|
||||||
b = -(a = 42),
|
a = 42,
|
||||||
void ((a <<= 0) && (a[(c = "PASS", 0 >>> (b += 1))] = 0));
|
void ((a <<= 0) && (a[(c = "PASS", 0)] = 0));
|
||||||
var a, b;
|
var a;
|
||||||
})();
|
})();
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -2341,10 +2358,7 @@ issue_3878_1: {
|
|||||||
console.log(b ? "PASS" : "FAIL");
|
console.log(b ? "PASS" : "FAIL");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var b = function(a) {
|
console.log(true ? "PASS" : "FAIL");
|
||||||
return (a = 0) == (a && this > (a += 0));
|
|
||||||
}();
|
|
||||||
console.log(b ? "PASS" : "FAIL");
|
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
@@ -2412,9 +2426,9 @@ issue_3887: {
|
|||||||
expect: {
|
expect: {
|
||||||
(function(b) {
|
(function(b) {
|
||||||
try {
|
try {
|
||||||
b-- && console.log("PASS");
|
1, console.log("PASS");
|
||||||
} catch (a_2) {}
|
} catch (a_2) {}
|
||||||
})(1);
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
@@ -2435,12 +2449,11 @@ issue_3903: {
|
|||||||
console.log(d);
|
console.log(d);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "PASS";
|
|
||||||
function f(b, c) {
|
function f(b, c) {
|
||||||
return console, c;
|
return console, c;
|
||||||
}
|
}
|
||||||
var d = f(f(), a = a);
|
f(f(), "PASS");
|
||||||
console.log(d);
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
@@ -2478,10 +2491,345 @@ issue_3920: {
|
|||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = function(b) {
|
(function(b) {
|
||||||
return (b[b = 0] = 0) >= (b ? 0 : 1);
|
"foo"[0] = 0;
|
||||||
}("foo");
|
})();
|
||||||
console.log(a);
|
console.log(false);
|
||||||
}
|
}
|
||||||
expect_stdout: "false"
|
expect_stdout: "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inlined_increment_prefix: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
++a;
|
||||||
|
})();
|
||||||
|
console.log(a += 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
void ++a;
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
inlined_increment_postfix: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
a++;
|
||||||
|
})();
|
||||||
|
console.log(a += 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
void a++;
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
compound_assignment_to_property: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
1 + (0..p >>= 0) && console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1 + (0..p >>= 0),
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 42;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 42;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_postfix: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 41;
|
||||||
|
a++;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 41;
|
||||||
|
a++;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_prefix: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 43;
|
||||||
|
--a;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 43;
|
||||||
|
--a;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3933: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a && (b ^= 1) && console.log("PASS");
|
||||||
|
})(1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
1, 1, console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3935: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
return a++;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(NaN);
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3937: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 123;
|
||||||
|
(a++ + (b = a))[b] ? 0 ? a : b : 0 ? a : b;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 123;
|
||||||
|
(a++ + (b = a))[b], 0, b;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "124 124"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3944: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (function() {
|
||||||
|
var a = 0 == (b && b.p), b = console.log(a);
|
||||||
|
}());
|
||||||
|
f;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void function f() {
|
||||||
|
while (a = 0 == (a = void 0), console.log(a), void 0);
|
||||||
|
var a;
|
||||||
|
f;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3953: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
(a += 0 * (a = 0)) && console.log("PASS");
|
||||||
|
}
|
||||||
|
f(1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
(a += 0 * (a = 0)) && console.log("PASS");
|
||||||
|
}
|
||||||
|
f(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3988: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(b) {
|
||||||
|
return ("" + (b &= 0))[b && this];
|
||||||
|
}
|
||||||
|
var a = f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function(b) {
|
||||||
|
return ("" + (b &= 0))[b && this];
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
operator_in: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Object.prototype.PASS = 0;
|
||||||
|
console.log(0 in [ 1 ]);
|
||||||
|
console.log(0 in [ , ]);
|
||||||
|
console.log(0 / 0 in { NaN: 2 });
|
||||||
|
console.log("PASS" in { });
|
||||||
|
console.log("FAIL" in { });
|
||||||
|
console.log("toString" in { });
|
||||||
|
console.log("toString" in { toString: 3 });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Object.prototype.PASS = 0;
|
||||||
|
console.log(true);
|
||||||
|
console.log(0 in [ , ]);
|
||||||
|
console.log(true);
|
||||||
|
console.log("PASS" in { });
|
||||||
|
console.log("FAIL" in { });
|
||||||
|
console.log("toString" in { });
|
||||||
|
console.log(true);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"false",
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"false",
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3997: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return b[b += this] = b;
|
||||||
|
}(0);
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return b[b += this] = b;
|
||||||
|
}(0);
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect_stdout: "string"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2336,6 +2336,7 @@ issue_3274: {
|
|||||||
inline: true,
|
inline: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
loops: true,
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -4705,3 +4706,75 @@ issue_3911: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3929: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var abc = function f() {
|
||||||
|
(function() {
|
||||||
|
switch (f) {
|
||||||
|
default:
|
||||||
|
var abc = 0;
|
||||||
|
case 0:
|
||||||
|
abc.p;
|
||||||
|
}
|
||||||
|
console.log(typeof f);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
typeof abc && abc();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var abc = function f() {
|
||||||
|
(function() {
|
||||||
|
switch (f) {
|
||||||
|
default:
|
||||||
|
var abc = 0;
|
||||||
|
case 0:
|
||||||
|
abc.p;
|
||||||
|
}
|
||||||
|
console.log(typeof f);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
typeof abc && abc();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4006: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
(function(b, c) {
|
||||||
|
for (var k in console.log(c), 0)
|
||||||
|
return b += 0;
|
||||||
|
})(0, --a);
|
||||||
|
return a ? 0 : --a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(c) {
|
||||||
|
for (var k in console.log(c), 0)
|
||||||
|
return;
|
||||||
|
})(--a), a || --a;
|
||||||
|
}
|
||||||
|
expect_stdout: "-1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,20 @@ must_replace: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repeated_nodes: {
|
||||||
|
options = {
|
||||||
|
global_defs: {
|
||||||
|
"@N": "rand()",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(N, N);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(rand(), rand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keyword: {
|
keyword: {
|
||||||
options = {
|
options = {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
|
|||||||
@@ -972,3 +972,72 @@ issue_3871: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3945_1: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
o.p;
|
||||||
|
var o = {
|
||||||
|
q: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
o.p;
|
||||||
|
var o = {
|
||||||
|
q: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3945_2: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof o);
|
||||||
|
var o = {
|
||||||
|
p: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof o);
|
||||||
|
var o = {
|
||||||
|
p: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4023: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = function() {
|
||||||
|
return { p: 0 };
|
||||||
|
}();
|
||||||
|
return console.log("undefined" != typeof a);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0 !== {});
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2223,13 +2223,13 @@ issue_3523_rename_ie8: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 0, b, c = "FAIL";
|
var a = 0, b, c = "FAIL";
|
||||||
(function() {
|
(function() {
|
||||||
var c, n, t, o, a, r, f, i, u, e, h, l, v, y;
|
var c, n, t, o, a, r, e, f, i, u, h, l, v, y;
|
||||||
})();
|
})();
|
||||||
try {
|
try {
|
||||||
throw 0;
|
throw 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
(function() {
|
(function() {
|
||||||
(function n() {
|
(function e() {
|
||||||
c = "PASS";
|
c = "PASS";
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
@@ -2522,3 +2522,195 @@ issue_3918: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3999: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
(function f() {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
try {
|
||||||
|
f[0];
|
||||||
|
} catch (f) {
|
||||||
|
var f = 0;
|
||||||
|
console.log(i);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
})(typeof f);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function f() {
|
||||||
|
for (var o = 0; o < 2; o++)
|
||||||
|
try {
|
||||||
|
f[0];
|
||||||
|
} catch (f) {
|
||||||
|
var f = 0;
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
})(typeof f);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4001: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
ie8: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
function f() {
|
||||||
|
return a;
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
var c = f();
|
||||||
|
(function g() {
|
||||||
|
c[42];
|
||||||
|
f;
|
||||||
|
})();
|
||||||
|
(function a() {});
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
console.log((a = 42, void f()[42], void function a() {}));
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4015: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var n, a = 0, b;
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (b) {
|
||||||
|
(function g() {
|
||||||
|
(function b() {
|
||||||
|
a++;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var n, o = 0, c;
|
||||||
|
function t() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (c) {
|
||||||
|
(function n() {
|
||||||
|
(function c() {
|
||||||
|
o++;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t();
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4019: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function() {
|
||||||
|
try {
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (b) {}
|
||||||
|
}, a = (console.log(a.length), ++a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = function() {
|
||||||
|
try {
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (o) {}
|
||||||
|
}, o = (console.log(o.length), ++o);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4028: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
try {
|
||||||
|
A;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
var b = a += a;
|
||||||
|
console.log(typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
try {
|
||||||
|
A;
|
||||||
|
} catch (a) {}
|
||||||
|
}
|
||||||
|
var b = a += a;
|
||||||
|
console.log(typeof b);
|
||||||
|
}
|
||||||
|
expect_stdout: "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737: {
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
a();
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
a();
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|||||||
@@ -808,9 +808,9 @@ issue_3795: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "FAIL", d = function() {
|
var a = "FAIL", d = function() {
|
||||||
if (a = 42, d) return -1;
|
if (void 0) return -1;
|
||||||
a = "PASS";
|
a = "PASS";
|
||||||
}();
|
}(a = 42);
|
||||||
console.log(a, d);
|
console.log(a, d);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS undefined"
|
expect_stdout: "PASS undefined"
|
||||||
|
|||||||
@@ -306,8 +306,7 @@ issue_2298: {
|
|||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
(function() {
|
(function() {
|
||||||
var a = undefined;
|
0;
|
||||||
var undefined = a++;
|
|
||||||
try {
|
try {
|
||||||
!function() {
|
!function() {
|
||||||
(void 0)[1] = "foo";
|
(void 0)[1] = "foo";
|
||||||
|
|||||||
@@ -1046,16 +1046,22 @@ array_hole: {
|
|||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
Array.prototype[2] = "PASS";
|
||||||
[ 1, 2, , 3][1],
|
console.log([ 1, 2, , 3 ][1]);
|
||||||
[ 1, 2, , 3][2],
|
console.log([ 1, 2, , 3 ][2]);
|
||||||
[ 1, 2, , 3][3]
|
console.log([ 1, 2, , 3 ][3]);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(2, void 0, 3);
|
Array.prototype[2] = "PASS";
|
||||||
|
console.log(2);
|
||||||
|
console.log([ , , , ][2]);
|
||||||
|
console.log(3);
|
||||||
}
|
}
|
||||||
expect_stdout: "2 undefined 3"
|
expect_stdout: [
|
||||||
|
"2",
|
||||||
|
"PASS",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
new_this: {
|
new_this: {
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ relational: {
|
|||||||
side_effects :true,
|
side_effects :true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
foo() in foo();
|
foo() in new foo();
|
||||||
foo() instanceof bar();
|
foo() instanceof bar();
|
||||||
foo() < "bar";
|
foo() < "bar";
|
||||||
bar() > foo();
|
bar() > foo();
|
||||||
|
|||||||
@@ -905,7 +905,7 @@ use_before_var: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(){
|
function f(){
|
||||||
console.log(t);
|
console.log(void 0);
|
||||||
var t = 1;
|
var t = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -981,12 +981,12 @@ inner_var_for_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
x(1, b, d);
|
x(1, void 0, d);
|
||||||
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
|
for (var b = 2, c = 3; x(1, 2, 3, d); x(1, 2, 3, d)) {
|
||||||
var d = 4, e = 5;
|
var d = 4, e = 5;
|
||||||
x(1, b, 3, d, e);
|
x(1, 2, 3, d, e);
|
||||||
}
|
}
|
||||||
x(1, b, 3, d, e);
|
x(1, 2, 3, d, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1520,10 +1520,7 @@ func_inline: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
console.log(1 + h());
|
console.log(1 + (void 0)());
|
||||||
var h = function() {
|
|
||||||
return 2;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2372,8 +2369,7 @@ delay_def: {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
function g() {
|
function g() {
|
||||||
return a;
|
return;
|
||||||
var a = 1;
|
|
||||||
}
|
}
|
||||||
console.log(f(), g());
|
console.log(f(), g());
|
||||||
}
|
}
|
||||||
@@ -2395,7 +2391,7 @@ delay_def_lhs: {
|
|||||||
expect: {
|
expect: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
long_name++;
|
long_name++;
|
||||||
return long_name;
|
return NaN;
|
||||||
var long_name;
|
var long_name;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
@@ -2651,11 +2647,9 @@ var_assign_5: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
var a;
|
|
||||||
!function(b) {
|
!function(b) {
|
||||||
a = 2,
|
console.log(2, void 0);
|
||||||
console.log(a, b);
|
}();
|
||||||
}(a);
|
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "2 undefined"
|
expect_stdout: "2 undefined"
|
||||||
@@ -2676,8 +2670,8 @@ var_assign_6: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
var a = function(){}(a = 1);
|
(function(){}());
|
||||||
console.log(a);
|
console.log(void 0);
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
@@ -2724,8 +2718,8 @@ issue_1814_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
!function(a) {
|
!function(a) {
|
||||||
console.log(a++, 42);
|
console.log(0, 42);
|
||||||
}(0);
|
}();
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "0 42"
|
expect_stdout: "0 42"
|
||||||
@@ -2751,8 +2745,8 @@ issue_1814_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
!function(a) {
|
!function(a) {
|
||||||
console.log("321", a++);
|
console.log("321", 0);
|
||||||
}(0);
|
}();
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "321 0"
|
expect_stdout: "321 0"
|
||||||
@@ -4725,7 +4719,7 @@ escape_conditional: {
|
|||||||
function bar() {}
|
function bar() {}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
else
|
else
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
@@ -4763,7 +4757,7 @@ escape_sequence: {
|
|||||||
function bar() {}
|
function bar() {}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
else
|
else
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
@@ -4808,7 +4802,7 @@ escape_throw: {
|
|||||||
function foo() {}
|
function foo() {}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
else
|
else
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
@@ -4845,7 +4839,7 @@ escape_local_conditional: {
|
|||||||
}
|
}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
else
|
else
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
@@ -4882,7 +4876,7 @@ escape_local_sequence: {
|
|||||||
}
|
}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
else
|
else
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
@@ -4926,7 +4920,7 @@ escape_local_throw: {
|
|||||||
}
|
}
|
||||||
(function() {
|
(function() {
|
||||||
var thing = baz();
|
var thing = baz();
|
||||||
if (thing !== (thing = baz()))
|
if (thing !== baz())
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
else
|
else
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
@@ -4980,11 +4974,7 @@ inverted_var: {
|
|||||||
console.log(1, 2, 3, 4, 5, function c() {
|
console.log(1, 2, 3, 4, 5, function c() {
|
||||||
c = 6;
|
c = 6;
|
||||||
return c;
|
return c;
|
||||||
}(), 7, function() {
|
}(), 7, 8);
|
||||||
c = 8;
|
|
||||||
return c;
|
|
||||||
var c = "foo";
|
|
||||||
}());
|
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -5180,9 +5170,7 @@ defun_var_3: {
|
|||||||
var a = 42, b;
|
var a = 42, b;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a() {}
|
console.log("function", "function");
|
||||||
console.log(typeof a, "function");
|
|
||||||
var a = 42;
|
|
||||||
}
|
}
|
||||||
expect_stdout: "function function"
|
expect_stdout: "function function"
|
||||||
}
|
}
|
||||||
@@ -7122,3 +7110,299 @@ issue_3922: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3949_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
var a = void (a = 0, g);
|
||||||
|
function g() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a) {
|
||||||
|
var a = void (a = 0, g);
|
||||||
|
function g() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
var a = void (a = 0, g);
|
||||||
|
function g() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
a = void (a = 0, g);
|
||||||
|
function g() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
for (var a, i = 3; 0 <= --i; ) {
|
||||||
|
a = f;
|
||||||
|
console.log(a === b);
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
for (var a, i = 3; 0 <= --i; ) {
|
||||||
|
a = f;
|
||||||
|
console.log(a === b);
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"false",
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
for (var a, i = 3; 0 <= --i; ) {
|
||||||
|
a = f;
|
||||||
|
console.log(a === b);
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
for (var a, i = 3; 0 <= --i; ) {
|
||||||
|
a = f;
|
||||||
|
console.log(a === b);
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"false",
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
local_assignment_lambda: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
function f() {
|
||||||
|
a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
f(),
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
local_assignment_loop: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
do {
|
||||||
|
a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
} while (!console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
do {
|
||||||
|
console.log("PASS");
|
||||||
|
} while (!console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3957_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
while (a += console.log(a = 0))
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
while (a += console.log(a = 0))
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3957_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
while (a += console.log(a = 0))
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
while (a += console.log(a = 0))
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3958: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
(function(c) {
|
||||||
|
console.log(c[0] = 1);
|
||||||
|
})(a = b);
|
||||||
|
--a;
|
||||||
|
})([]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
(function(c) {
|
||||||
|
console.log(c[0] = 1);
|
||||||
|
})(a = []);
|
||||||
|
--a;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3974: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
var a = 0 in 0;
|
||||||
|
0 && a;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
var a = 0 in 0;
|
||||||
|
0 && a;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4030: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
{
|
||||||
|
delete (a = "PASS");
|
||||||
|
A = "PASS";
|
||||||
|
}
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,9 +97,8 @@ issue_2233_2: {
|
|||||||
var RegExp;
|
var RegExp;
|
||||||
UndeclaredGlobal;
|
UndeclaredGlobal;
|
||||||
function foo() {
|
function foo() {
|
||||||
var Number;
|
|
||||||
AnotherUndeclaredGlobal;
|
AnotherUndeclaredGlobal;
|
||||||
Number.isNaN;
|
(void 0).isNaN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,3 +274,120 @@ drop_value: {
|
|||||||
foo(), bar();
|
foo(), bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator_in: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
"foo" in true;
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
0 in true;
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3983_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f() {
|
||||||
|
g && g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
function g() {
|
||||||
|
0 ? a : 0;
|
||||||
|
}
|
||||||
|
var b = a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
g();
|
||||||
|
function g() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3983_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f() {
|
||||||
|
g && g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
function g() {
|
||||||
|
0 ? a : 0;
|
||||||
|
}
|
||||||
|
var b = a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4008: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f && f(a && a[a]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f(a[a]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
5
test/input/reduce/diff_error.js
Normal file
5
test/input/reduce/diff_error.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
(function f(a) {
|
||||||
|
do {
|
||||||
|
console.log(f.length);
|
||||||
|
} while (console.log(f += 0));
|
||||||
|
})();
|
||||||
19
test/input/reduce/diff_error.reduced.js
Normal file
19
test/input/reduce/diff_error.reduced.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// (beautified)
|
||||||
|
(function f(a) {
|
||||||
|
do {
|
||||||
|
console.log(f.length);
|
||||||
|
} while (console.log(f += 0));
|
||||||
|
})();
|
||||||
|
// output: 1
|
||||||
|
// function(){}0
|
||||||
|
//
|
||||||
|
// minify: 0
|
||||||
|
// function(){}0
|
||||||
|
//
|
||||||
|
// options: {
|
||||||
|
// "compress": {
|
||||||
|
// "keep_fargs": false,
|
||||||
|
// "unsafe": true
|
||||||
|
// },
|
||||||
|
// "mangle": false
|
||||||
|
// }
|
||||||
@@ -249,7 +249,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with `--output-opts`", function(done) {
|
it("Should work with `--output-opts`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -O';
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -O ascii_only';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
||||||
@@ -257,7 +257,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail when both --beautify & --output-opts are specified", function(done) {
|
it("Should fail when both --beautify & --output-opts are specified", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js -bO";
|
var command = uglifyjscmd + " test/input/issue-520/input.js -bO ascii_only";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: --beautify cannot be used with --output-opts\n");
|
assert.strictEqual(stderr, "ERROR: --beautify cannot be used with --output-opts\n");
|
||||||
@@ -717,7 +717,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json";
|
var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json";
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,a:2};return a.prop+a.a}\n');
|
assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,t:2};return a.prop+a.t}\n');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -486,4 +486,19 @@ describe("operator", function() {
|
|||||||
assert.strictEqual(UglifyJS.parse(exp[0]).print_to_string(), exp[1] + ";");
|
assert.strictEqual(UglifyJS.parse(exp[0]).print_to_string(), exp[1] + ";");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should preserve space between /regex/ and `in`", function() {
|
||||||
|
[
|
||||||
|
"/regex/ in {}",
|
||||||
|
"/regex/g in {}",
|
||||||
|
"0 + /regex/ in {}",
|
||||||
|
"0 + /regex/g in {}",
|
||||||
|
].forEach(function(exp) {
|
||||||
|
var code = UglifyJS.parse(exp).print_to_string();
|
||||||
|
try {
|
||||||
|
assert.strictEqual(UglifyJS.parse(code).print_to_string(), code);
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("Failed to reparse: " + exp + "\n" + ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -296,4 +296,18 @@ describe("test/reduce.js", function() {
|
|||||||
"// }",
|
"// }",
|
||||||
]).join("\n"));
|
]).join("\n"));
|
||||||
});
|
});
|
||||||
|
it("Should handle corner cases when intermediate case differs only in Error.message", function() {
|
||||||
|
if (semver.satisfies(process.version, "<=0.10")) return;
|
||||||
|
var result = reduce_test(read("test/input/reduce/diff_error.js"), {
|
||||||
|
compress: {
|
||||||
|
keep_fargs: false,
|
||||||
|
unsafe: true,
|
||||||
|
},
|
||||||
|
mangle: false,
|
||||||
|
}, {
|
||||||
|
verbose: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, read("test/input/reduce/diff_error.reduced.js"));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -438,7 +438,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
var code = testcase_ast.print_to_string();
|
var code = testcase_ast.print_to_string();
|
||||||
if (diff = test_for_diff(code, minify_options, result_cache, max_timeout)) {
|
var diff = test_for_diff(code, minify_options, result_cache, max_timeout);
|
||||||
|
if (diff && !diff.timed_out && !diff.error) {
|
||||||
testcase = code;
|
testcase = code;
|
||||||
differs = diff;
|
differs = diff;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ var VALUES = [
|
|||||||
"this",
|
"this",
|
||||||
];
|
];
|
||||||
|
|
||||||
var BINARY_OPS_NO_COMMA = [
|
var BINARY_OPS = [
|
||||||
" + ", // spaces needed to disambiguate with ++ cases (could otherwise cause syntax errors)
|
" + ", // spaces needed to disambiguate with ++ cases (could otherwise cause syntax errors)
|
||||||
" - ",
|
" - ",
|
||||||
"/",
|
"/",
|
||||||
@@ -190,9 +190,15 @@ var BINARY_OPS_NO_COMMA = [
|
|||||||
"%",
|
"%",
|
||||||
"&&",
|
"&&",
|
||||||
"||",
|
"||",
|
||||||
"^" ];
|
"^",
|
||||||
|
",",
|
||||||
var BINARY_OPS = [","].concat(BINARY_OPS_NO_COMMA);
|
];
|
||||||
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
|
BINARY_OPS.push(" in ");
|
||||||
|
|
||||||
var ASSIGNMENTS = [
|
var ASSIGNMENTS = [
|
||||||
"=",
|
"=",
|
||||||
@@ -762,6 +768,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
return createArrayLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
return createArrayLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
||||||
case p++:
|
case p++:
|
||||||
return createObjectLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
return createObjectLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
||||||
|
case p++:
|
||||||
|
return createValue() + " in " + createArrayLiteral(recurmax, stmtDepth, canThrow);
|
||||||
|
case p++:
|
||||||
|
return createValue() + " in " + createObjectLiteral(recurmax, stmtDepth, canThrow);
|
||||||
case p++:
|
case p++:
|
||||||
var name = getVarName();
|
var name = getVarName();
|
||||||
var s = name + "[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
var s = name + "[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
||||||
@@ -879,7 +889,7 @@ function createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
}
|
}
|
||||||
function _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
function _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
||||||
return "(" + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow)
|
return "(" + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow)
|
||||||
+ createBinaryOp(noComma) + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
+ createBinaryOp(noComma, canThrow) + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
||||||
}
|
}
|
||||||
function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
||||||
// intentionally generate more hardcore ops
|
// intentionally generate more hardcore ops
|
||||||
@@ -929,9 +939,12 @@ function createValue() {
|
|||||||
return VALUES[rng(VALUES.length)];
|
return VALUES[rng(VALUES.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBinaryOp(noComma) {
|
function createBinaryOp(noComma, canThrow) {
|
||||||
if (noComma) return BINARY_OPS_NO_COMMA[rng(BINARY_OPS_NO_COMMA.length)];
|
var op;
|
||||||
return BINARY_OPS[rng(BINARY_OPS.length)];
|
do {
|
||||||
|
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
||||||
|
} while (noComma && op == "," || !canThrow && op == " in ");
|
||||||
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAssignment() {
|
function createAssignment() {
|
||||||
@@ -1124,18 +1137,6 @@ function log(options) {
|
|||||||
errorln(original_result);
|
errorln(original_result);
|
||||||
errorln("uglified result:");
|
errorln("uglified result:");
|
||||||
errorln(uglify_result);
|
errorln(uglify_result);
|
||||||
errorln("//-------------------------------------------------------------");
|
|
||||||
var reduced = reduce_test(original_code, JSON.parse(options), {
|
|
||||||
verbose: false,
|
|
||||||
}).code;
|
|
||||||
if (reduced) {
|
|
||||||
errorln();
|
|
||||||
errorln("// reduced test case (output will differ)");
|
|
||||||
errorln();
|
|
||||||
errorln(reduced);
|
|
||||||
errorln();
|
|
||||||
errorln("//-------------------------------------------------------------");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
errorln("// !!! uglify failed !!!");
|
errorln("// !!! uglify failed !!!");
|
||||||
errorln(uglify_code);
|
errorln(uglify_code);
|
||||||
@@ -1146,6 +1147,20 @@ function log(options) {
|
|||||||
errorln(original_result);
|
errorln(original_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errorln("//-------------------------------------------------------------");
|
||||||
|
var reduce_options = JSON.parse(options);
|
||||||
|
reduce_options.validate = true;
|
||||||
|
var reduced = reduce_test(original_code, reduce_options, {
|
||||||
|
verbose: false,
|
||||||
|
}).code;
|
||||||
|
if (reduced) {
|
||||||
|
errorln();
|
||||||
|
errorln("// reduced test case (output will differ)");
|
||||||
|
errorln();
|
||||||
|
errorln(reduced);
|
||||||
|
errorln();
|
||||||
|
errorln("//-------------------------------------------------------------");
|
||||||
|
}
|
||||||
errorln("minify(options):");
|
errorln("minify(options):");
|
||||||
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
||||||
errorln();
|
errorln();
|
||||||
@@ -1159,6 +1174,10 @@ function log(options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sort_globals(code) {
|
||||||
|
return "var " + sandbox.run_code("throw Object.keys(this).sort();" + code).join(",") + ";" + code;
|
||||||
|
}
|
||||||
|
|
||||||
function fuzzy_match(original, uglified) {
|
function fuzzy_match(original, uglified) {
|
||||||
uglified = uglified.split(" ");
|
uglified = uglified.split(" ");
|
||||||
var i = uglified.length;
|
var i = uglified.length;
|
||||||
@@ -1173,34 +1192,63 @@ function fuzzy_match(original, uglified) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function skip_infinite_recursion(orig, toplevel) {
|
function patch_try_catch(orig, toplevel) {
|
||||||
var code = orig;
|
var stack = [ {
|
||||||
var tries = [];
|
code: orig,
|
||||||
var offset = 0;
|
index: 0,
|
||||||
|
offset: 0,
|
||||||
|
tries: [],
|
||||||
|
} ];
|
||||||
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)]+)\)|}\s*finally)\s*(?={)/g;
|
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)]+)\)|}\s*finally)\s*(?={)/g;
|
||||||
var match;
|
while (stack.length) {
|
||||||
while (match = re.exec(code)) {
|
var code = stack[0].code;
|
||||||
if (/}\s*finally\s*$/.test(match[0])) {
|
var offset = stack[0].offset;
|
||||||
tries.shift();
|
var tries = stack[0].tries;
|
||||||
continue;
|
var match;
|
||||||
}
|
re.lastIndex = stack.shift().index;
|
||||||
var index = match.index + match[0].length + 1;
|
while (match = re.exec(code)) {
|
||||||
if (/(?:^|[\s{}):;])try\s*$/.test(match[0])) {
|
var index = match.index + match[0].length + 1;
|
||||||
tries.unshift({ try: index - offset });
|
if (/(?:^|[\s{}):;])try\s*$/.test(match[0])) {
|
||||||
continue;
|
tries.unshift({ try: index - offset });
|
||||||
}
|
continue;
|
||||||
while (tries.length && tries[0].catch) tries.shift();
|
}
|
||||||
tries[0].catch = index;
|
var insert;
|
||||||
var insert = "throw " + match[1] + ".ufuzz_skip || (" + match[1] + ".ufuzz_skip = " + tries[0].try + "), " + match[1] + ";";
|
if (/}\s*finally\s*$/.test(match[0])) {
|
||||||
var new_code = code.slice(0, index) + insert + code.slice(index);
|
tries.shift();
|
||||||
var result = sandbox.run_code(new_code, toplevel);
|
insert = 'if (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;';
|
||||||
if (typeof result != "object" || typeof result.name != "string" || typeof result.message != "string") {
|
} else {
|
||||||
offset += insert.length;
|
while (tries.length && tries[0].catch) tries.shift();
|
||||||
code = new_code;
|
tries[0].catch = index - offset;
|
||||||
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") {
|
insert = [
|
||||||
index = result.ufuzz_skip;
|
"if (!" + match[1] + ".ufuzz_var) {",
|
||||||
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
|
match[1] + '.ufuzz_var = "' + match[1] + '";',
|
||||||
|
match[1] + ".ufuzz_try = " + tries[0].try + ";",
|
||||||
|
match[1] + ".ufuzz_catch = " + tries[0].catch + ";",
|
||||||
|
"UFUZZ_ERROR = " + match[1] + ";",
|
||||||
|
"}",
|
||||||
|
"throw " + match[1] + ";",
|
||||||
|
].join("\n");
|
||||||
|
}
|
||||||
|
var new_code = code.slice(0, index) + insert + code.slice(index);
|
||||||
|
var result = sandbox.run_code(new_code, toplevel);
|
||||||
|
if (typeof result != "object" || typeof result.name != "string" || typeof result.message != "string") {
|
||||||
|
if (!stack.filled && match[1]) stack.push({
|
||||||
|
code: code,
|
||||||
|
index: index && index - 1,
|
||||||
|
offset: offset,
|
||||||
|
tries: JSON.parse(JSON.stringify(tries)),
|
||||||
|
});
|
||||||
|
offset += insert.length;
|
||||||
|
code = new_code;
|
||||||
|
} else if (result.name == "TypeError" && /'in'/.test(result.message)) {
|
||||||
|
index = result.ufuzz_catch;
|
||||||
|
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
|
||||||
|
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") {
|
||||||
|
index = result.ufuzz_try;
|
||||||
|
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
stack.filled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1209,14 +1257,6 @@ var fallback_options = [ JSON.stringify({
|
|||||||
mangle: false
|
mangle: false
|
||||||
}) ];
|
}) ];
|
||||||
var minify_options = require("./options.json").map(JSON.stringify);
|
var minify_options = require("./options.json").map(JSON.stringify);
|
||||||
var sort_globals = [
|
|
||||||
"Object.keys(this).sort().forEach(function(name) {",
|
|
||||||
" var value = this[name];",
|
|
||||||
" delete this[name];",
|
|
||||||
" this[name] = value;",
|
|
||||||
"});",
|
|
||||||
"",
|
|
||||||
].join("\n");
|
|
||||||
var original_code, original_result, errored;
|
var original_code, original_result, errored;
|
||||||
var uglify_code, uglify_result, ok;
|
var uglify_code, uglify_result, ok;
|
||||||
for (var round = 1; round <= num_iterations; round++) {
|
for (var round = 1; round <= num_iterations; round++) {
|
||||||
@@ -1238,7 +1278,7 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
ok = sandbox.same_stdout(original_result, uglify_result);
|
ok = sandbox.same_stdout(original_result, uglify_result);
|
||||||
// ignore declaration order of global variables
|
// ignore declaration order of global variables
|
||||||
if (!ok && !toplevel) {
|
if (!ok && !toplevel) {
|
||||||
ok = sandbox.same_stdout(sandbox.run_code(sort_globals + original_code), sandbox.run_code(sort_globals + uglify_code));
|
ok = sandbox.same_stdout(sandbox.run_code(sort_globals(original_code)), sandbox.run_code(sort_globals(uglify_code)));
|
||||||
}
|
}
|
||||||
// ignore numerical imprecision caused by `unsafe_math`
|
// ignore numerical imprecision caused by `unsafe_math`
|
||||||
if (!ok && typeof uglify_result == "string" && o.compress && o.compress.unsafe_math) {
|
if (!ok && typeof uglify_result == "string" && o.compress && o.compress.unsafe_math) {
|
||||||
@@ -1248,10 +1288,11 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
ok = sandbox.same_stdout(fuzzy_result, uglify_result);
|
ok = sandbox.same_stdout(fuzzy_result, uglify_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ignore difference in error message caused by `in`
|
||||||
// ignore difference in depth of termination caused by infinite recursion
|
// ignore difference in depth of termination caused by infinite recursion
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
var orig_skipped = skip_infinite_recursion(original_code, toplevel);
|
var orig_skipped = patch_try_catch(original_code, toplevel);
|
||||||
var uglify_skipped = skip_infinite_recursion(uglify_code, toplevel);
|
var uglify_skipped = patch_try_catch(uglify_code, toplevel);
|
||||||
if (orig_skipped && uglify_skipped) {
|
if (orig_skipped && uglify_skipped) {
|
||||||
ok = sandbox.same_stdout(sandbox.run_code(orig_skipped, toplevel), sandbox.run_code(uglify_skipped, toplevel));
|
ok = sandbox.same_stdout(sandbox.run_code(orig_skipped, toplevel), sandbox.run_code(uglify_skipped, toplevel));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user