Compare commits
250 Commits
v3.9.1
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f751e64d49 | ||
|
|
60c56a24b9 | ||
|
|
01f23cf5a1 | ||
|
|
99fb3e8f0d | ||
|
|
756c9aa7dc | ||
|
|
07d6bfd707 | ||
|
|
81243c4e71 | ||
|
|
cd6e849555 | ||
|
|
91de285166 | ||
|
|
4d8f289eb0 | ||
|
|
945ba64160 | ||
|
|
c699200398 | ||
|
|
daf44f2b21 | ||
|
|
fcd90db30d | ||
|
|
e2888bdc43 | ||
|
|
fb50b7b627 | ||
|
|
9d59c693c2 | ||
|
|
6ddb5bd94d | ||
|
|
eda49605c5 | ||
|
|
1e9ef17e32 | ||
|
|
222100ea4c | ||
|
|
93db48a317 | ||
|
|
2944e3df7d | ||
|
|
e0ae8da089 | ||
|
|
81f1311b24 | ||
|
|
2433bb4e52 | ||
|
|
3fac29a017 | ||
|
|
b4c18f6b83 | ||
|
|
73d6438773 | ||
|
|
5c6316a37d | ||
|
|
278577f3cb | ||
|
|
0d8597e904 | ||
|
|
c20bb99a62 | ||
|
|
2377171200 | ||
|
|
603d92effc | ||
|
|
17f0cc359f | ||
|
|
35bae3fcd0 | ||
|
|
4614b5b46e | ||
|
|
2f93058c6e | ||
|
|
a729c43e87 | ||
|
|
66e9039350 | ||
|
|
d717bf9ce8 | ||
|
|
5dea52266b | ||
|
|
fccefbeaca | ||
|
|
1e2b0aaa04 | ||
|
|
6a54de79b5 | ||
|
|
9e2290b29c | ||
|
|
97d0fc271d | ||
|
|
7906033e82 | ||
|
|
4bf21ce5c1 | ||
|
|
44d6b47bdc | ||
|
|
129e449c8e | ||
|
|
75c3c8963f | ||
|
|
d26b7522d9 | ||
|
|
2fd86d3cb0 | ||
|
|
8f7ab602e2 | ||
|
|
1dd339f95e | ||
|
|
c7063c1f38 | ||
|
|
f4a12b34f2 | ||
|
|
5d5c7934a5 | ||
|
|
8f4b45f4f8 | ||
|
|
952e2656eb | ||
|
|
240383a314 | ||
|
|
250b782b1e | ||
|
|
3c2b3aeddb | ||
|
|
aa605495f8 | ||
|
|
33a26d456b | ||
|
|
49d9ac1c43 | ||
|
|
c8e61448cb | ||
|
|
f704e9b65c | ||
|
|
0b77d861a8 | ||
|
|
e27dab7e7c | ||
|
|
80f3ad3ce0 | ||
|
|
22f7af205d | ||
|
|
8a7a4749c7 | ||
|
|
514fc68f4f | ||
|
|
478aaab469 | ||
|
|
ab217539e9 | ||
|
|
a942dc07c4 | ||
|
|
a0eaff750d | ||
|
|
57777b6cfa | ||
|
|
8d205f7f39 | ||
|
|
bc9bfd15a2 | ||
|
|
9fc1c4b3b5 | ||
|
|
c59bf5e8d8 | ||
|
|
d2d3a6e065 | ||
|
|
7755733716 | ||
|
|
b3a987b0df | ||
|
|
88a338f29e | ||
|
|
07734b000a | ||
|
|
85c1cba760 | ||
|
|
4bd31607f6 | ||
|
|
4728bc73ad | ||
|
|
52ce9a333c | ||
|
|
abbeb266b5 | ||
|
|
b11c5151bc | ||
|
|
962b1f3d40 | ||
|
|
3ee46e91e8 | ||
|
|
ee26e7f11b | ||
|
|
937f534392 | ||
|
|
1b2c02c944 | ||
|
|
0aa526e72c | ||
|
|
c2112d5886 | ||
|
|
5f6825f9ec | ||
|
|
7e80a979a7 | ||
|
|
b7bb706150 | ||
|
|
32c2cc33bb | ||
|
|
947b8750e8 | ||
|
|
88f6ff38d1 | ||
|
|
4198095a9c | ||
|
|
13ed445607 | ||
|
|
1db50c3b16 | ||
|
|
7f6b5d662b | ||
|
|
1c15d0db45 | ||
|
|
67461666dc | ||
|
|
45d81f881b | ||
|
|
8c7d23dfb1 | ||
|
|
7fa0dbdeb9 | ||
|
|
c644c1292d | ||
|
|
d224d71b8d | ||
|
|
27d3669800 | ||
|
|
110a1ac885 | ||
|
|
3f8fc3a316 | ||
|
|
88384cf351 | ||
|
|
72a9d799b6 | ||
|
|
766fafda8b | ||
|
|
842ac27efb | ||
|
|
0af42d1831 | ||
|
|
ff7f6139ba | ||
|
|
0db7caf13b | ||
|
|
d9bc6f303c | ||
|
|
6fd9b338dd | ||
|
|
d8d4e71b9e | ||
|
|
fb2f8d1a51 | ||
|
|
54a783ba84 | ||
|
|
63c432f4fa | ||
|
|
07785d0003 | ||
|
|
6eaeb19a4a | ||
|
|
2246c79318 | ||
|
|
dda58244b6 | ||
|
|
ca04508cd1 | ||
|
|
6b03b800b3 | ||
|
|
f9cab7ad61 | ||
|
|
0a3d780327 | ||
|
|
b0555a123a | ||
|
|
fa29344781 | ||
|
|
dcfc514c38 | ||
|
|
8ad8d7b717 | ||
|
|
0357e5923f | ||
|
|
f63803e3e3 | ||
|
|
63be1f3a4d | ||
|
|
e36e07fa77 | ||
|
|
d1b4f61f93 | ||
|
|
5b893c8ec3 | ||
|
|
8571a08a93 | ||
|
|
68cc14f846 | ||
|
|
f94497d1d6 | ||
|
|
eaf3911c31 | ||
|
|
91cdb93e57 | ||
|
|
634f231b78 | ||
|
|
6702cae918 | ||
|
|
6d2f77c180 | ||
|
|
accca2445f | ||
|
|
0bc4f6edb4 | ||
|
|
ce84a706a3 | ||
|
|
86b5248837 | ||
|
|
59e1601fb8 | ||
|
|
d35a9e7839 | ||
|
|
0465bd270d | ||
|
|
6780d0906c | ||
|
|
0b303379c0 | ||
|
|
d7ec2ecc12 | ||
|
|
2827fa8699 | ||
|
|
c80ec625ec | ||
|
|
5e78f20f1c | ||
|
|
1f75232062 | ||
|
|
028ff64e9a | ||
|
|
7a8cffd631 | ||
|
|
5b553aafe2 | ||
|
|
084437bc6d | ||
|
|
1cd9a2df9a | ||
|
|
7f3dbb6df7 | ||
|
|
e4d73d8b7c | ||
|
|
8220dbbea0 | ||
|
|
59e999597e | ||
|
|
cbcb3ac44e | ||
|
|
f07ab4666f | ||
|
|
a800356ad0 | ||
|
|
e076abdbf2 | ||
|
|
425613b0d2 | ||
|
|
69da8e53e0 | ||
|
|
bb6b3a773a | ||
|
|
364d20f8fb | ||
|
|
392ac4ff31 | ||
|
|
9ffed2bea6 | ||
|
|
5f7cb6939c | ||
|
|
64e7a00399 | ||
|
|
c99eaae360 | ||
|
|
34213ea2f8 | ||
|
|
da8c428a07 | ||
|
|
0d8dea9538 | ||
|
|
2babe737e0 | ||
|
|
2cce61c564 | ||
|
|
246ec416c0 | ||
|
|
6be9c752d5 | ||
|
|
76ed083e47 | ||
|
|
b31918bbf0 | ||
|
|
b14496c742 | ||
|
|
991fa99655 | ||
|
|
3d7f73114d | ||
|
|
dde9e293df | ||
|
|
34685a6f55 | ||
|
|
9812c826e0 | ||
|
|
2fac2bbfe4 | ||
|
|
242c61be94 | ||
|
|
e1cb1a0e3c | ||
|
|
af22b9c657 | ||
|
|
adee5023c0 | ||
|
|
7ee8f3512e | ||
|
|
dc5db9b6ca | ||
|
|
079aaa0d48 | ||
|
|
d4f17f29ae | ||
|
|
e99bc914ca | ||
|
|
025d34bfa2 | ||
|
|
c44c2d6c21 | ||
|
|
824ecfb8a2 | ||
|
|
ceebc466b9 | ||
|
|
35b31bdd4e | ||
|
|
c8b82583d2 | ||
|
|
9f9179ba1a | ||
|
|
872231a0ca | ||
|
|
36420183fd | ||
|
|
a8f8aa518b | ||
|
|
4c12cccff9 | ||
|
|
dcce4e5c66 | ||
|
|
56c0b834d6 | ||
|
|
6f864402d3 | ||
|
|
8909e9e1cb | ||
|
|
e80ed38772 | ||
|
|
9863f0efa3 | ||
|
|
e8664e63ef | ||
|
|
ddd30eeaaa | ||
|
|
a68953c491 | ||
|
|
fa5c4f2d03 | ||
|
|
9d7d365c2b | ||
|
|
ad344c5be3 | ||
|
|
96b89e34a3 | ||
|
|
4644becb9b | ||
|
|
f7460166dd | ||
|
|
32f76f7ff8 |
19
.github/ISSUE_TEMPLATE.md
vendored
19
.github/ISSUE_TEMPLATE.md
vendored
@@ -2,24 +2,19 @@
|
||||
|
||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||
|
||||
**ES5 or ES6+ input?**
|
||||
|
||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||
|
||||
**Uglify version (`uglifyjs -V`)**
|
||||
|
||||
**JavaScript input**
|
||||
|
||||
<!--
|
||||
A complete parsable JS program exhibiting the issue with
|
||||
UglifyJS alone - without third party tools or libraries.
|
||||
Ideally the input should be as small as possible.
|
||||
Post a link to a gist if necessary.
|
||||
|
||||
Issues without a reproducible test case will be closed.
|
||||
-->
|
||||
**JavaScript input** <!-- ideally as small as possible -->
|
||||
|
||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||
|
||||
**JavaScript output or error produced.**
|
||||
|
||||
<!--
|
||||
Note: `uglify-js` only supports JavaScript.
|
||||
Those wishing to minify ES6+ should transpile first.
|
||||
Note: `uglify-js` only supports ES5.
|
||||
Those wishing to minify ES6 should use `uglify-es`.
|
||||
-->
|
||||
|
||||
43
.github/workflows/ci.yml
vendored
43
.github/workflows/ci.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: CI
|
||||
on: [ push, pull_request ]
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ "0.8", "0.10", "0.12", "4", "6", "8", "10", "12", latest ]
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||
exclude:
|
||||
- node: "0.8"
|
||||
script: release/jetstream
|
||||
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
TYPE: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: tmp
|
||||
key: tmp ${{ matrix.script }}
|
||||
- name: Perform tests
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
||||
cd ~/.nvs
|
||||
git clean -xdf
|
||||
cd -
|
||||
done
|
||||
. ~/.nvs/nvs.sh --version
|
||||
nvs use $NODE
|
||||
node --version
|
||||
npm config set audit false
|
||||
npm config set optional false
|
||||
npm config set save false
|
||||
npm config set strict-ssl false
|
||||
npm config set update-notifier false
|
||||
npm --version
|
||||
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||
node test/$TYPE
|
||||
34
.github/workflows/ufuzz.yml
vendored
34
.github/workflows/ufuzz.yml
vendored
@@ -1,34 +0,0 @@
|
||||
name: Fuzzing
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/15 * * * *"
|
||||
jobs:
|
||||
ufuzz:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
name: ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
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
|
||||
cd ~/.nvs
|
||||
git clean -xdf
|
||||
cd -
|
||||
done
|
||||
. ~/.nvs/nvs.sh --version
|
||||
nvs use 10
|
||||
node --version
|
||||
npm config set audit false
|
||||
npm config set optional false
|
||||
npm config set save false
|
||||
npm config set strict-ssl false
|
||||
npm config set update-notifier false
|
||||
npm --version
|
||||
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||
node test/ufuzz/job 3600000
|
||||
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
@@ -1,61 +0,0 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
## Documentation
|
||||
|
||||
Every new feature and API change should be accompanied by a README additon.
|
||||
|
||||
## Testing
|
||||
|
||||
All features and bugs should have tests that verify the fix. You can run all
|
||||
tests using `npm test`.
|
||||
|
||||
The most common type of test are tests that verify input and output of the
|
||||
Uglify transforms. These tests exist in `test/compress`. New tests can be added
|
||||
either to an existing file or in a new file `issue-xxx.js`.
|
||||
|
||||
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
|
||||
|
||||
## Code style
|
||||
|
||||
- File encoding must be `UTF-8`.
|
||||
- `LF` is always used as a line ending.
|
||||
- Statements end with semicolons.
|
||||
- Indentation uses 4 spaces, switch `case` 2 spaces.
|
||||
- Identifiers use `snake_case`.
|
||||
- Strings use double quotes (`"`).
|
||||
- Use a trailing comma for multiline array and object literals to minimize diffs.
|
||||
- The Uglify code only uses ES5, even in the `harmony` branch.
|
||||
- Line length should be at most 80 cols, except when it is easier to read a
|
||||
longer line.
|
||||
- If both sides of a comparison are of the same type, `==` and `!=` are used.
|
||||
- Multiline conditions place `&&` and `||` first on the line.
|
||||
|
||||
**Example feature**
|
||||
|
||||
```js
|
||||
OPT(AST_Debugger, function(self, compressor) {
|
||||
if (compressor.option("drop_debugger"))
|
||||
return make_node(AST_EmptyStatement, self);
|
||||
return self;
|
||||
});
|
||||
```
|
||||
|
||||
**Example test case**
|
||||
|
||||
```js
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
}
|
||||
expect: {
|
||||
if (foo);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
UglifyJS is released under the BSD license:
|
||||
|
||||
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
23
appveyor.yml
23
appveyor.yml
@@ -1,5 +1,24 @@
|
||||
build: off
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- npm install
|
||||
|
||||
test_script:
|
||||
- echo No longer in use
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
|
||||
build: off
|
||||
|
||||
251
bin/uglifyjs
251
bin/uglifyjs
@@ -3,7 +3,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
require("../tools/exit");
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
@@ -11,65 +15,43 @@ var path = require("path");
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
mangle: false
|
||||
};
|
||||
program.version(info.name + " " + info.version);
|
||||
program.version(info.name + ' ' + info.version);
|
||||
program.parseArgv = program.parse;
|
||||
program.parse = undefined;
|
||||
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
||||
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
||||
var text = [];
|
||||
var options = UglifyJS.default_options();
|
||||
for (var option in options) {
|
||||
text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
|
||||
text.push(format_object(options[option]));
|
||||
text.push("");
|
||||
}
|
||||
return text.join("\n");
|
||||
};
|
||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
||||
program.option("-O, --output-opts [options]", "Output options (beautify disabled).", parse_js());
|
||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed everything in a big function, with configurable argument(s) & value(s).");
|
||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||
program.option("--rename", "Force symbol expansion.");
|
||||
program.option("--no-rename", "Disable symbol expansion.");
|
||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
|
||||
program.option("--timings", "Display operations run time on STDERR.");
|
||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
||||
program.option("--stats", "Display operations run time on STDERR.")
|
||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||
program.option("--verbose", "Print diagnostic messages.");
|
||||
program.option("--warn", "Print warning messages.");
|
||||
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
||||
program.option("--reduce-test", "Reduce a standalone `console.log` based test case.");
|
||||
program.arguments("[files...]").parseArgv(process.argv);
|
||||
if (program.configFile) {
|
||||
options = JSON.parse(read_file(program.configFile));
|
||||
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
|
||||
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
|
||||
expression: true
|
||||
}).value;
|
||||
}
|
||||
}
|
||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
fatal("cannot write source map to STDOUT");
|
||||
fatal("ERROR: cannot write source map to STDOUT");
|
||||
}
|
||||
[
|
||||
"compress",
|
||||
"enclose",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"sourceMap",
|
||||
@@ -80,25 +62,12 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
options[name] = program[name];
|
||||
}
|
||||
});
|
||||
if (program.verbose) {
|
||||
options.warnings = "verbose";
|
||||
} else if (program.warn) {
|
||||
options.warnings = true;
|
||||
}
|
||||
if (options.warnings) {
|
||||
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
|
||||
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";
|
||||
@@ -120,14 +89,23 @@ if (program.mangleProps) {
|
||||
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);
|
||||
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||
});
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
options.mangle.properties = program.mangleProps;
|
||||
}
|
||||
var cache;
|
||||
if (program.nameCache) {
|
||||
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||
cache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||
if (options.mangle) {
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
options.mangle.cache = to_cache("vars");
|
||||
if (options.mangle.properties) {
|
||||
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
||||
options.mangle.properties.cache = to_cache("props");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (program.output == "ast") {
|
||||
options.output = {
|
||||
@@ -136,17 +114,12 @@ if (program.output == "ast") {
|
||||
};
|
||||
}
|
||||
if (program.parse) {
|
||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
||||
if (program.parse.acorn || program.parse.spidermonkey) {
|
||||
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
||||
} else {
|
||||
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) {
|
||||
return name;
|
||||
};
|
||||
@@ -159,8 +132,15 @@ if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
||||
};
|
||||
}();
|
||||
}
|
||||
if (program.verbose) {
|
||||
options.warnings = "verbose";
|
||||
} else if (program.warn) {
|
||||
options.warnings = true;
|
||||
}
|
||||
if (program.self) {
|
||||
if (program.args.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||
if (program.args.length) {
|
||||
console.error("WARN: Ignoring input files since --self was passed");
|
||||
}
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
@@ -188,12 +168,10 @@ function convert_ast(fn) {
|
||||
}
|
||||
|
||||
function run() {
|
||||
var content = program.sourceMap && program.sourceMap.content;
|
||||
if (content && content != "inline") {
|
||||
UglifyJS.AST_Node.info("Using input source map: " + content);
|
||||
options.sourceMap.content = read_file(content, content);
|
||||
}
|
||||
if (program.timings) options.timings = true;
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
console.error("WARN:", msg);
|
||||
};
|
||||
if (program.stats) program.stats = Date.now();
|
||||
try {
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn) {
|
||||
@@ -216,58 +194,34 @@ function run() {
|
||||
} catch (ex) {
|
||||
fatal(ex);
|
||||
}
|
||||
if (program.reduceTest) {
|
||||
// load on demand - assumes dev tree checked out
|
||||
var reduce_test = require("../test/reduce");
|
||||
var testcase = files[0] || files[Object.keys(files)[0]];
|
||||
var result = reduce_test(testcase, options, {verbose: true});
|
||||
}
|
||||
else {
|
||||
var result = UglifyJS.minify(files, options);
|
||||
}
|
||||
if (result.error) {
|
||||
var ex = result.error;
|
||||
if (ex.name == "SyntaxError") {
|
||||
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var file = files[ex.filename];
|
||||
if (file) {
|
||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var col = ex.col;
|
||||
var lines = file.split(/\r?\n/);
|
||||
var lines = files[ex.filename].split(/\r?\n/);
|
||||
var line = lines[ex.line - 1];
|
||||
if (!line && !col) {
|
||||
line = lines[ex.line - 2];
|
||||
col = line.length;
|
||||
}
|
||||
if (line) {
|
||||
var limit = 70;
|
||||
if (col > limit) {
|
||||
line = line.slice(col - limit);
|
||||
col = limit;
|
||||
if (col > 40) {
|
||||
line = line.slice(col - 40);
|
||||
col = 40;
|
||||
}
|
||||
print_error(line.slice(0, 80));
|
||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
console.error(line.slice(0, 80));
|
||||
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
}
|
||||
}
|
||||
} else if (ex.defs) {
|
||||
print_error("Supported options:");
|
||||
print_error(format_object(ex.defs));
|
||||
if (ex.defs) {
|
||||
console.error("Supported options:");
|
||||
console.error(ex.defs);
|
||||
}
|
||||
fatal(ex);
|
||||
} else if (program.output == "ast") {
|
||||
if (!options.compress && !options.mangle) {
|
||||
result.ast.figure_out_scope({});
|
||||
}
|
||||
print(JSON.stringify(result.ast, function(key, value) {
|
||||
if (value) switch (key) {
|
||||
case "thedef":
|
||||
return symdef(value);
|
||||
case "enclosed":
|
||||
return value.length ? value.map(symdef) : undefined;
|
||||
case "variables":
|
||||
case "functions":
|
||||
case "globals":
|
||||
return value.size() ? value.map(symdef) : undefined;
|
||||
}
|
||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||
if (skip_key(key)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
@@ -283,7 +237,7 @@ function run() {
|
||||
return value;
|
||||
}, 2));
|
||||
} else if (program.output == "spidermonkey") {
|
||||
print(JSON.stringify(UglifyJS.minify(result.code, {
|
||||
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
@@ -297,23 +251,19 @@ function run() {
|
||||
fs.writeFileSync(program.output + ".map", result.map);
|
||||
}
|
||||
} else {
|
||||
print(result.code);
|
||||
console.log(result.code);
|
||||
}
|
||||
if (program.nameCache) {
|
||||
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
||||
}
|
||||
if (result.timings) for (var phase in result.timings) {
|
||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
||||
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
||||
}));
|
||||
}
|
||||
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
|
||||
}
|
||||
|
||||
function fatal(message) {
|
||||
if (message instanceof Error) {
|
||||
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||
} else {
|
||||
message = "ERROR: " + message;
|
||||
}
|
||||
print_error(message);
|
||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -337,7 +287,7 @@ function simple_glob(glob) {
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.sort().filter(function(name) {
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
@@ -357,17 +307,25 @@ function read_file(path, default_value) {
|
||||
}
|
||||
}
|
||||
|
||||
function parse_js(flag) {
|
||||
function parse_js(flag, constants) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
UglifyJS.parse(value, {
|
||||
UglifyJS.minify(value, {
|
||||
parse: {
|
||||
expression: true
|
||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
if (flag) {
|
||||
if (!constants) {
|
||||
options[name] = value;
|
||||
} else if (value instanceof UglifyJS.AST_Array) {
|
||||
options[name] = value.elements.map(to_string);
|
||||
@@ -384,50 +342,43 @@ function parse_js(flag) {
|
||||
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||
|
||||
function to_string(value) {
|
||||
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
|
||||
return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({
|
||||
quote_keys: true
|
||||
});
|
||||
}
|
||||
}));
|
||||
} catch (ex) {
|
||||
if (flag) {
|
||||
fatal("cannot parse arguments for '" + flag + "': " + value);
|
||||
} else {
|
||||
options[value] = null;
|
||||
}
|
||||
} catch(ex) {
|
||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
function parse_source_map() {
|
||||
var parse = parse_js("sourceMap", true);
|
||||
return function(value, options) {
|
||||
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
||||
var settings = parse(value, options);
|
||||
if (!hasContent && settings.content && settings.content != "inline") {
|
||||
console.error("INFO: Using input source map:", settings.content);
|
||||
settings.content = read_file(settings.content, settings.content);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
function to_cache(key) {
|
||||
if (cache[key]) {
|
||||
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
||||
} else {
|
||||
cache[key] = {
|
||||
cname: -1,
|
||||
props: new UglifyJS.Dictionary()
|
||||
};
|
||||
}
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
function symdef(def) {
|
||||
var ret = (1e6 + def.id) + " " + def.name;
|
||||
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function format_object(obj) {
|
||||
var lines = [];
|
||||
var padding = "";
|
||||
Object.keys(obj).map(function(name) {
|
||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||
return [ name, JSON.stringify(obj[name]) ];
|
||||
}).forEach(function(tokens) {
|
||||
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||
});
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function print_error(msg) {
|
||||
process.stderr.write(msg);
|
||||
process.stderr.write("\n");
|
||||
}
|
||||
|
||||
function print(txt) {
|
||||
process.stdout.write(txt);
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
|
||||
708
lib/ast.js
708
lib/ast.js
File diff suppressed because it is too large
Load Diff
7895
lib/compress.js
7895
lib/compress.js
File diff suppressed because it is too large
Load Diff
205
lib/minify.js
205
lib/minify.js
@@ -1,47 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
var to_ascii, to_base64;
|
||||
if (typeof Buffer == "undefined") {
|
||||
to_ascii = atob;
|
||||
to_base64 = btoa;
|
||||
} else if (typeof Buffer.alloc == "undefined") {
|
||||
to_ascii = function(b64) {
|
||||
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
||||
return new Buffer(b64, "base64").toString();
|
||||
};
|
||||
to_base64 = function(str) {
|
||||
} : atob;
|
||||
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||
return new Buffer(str).toString("base64");
|
||||
};
|
||||
} else {
|
||||
to_ascii = function(b64) {
|
||||
return Buffer.from(b64, "base64").toString();
|
||||
};
|
||||
to_base64 = function(str) {
|
||||
return Buffer.from(str).toString("base64");
|
||||
};
|
||||
}
|
||||
} : btoa;
|
||||
|
||||
function read_source_map(name, toplevel) {
|
||||
var comments = toplevel.end.comments_after;
|
||||
for (var i = comments.length; --i >= 0;) {
|
||||
var comment = comments[i];
|
||||
if (comment.type != "comment1") break;
|
||||
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
|
||||
if (!match) break;
|
||||
if (match[1] == "sourceMappingURL") {
|
||||
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
|
||||
if (!match) break;
|
||||
function read_source_map(code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
AST_Node.warn("inline source map not found");
|
||||
return null;
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
}
|
||||
AST_Node.warn("inline source map not found: " + name);
|
||||
}
|
||||
|
||||
function parse_source_map(content) {
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (ex) {
|
||||
throw new Error("invalid input source map: " + content);
|
||||
}
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
@@ -55,74 +27,40 @@ function set_shorthand(name, options, keys) {
|
||||
}
|
||||
}
|
||||
|
||||
function init_cache(cache) {
|
||||
if (!cache) return;
|
||||
if (!("props" in cache)) {
|
||||
cache.props = new Dictionary();
|
||||
} else if (!(cache.props instanceof Dictionary)) {
|
||||
cache.props = Dictionary.fromObject(cache.props);
|
||||
}
|
||||
}
|
||||
|
||||
function to_json(cache) {
|
||||
return {
|
||||
props: cache.props.toObject()
|
||||
};
|
||||
}
|
||||
|
||||
function minify(files, options) {
|
||||
var warn_function = AST_Node.warn_function;
|
||||
try {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options = defaults(options, {
|
||||
compress: {},
|
||||
enclose: false,
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
warnings: false,
|
||||
wrap: false,
|
||||
}, true);
|
||||
var timings = options.timings && {
|
||||
start: Date.now()
|
||||
};
|
||||
if (options.rename === undefined) {
|
||||
options.rename = options.compress && options.mangle;
|
||||
}
|
||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
var quoted_props;
|
||||
set_shorthand("warnings", options, [ "compress" ]);
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
cache: null,
|
||||
eval: false,
|
||||
ie8: false,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
safari10: false,
|
||||
toplevel: false,
|
||||
}, true);
|
||||
if (options.mangle.properties) {
|
||||
if (typeof options.mangle.properties != "object") {
|
||||
options.mangle.properties = {};
|
||||
}
|
||||
if (options.mangle.properties.keep_quoted) {
|
||||
quoted_props = options.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
options.mangle.properties.reserved = quoted_props;
|
||||
}
|
||||
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
||||
options.mangle.properties.cache = options.nameCache.props || {};
|
||||
}
|
||||
}
|
||||
init_cache(options.mangle.cache);
|
||||
init_cache(options.mangle.properties.cache);
|
||||
}
|
||||
if (options.sourceMap) {
|
||||
options.sourceMap = defaults(options.sourceMap, {
|
||||
@@ -134,85 +72,61 @@ function minify(files, options) {
|
||||
}, true);
|
||||
}
|
||||
var warnings = [];
|
||||
if (options.warnings) AST_Node.log_function(function(warning) {
|
||||
if (options.warnings && !AST_Node.warn_function) {
|
||||
AST_Node.warn_function = function(warning) {
|
||||
warnings.push(warning);
|
||||
}, options.warnings == "verbose");
|
||||
if (timings) timings.parse = Date.now();
|
||||
var source_maps, toplevel;
|
||||
};
|
||||
}
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
source_map_content = parse_source_map(source_map_content);
|
||||
}
|
||||
source_maps = source_map_content && Object.create(null);
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
for (var name in files) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||
if (source_maps) {
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, toplevel);
|
||||
if (inlined_content) {
|
||||
source_maps[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
} else {
|
||||
source_maps[name] = source_map_content;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
if (Object.keys(files).length > 1)
|
||||
throw new Error("inline source map only works with singular input");
|
||||
options.sourceMap.content = read_source_map(files[name]);
|
||||
}
|
||||
}
|
||||
toplevel = options.parse.toplevel;
|
||||
}
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
[ "enclose", "wrap" ].forEach(function(action) {
|
||||
var option = options[action];
|
||||
if (!option) return;
|
||||
var orig = toplevel.print_to_string().slice(0, -1);
|
||||
toplevel = toplevel[action](option);
|
||||
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
||||
});
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
if (options.compress) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
}
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
if (timings) timings.scope = Date.now();
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
if (options.mangle) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
base54.reset();
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
if (options.mangle.properties) {
|
||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||
}
|
||||
if (timings) timings.output = Date.now();
|
||||
}
|
||||
var result = {};
|
||||
if (options.output.ast) {
|
||||
result.ast = toplevel;
|
||||
}
|
||||
if (!HOP(options.output, "code") || options.output.code) {
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||
}
|
||||
options.output.source_map = SourceMap({
|
||||
content: options.sourceMap.includeSources,
|
||||
file: options.sourceMap.filename,
|
||||
orig: source_maps,
|
||||
orig: options.sourceMap.content,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
if (files instanceof AST_Toplevel) {
|
||||
throw new Error("original source content unavailable");
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.setSourceContent(name, files[name]);
|
||||
for (var name in files) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,41 +137,20 @@ function minify(files, options) {
|
||||
result.code = stream.get();
|
||||
if (options.sourceMap) {
|
||||
result.map = options.output.source_map.toString();
|
||||
var url = options.sourceMap.url;
|
||||
if (url) {
|
||||
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
|
||||
if (url == "inline") {
|
||||
if (options.sourceMap.url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else {
|
||||
result.code += "\n//# sourceMappingURL=" + url;
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.nameCache && options.mangle) {
|
||||
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
||||
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||
options.nameCache.props = to_json(options.mangle.properties.cache);
|
||||
}
|
||||
}
|
||||
if (timings) {
|
||||
timings.end = Date.now();
|
||||
result.timings = {
|
||||
parse: 1e-3 * (timings.rename - timings.parse),
|
||||
rename: 1e-3 * (timings.compress - timings.rename),
|
||||
compress: 1e-3 * (timings.scope - timings.compress),
|
||||
scope: 1e-3 * (timings.mangle - timings.scope),
|
||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||
properties: 1e-3 * (timings.output - timings.properties),
|
||||
output: 1e-3 * (timings.end - timings.output),
|
||||
total: 1e-3 * (timings.end - timings.start)
|
||||
};
|
||||
}
|
||||
if (warnings.length) {
|
||||
result.warnings = warnings;
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
return { error: ex };
|
||||
} finally {
|
||||
AST_Node.warn_function = warn_function;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
function normalize_directives(body) {
|
||||
(function(){
|
||||
|
||||
var normalize_directives = function(body) {
|
||||
var in_directive = true;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||
body[i] = new AST_Directive({
|
||||
@@ -57,8 +59,9 @@
|
||||
in_directive = false;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
};
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
Program: function(M) {
|
||||
@@ -115,7 +118,7 @@
|
||||
value : from_moz(M.value)
|
||||
};
|
||||
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
||||
args.key = new AST_SymbolAccessor({
|
||||
args.key = new AST_SymbolMethod({
|
||||
name: args.key
|
||||
});
|
||||
args.value = new AST_Accessor(args.value);
|
||||
@@ -126,7 +129,7 @@
|
||||
return new AST_Array({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
elements : M.elements.map(function(elem) {
|
||||
elements : M.elements.map(function(elem){
|
||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||
})
|
||||
});
|
||||
@@ -135,7 +138,7 @@
|
||||
return new AST_Object({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
properties : M.properties.map(function(prop) {
|
||||
properties : M.properties.map(function(prop){
|
||||
prop.type = "Property";
|
||||
return from_moz(prop)
|
||||
})
|
||||
@@ -165,7 +168,7 @@
|
||||
});
|
||||
},
|
||||
VariableDeclaration: function(M) {
|
||||
return new AST_Var({
|
||||
return new (M.kind === "const" ? AST_Const : AST_Var)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
definitions : M.declarations.map(from_moz)
|
||||
@@ -177,17 +180,6 @@
|
||||
end : my_end_token(M)
|
||||
};
|
||||
if (val === null) return new AST_Null(args);
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags);
|
||||
args.value.raw_source = rx.pattern;
|
||||
return new AST_RegExp(args);
|
||||
} else if (rx) {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
switch (typeof val) {
|
||||
case "string":
|
||||
args.value = val;
|
||||
@@ -197,12 +189,22 @@
|
||||
return new AST_Number(args);
|
||||
case "boolean":
|
||||
return new (val ? AST_True : AST_False)(args);
|
||||
default:
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags).toString();
|
||||
} else {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
}
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
},
|
||||
Identifier: function(M) {
|
||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||
return new ( p.type == "LabeledStatement" ? AST_Label
|
||||
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
|
||||
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
||||
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||
@@ -322,7 +324,7 @@
|
||||
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
||||
return {
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
kind: M instanceof AST_Const ? "const" : "var",
|
||||
declarations: M.definitions.map(to_moz)
|
||||
};
|
||||
});
|
||||
@@ -379,7 +381,7 @@
|
||||
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
||||
var key = {
|
||||
type: "Literal",
|
||||
value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
|
||||
value: M.key instanceof AST_SymbolMethod ? M.key.name : M.key
|
||||
};
|
||||
var kind;
|
||||
if (M instanceof AST_ObjectKeyVal) {
|
||||
@@ -403,20 +405,19 @@
|
||||
var def = M.definition();
|
||||
return {
|
||||
type: "Identifier",
|
||||
name: def && def.mangled_name || M.name
|
||||
name: def ? def.mangled_name || def.name : M.name
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||
var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
||||
var value = "/" + M.value.raw_source + "/" + flags;
|
||||
var value = M.value;
|
||||
return {
|
||||
type: "Literal",
|
||||
value: value,
|
||||
raw: value,
|
||||
raw: value.toString(),
|
||||
regex: {
|
||||
pattern: M.value.raw_source,
|
||||
flags: flags
|
||||
pattern: value.source,
|
||||
flags: value.toString().match(/[gimuy]*$/)[0]
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -477,7 +478,7 @@
|
||||
endpos : range ? range[0] : moznode.start,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function my_end_token(moznode) {
|
||||
var loc = moznode.loc, end = loc && loc.end;
|
||||
@@ -492,7 +493,7 @@
|
||||
endpos : range ? range[1] : moznode.end,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function map(moztype, mytype, propmap) {
|
||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||
@@ -504,7 +505,7 @@
|
||||
me_to_moz += "return {\n" +
|
||||
"type: " + JSON.stringify(moztype);
|
||||
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
|
||||
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
||||
if (!m) throw new Error("Can't understand property map: " + prop);
|
||||
var moz = m[1], how = m[2], my = m[3];
|
||||
@@ -547,7 +548,7 @@
|
||||
);
|
||||
MOZ_TO_ME[moztype] = moz_to_me;
|
||||
def_to_moz(mytype, me_to_moz);
|
||||
}
|
||||
};
|
||||
|
||||
var FROM_MOZ_STACK = null;
|
||||
|
||||
@@ -556,28 +557,13 @@
|
||||
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||
FROM_MOZ_STACK.pop();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
AST_Node.from_mozilla_ast = function(node){
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
var ast = from_moz(node);
|
||||
FROM_MOZ_STACK = save_stack;
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LabelRef) {
|
||||
for (var level = 0, parent; parent = this.parent(level); level++) {
|
||||
if (parent instanceof AST_Scope) break;
|
||||
if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
|
||||
node.thedef = parent.label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!node.thedef) {
|
||||
var s = node.start;
|
||||
js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos);
|
||||
}
|
||||
}
|
||||
}));
|
||||
return ast;
|
||||
};
|
||||
|
||||
@@ -597,24 +583,24 @@
|
||||
}
|
||||
}
|
||||
return moznode;
|
||||
}
|
||||
};
|
||||
|
||||
function def_to_moz(mytype, handler) {
|
||||
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
||||
return set_moz_loc(this, handler(this));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function to_moz(node) {
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
};
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
body: node.body.map(to_moz)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function to_moz_scope(type, node) {
|
||||
var body = node.body.map(to_moz);
|
||||
@@ -625,5 +611,5 @@
|
||||
type: type,
|
||||
body: body
|
||||
};
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
1506
lib/output.js
1506
lib/output.js
File diff suppressed because it is too large
Load Diff
1886
lib/parse.js
1886
lib/parse.js
File diff suppressed because one or more lines are too long
@@ -44,6 +44,16 @@
|
||||
"use strict";
|
||||
|
||||
function find_builtins(reserved) {
|
||||
|
||||
// Compatibility fix for some standard defined globals not defined on every js environment
|
||||
var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
|
||||
var objects = {};
|
||||
var global_ref = typeof global === "object" ? global : self;
|
||||
|
||||
new_globals.forEach(function (new_global) {
|
||||
objects[new_global] = global_ref[new_global] || new Function();
|
||||
});
|
||||
|
||||
// NaN will be included due to Number.NaN
|
||||
[
|
||||
"null",
|
||||
@@ -53,57 +63,28 @@ function find_builtins(reserved) {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp, objects.Symbol, ArrayBuffer,
|
||||
DataView, decodeURI, decodeURIComponent,
|
||||
encodeURI, encodeURIComponent, eval, EvalError,
|
||||
Float32Array, Float64Array, Int8Array, Int16Array,
|
||||
Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
|
||||
parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
|
||||
objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
|
||||
Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
|
||||
objects.WeakMap, objects.WeakSet
|
||||
].forEach(function(ctor){
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
}
|
||||
});
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||
add(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
function addStrings(node, add) {
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
addStrings(node.tail_node(), add);
|
||||
} else if (node instanceof AST_String) {
|
||||
add(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
addStrings(node.consequent, add);
|
||||
addStrings(node.alternative, add);
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
function mangle_properties(ast, options) {
|
||||
options = defaults(options, {
|
||||
builtins: false,
|
||||
@@ -113,67 +94,89 @@ function mangle_properties(ast, options) {
|
||||
only_cache: false,
|
||||
regex: null,
|
||||
reserved: null,
|
||||
}, true);
|
||||
});
|
||||
|
||||
var reserved = options.reserved;
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
var reserved = options.reserved || [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cname = -1;
|
||||
var cache;
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
cache.each(function(mangled_name) {
|
||||
push_uniq(reserved, mangled_name);
|
||||
});
|
||||
} else {
|
||||
cache = new Dictionary();
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
cache = {
|
||||
cname: -1,
|
||||
props: new Dictionary()
|
||||
};
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
var keep_quoted = options.keep_quoted;
|
||||
|
||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug_suffix;
|
||||
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
|
||||
var debug_name_suffix;
|
||||
if (debug) {
|
||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||
}
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
var to_keep = {};
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
add(node.key, keep_quoted && node.quote);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
add(node.key.name);
|
||||
} else if (node instanceof AST_Dot) {
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
add(node.property);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
addStrings(node.args[1], add);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, keep_quoted);
|
||||
}
|
||||
else if (node instanceof AST_ConciseMethod) {
|
||||
add(node.name.name);
|
||||
}
|
||||
}));
|
||||
|
||||
// step 2: transform the tree, renaming properties
|
||||
return ast.transform(new TreeTransformer(function(node) {
|
||||
return ast.transform(new TreeTransformer(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
if (!(keep_quoted && node.quote))
|
||||
node.key = mangle(node.key);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter
|
||||
node.key.name = mangle(node.key.name);
|
||||
} else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
} else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
node.property = mangleStrings(node.property);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
node.args[1] = mangleStrings(node.args[1]);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
if (!keep_quoted)
|
||||
node.property = mangleStrings(node.property);
|
||||
}
|
||||
else if (node instanceof AST_ConciseMethod) {
|
||||
if (should_mangle(node.name.name)) {
|
||||
node.name.name = mangle(node.name.name);
|
||||
}
|
||||
}
|
||||
// else if (node instanceof AST_String) {
|
||||
// if (should_mangle(node.value)) {
|
||||
// AST_Node.warn(
|
||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
||||
// file : node.start.file,
|
||||
// line : node.start.line,
|
||||
// col : node.start.col,
|
||||
// prop : node.value
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
}));
|
||||
|
||||
// only function declarations after this line
|
||||
@@ -181,50 +184,102 @@ function mangle_properties(ast, options) {
|
||||
function can_mangle(name) {
|
||||
if (unmangleable.indexOf(name) >= 0) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
if (options.only_cache) return cache.has(name);
|
||||
if (options.only_cache) {
|
||||
return cache.props.has(name);
|
||||
}
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (keep_quoted && name in to_keep) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.has(name) || names_to_mangle.indexOf(name) >= 0;
|
||||
return cache.props.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
if (can_mangle(name)) push_uniq(names_to_mangle, name);
|
||||
if (!should_mangle(name)) push_uniq(unmangleable, name);
|
||||
function add(name, keep) {
|
||||
if (keep) {
|
||||
to_keep[name] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (can_mangle(name))
|
||||
push_uniq(names_to_mangle, name);
|
||||
|
||||
if (!should_mangle(name)) {
|
||||
push_uniq(unmangleable, name);
|
||||
}
|
||||
}
|
||||
|
||||
function mangle(name) {
|
||||
if (!should_mangle(name)) {
|
||||
return name;
|
||||
}
|
||||
var mangled = cache.get(name);
|
||||
|
||||
var mangled = cache.props.get(name);
|
||||
if (!mangled) {
|
||||
if (debug) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
|
||||
if (can_mangle(debug_mangled)) mangled = debug_mangled;
|
||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||
|
||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
||||
mangled = debug_mangled;
|
||||
}
|
||||
}
|
||||
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) do {
|
||||
mangled = base54(++cname);
|
||||
} while (!can_mangle(mangled));
|
||||
cache.set(name, mangled);
|
||||
if (!mangled) {
|
||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
||||
// check so we don't collide with a quoted name.
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
||||
}
|
||||
|
||||
cache.props.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function addStrings(node, keep) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
node.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_Sequence) {
|
||||
walk(node.expressions[node.expressions.length - 1]);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_String) {
|
||||
add(node.value, keep);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Conditional) {
|
||||
walk(node.consequent);
|
||||
walk(node.alternative);
|
||||
return true;
|
||||
}
|
||||
throw out;
|
||||
}));
|
||||
})(node);
|
||||
} catch(ex) {
|
||||
if (ex !== out) throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
function mangleStrings(node) {
|
||||
return node.transform(new TreeTransformer(function(node) {
|
||||
return node.transform(new TreeTransformer(function(node){
|
||||
if (node instanceof AST_Sequence) {
|
||||
var last = node.expressions.length - 1;
|
||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||
} else if (node instanceof AST_String) {
|
||||
}
|
||||
else if (node instanceof AST_String) {
|
||||
node.value = mangle(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
}
|
||||
else if (node instanceof AST_Conditional) {
|
||||
node.consequent = mangleStrings(node.consequent);
|
||||
node.alternative = mangleStrings(node.alternative);
|
||||
}
|
||||
|
||||
751
lib/scope.js
751
lib/scope.js
@@ -43,209 +43,297 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, orig, init) {
|
||||
function SymbolDef(scope, index, orig) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.init = init;
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
this.replaced = 0;
|
||||
this.global = false;
|
||||
this.export = false;
|
||||
this.mangled_name = null;
|
||||
this.object_destructuring_arg = false;
|
||||
this.undeclared = false;
|
||||
this.index = index;
|
||||
this.id = SymbolDef.next_id++;
|
||||
this.lambda = orig instanceof AST_SymbolLambda;
|
||||
}
|
||||
};
|
||||
|
||||
SymbolDef.next_id = 1;
|
||||
|
||||
SymbolDef.prototype = {
|
||||
unmangleable: function(options) {
|
||||
return this.global && !options.toplevel
|
||||
if (!options) options = {};
|
||||
|
||||
return (this.global && !options.toplevel)
|
||||
|| this.export
|
||||
|| this.object_destructuring_arg
|
||||
|| this.undeclared
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||
|| (options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||
|| this.orig[0] instanceof AST_SymbolDefun))
|
||||
|| this.orig[0] instanceof AST_SymbolMethod
|
||||
|| (options.keep_classnames
|
||||
&& (this.orig[0] instanceof AST_SymbolClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefClass));
|
||||
},
|
||||
mangle: function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
if (this.global && cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var def;
|
||||
if (def = this.redefined()) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else {
|
||||
this.mangled_name = next_mangled_name(this.scope, options, this);
|
||||
}
|
||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
var sym = this.orig[0];
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
var def;
|
||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
}
|
||||
},
|
||||
redefined: function() {
|
||||
return this.defun && this.defun.variables.get(this.name);
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
cache: null,
|
||||
ie8: false,
|
||||
safari10: false,
|
||||
});
|
||||
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
var self = this;
|
||||
var scope = self.parent_scope = null;
|
||||
var labels = new Dictionary();
|
||||
var defun = null;
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_Catch) {
|
||||
var in_destructuring = null;
|
||||
var in_export = false;
|
||||
var in_block = 0;
|
||||
var for_scopes = [];
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node.is_block_scope()) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
scope.init_scope_vars(save_scope);
|
||||
if (!(node instanceof AST_Scope)) {
|
||||
scope.uses_with = save_scope.uses_with;
|
||||
scope.uses_eval = save_scope.uses_eval;
|
||||
scope.directives = save_scope.directives;
|
||||
}
|
||||
if (options.safari10) {
|
||||
if (node instanceof AST_For || node instanceof AST_ForIn) {
|
||||
for_scopes.push(scope);
|
||||
}
|
||||
}
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Destructuring && node.is_array === false) {
|
||||
in_destructuring = node; // These don't nest
|
||||
descend();
|
||||
in_destructuring = null;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
node.init_scope_vars(scope);
|
||||
var save_scope = scope;
|
||||
var save_defun = defun;
|
||||
var save_labels = labels;
|
||||
defun = scope = node;
|
||||
labels = new Dictionary();
|
||||
descend();
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
labels = save_labels;
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Export) {
|
||||
in_export = true;
|
||||
descend();
|
||||
in_export = false;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_BlockStatement
|
||||
|| node instanceof AST_Switch
|
||||
|| node instanceof AST_Try
|
||||
|| node instanceof AST_Catch
|
||||
|| node instanceof AST_Finally) {
|
||||
in_block++;
|
||||
descend();
|
||||
in_block--;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
var l = node.label;
|
||||
if (labels.has(l.name)) {
|
||||
throw new Error(string_template("Label {name} defined twice", l));
|
||||
}
|
||||
labels.set(l.name, l);
|
||||
descend();
|
||||
labels.del(l.name);
|
||||
return true; // no descend again
|
||||
}
|
||||
if (node instanceof AST_With) {
|
||||
for (var s = scope; s; s = s.parent_scope) s.uses_with = true;
|
||||
for (var s = scope; s; s = s.parent_scope)
|
||||
s.uses_with = true;
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Symbol) {
|
||||
node.scope = scope;
|
||||
}
|
||||
if (node instanceof AST_SymbolFunarg) {
|
||||
node.object_destructuring_arg = !!in_destructuring;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
node.thedef = node;
|
||||
node.references = [];
|
||||
}
|
||||
if (node instanceof AST_SymbolDefun) {
|
||||
// This should be defined in the parent scope, as we encounter the
|
||||
// AST_Defun node before getting to its AST_Symbol.
|
||||
(node.scope = defun.parent_scope.resolve()).def_function(node, defun);
|
||||
} else if (node instanceof AST_SymbolLambda) {
|
||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
||||
} else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
defun.def_function(node, in_export, in_block);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
// the parent scope. The reason is that we enter a new
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
var parent_lambda = defun.parent_scope;
|
||||
while (parent_lambda.is_block_scope()) {
|
||||
parent_lambda = parent_lambda.parent_scope;
|
||||
}
|
||||
(node.scope = parent_lambda).def_function(node, in_export, in_block);
|
||||
}
|
||||
else if (node instanceof AST_SymbolClass) {
|
||||
defun.def_variable(node, in_export, in_block);
|
||||
}
|
||||
else if (node instanceof AST_SymbolImport) {
|
||||
scope.def_variable(node, in_export, in_block);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefClass) {
|
||||
// This deals with the name of the class being available
|
||||
// inside the class.
|
||||
(node.scope = defun.parent_scope).def_function(node, in_export, in_block);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolLet
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node, in_export, in_block);
|
||||
def.destructuring = in_destructuring;
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
var def = scope.find_variable(node);
|
||||
if (node.thedef !== def) {
|
||||
node.thedef = def;
|
||||
}
|
||||
node.reference(options);
|
||||
}
|
||||
} else if (node instanceof AST_SymbolCatch) {
|
||||
scope.def_variable(node).defun = defun;
|
||||
}
|
||||
}
|
||||
else if (node instanceof AST_SymbolCatch) {
|
||||
scope.def_variable(node, in_export, in_block).defun = defun;
|
||||
}
|
||||
else if (node instanceof AST_LabelRef) {
|
||||
var sym = labels.get(node.name);
|
||||
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
||||
name: node.name,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
}));
|
||||
node.thedef = sym;
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: find back references and eval
|
||||
self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl) {
|
||||
if (node.label) node.label.thedef.references.push(node);
|
||||
var func = null;
|
||||
var cls = null;
|
||||
var globals = self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_Lambda) {
|
||||
var prev_func = func;
|
||||
func = node;
|
||||
descend();
|
||||
func = prev_func;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Class) {
|
||||
var prev_cls = cls;
|
||||
cls = node;
|
||||
descend();
|
||||
cls = prev_cls;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_LoopControl && node.label) {
|
||||
node.label.thedef.references.push(node);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
var name = node.name;
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (!sym) {
|
||||
sym = self.def_global(node);
|
||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||
sym.scope.uses_arguments = true;
|
||||
}
|
||||
if (name == "eval") {
|
||||
var parent = tw.parent();
|
||||
if (parent.TYPE == "Call" && parent.expression === node) {
|
||||
if (name == "eval" && tw.parent() instanceof AST_Call) {
|
||||
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
|
||||
s.uses_eval = true;
|
||||
}
|
||||
} else if (sym.undeclared) {
|
||||
self.uses_eval = true;
|
||||
}
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
||||
node.scope.uses_arguments = true;
|
||||
}
|
||||
if (!sym) {
|
||||
sym = self.def_global(node);
|
||||
}
|
||||
node.thedef = sym;
|
||||
node.reference(options);
|
||||
return true;
|
||||
}
|
||||
// ensure mangling works if catch reuses a scope variable
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var def = node.definition().redefined();
|
||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie8) self.walk(new TreeWalker(function(node) {
|
||||
if (options.ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
var refs = node.thedef.references;
|
||||
var scope = node.thedef.defun;
|
||||
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||
scope = scope.parent_scope.resolve();
|
||||
}
|
||||
redefine(node, scope);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
var def = node.thedef;
|
||||
redefine(node, node.scope.parent_scope.resolve());
|
||||
if (typeof node.thedef.init !== "undefined") {
|
||||
node.thedef.init = false;
|
||||
} else if (def.init) {
|
||||
node.thedef.init = def.init;
|
||||
}
|
||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||
refs.forEach(function(ref) {
|
||||
ref.thedef = def;
|
||||
ref.reference(options);
|
||||
});
|
||||
node.thedef = def;
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function redefine(node, scope) {
|
||||
var name = node.name;
|
||||
var old_def = node.thedef;
|
||||
var new_def = scope.find_variable(name);
|
||||
if (new_def) {
|
||||
var redef;
|
||||
while (redef = new_def.redefined()) new_def = redef;
|
||||
} else {
|
||||
new_def = self.globals.get(name);
|
||||
}
|
||||
if (new_def) {
|
||||
new_def.orig.push(node);
|
||||
} else {
|
||||
new_def = scope.def_variable(node);
|
||||
}
|
||||
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||
node.thedef = new_def;
|
||||
node.reference(options);
|
||||
// pass 4: add symbol definitions to loop scopes
|
||||
// Safari/Webkit bug workaround - loop init let variable shadowing argument.
|
||||
// https://github.com/mishoo/UglifyJS2/issues/1753
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=171041
|
||||
if (options.safari10) {
|
||||
for (var i = 0; i < for_scopes.length; i++) {
|
||||
var scope = for_scopes[i];
|
||||
scope.parent_scope.variables.each(function(def) {
|
||||
push_uniq(scope.enclosed, def);
|
||||
});
|
||||
if (old_def.lambda) new_def.lambda = true;
|
||||
if (new_def.undeclared) self.variables.set(name, new_def);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
var globals = this.globals, name = node.name;
|
||||
if (globals.has(name)) {
|
||||
return globals.get(name);
|
||||
} else {
|
||||
var g = new SymbolDef(this, node);
|
||||
var g = new SymbolDef(this, globals.size(), node);
|
||||
g.undeclared = true;
|
||||
g.global = true;
|
||||
globals.set(name, g);
|
||||
@@ -253,7 +341,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
@@ -263,10 +351,27 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
|
||||
this.cname = -1; // the current index for mangling functions/variables
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
|
||||
AST_Node.DEFMETHOD("is_block_scope", function(){
|
||||
return false; // Behaviour will be overridden by AST_Block
|
||||
});
|
||||
|
||||
AST_Block.DEFMETHOD("is_block_scope", function(){
|
||||
return (
|
||||
!(this instanceof AST_Lambda) &&
|
||||
!(this instanceof AST_Toplevel) &&
|
||||
!(this instanceof AST_Class) &&
|
||||
!(this instanceof AST_SwitchBranch)
|
||||
);
|
||||
});
|
||||
|
||||
AST_IterationStatement.DEFMETHOD("is_block_scope", function(){
|
||||
return true;
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
this.def_variable(new AST_SymbolConst({
|
||||
name: "arguments",
|
||||
start: this.start,
|
||||
end: this.end
|
||||
@@ -275,7 +380,8 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function() {
|
||||
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
var s = this.scope;
|
||||
while (s) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
@@ -283,6 +389,7 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
});
|
||||
}
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -291,341 +398,297 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
|
||||
this.mark_enclosed(options);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name) {
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
if (name instanceof AST_Symbol) name = name.name;
|
||||
return this.variables.get(name)
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, in_export, in_block){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol, in_export, in_block));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
||||
var def = this.variables.get(symbol.name);
|
||||
if (def) {
|
||||
def.orig.push(symbol);
|
||||
if (def.init instanceof AST_Function) def.init = init;
|
||||
} else {
|
||||
def = new SymbolDef(this, symbol, init);
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export, in_block){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.object_destructuring_arg = symbol.object_destructuring_arg;
|
||||
if (in_export) {
|
||||
def.export = true;
|
||||
}
|
||||
if (in_block && symbol instanceof AST_SymbolBlockDeclaration) {
|
||||
def.global = false;
|
||||
} else {
|
||||
def.global = !this.parent_scope;
|
||||
}
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
}
|
||||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("resolve", return_this);
|
||||
AST_Scope.DEFMETHOD("resolve", function() {
|
||||
return this.parent_scope.resolve();
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
var ext = this.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name reserved from mangling.
|
||||
if (options.reserved.indexOf(m) >= 0) continue;
|
||||
|
||||
// we must ensure that the mangled name does not shadow a name
|
||||
// from some parent scope that is referenced in this or in
|
||||
// inner scopes.
|
||||
for (var i = ext.length; --i >= 0;) {
|
||||
var sym = ext[i];
|
||||
var name = sym.mangled_name || (sym.unmangleable(options) && sym.name);
|
||||
if (m == name) continue out;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
});
|
||||
AST_Toplevel.DEFMETHOD("resolve", return_this);
|
||||
|
||||
function names_in_use(scope, options) {
|
||||
var names = scope.names_in_use;
|
||||
if (!names) {
|
||||
scope.names_in_use = names = Object.create(scope.mangled_names || null);
|
||||
scope.cname_holes = [];
|
||||
var cache = options.cache && options.cache.props;
|
||||
scope.enclosed.forEach(function(def) {
|
||||
if (def.unmangleable(options)) names[def.name] = true;
|
||||
if (def.global && cache && cache.has(def.name)) {
|
||||
names[cache.get(def.name)] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return names;
|
||||
}
|
||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// #179, #326
|
||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
||||
// a function expression's argument cannot shadow the function expression's name
|
||||
|
||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
||||
|
||||
// the function's mangled_name is null when keep_fnames is true
|
||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||
|
||||
function next_mangled_name(scope, options, def) {
|
||||
var in_use = names_in_use(scope, options);
|
||||
var holes = scope.cname_holes;
|
||||
var names = Object.create(null);
|
||||
var scopes = [ scope ];
|
||||
def.references.forEach(function(sym) {
|
||||
var scope = sym.scope;
|
||||
do {
|
||||
if (scopes.indexOf(scope) < 0) {
|
||||
for (var name in names_in_use(scope, options)) {
|
||||
names[name] = true;
|
||||
}
|
||||
scopes.push(scope);
|
||||
} else break;
|
||||
} while (scope = scope.parent_scope);
|
||||
});
|
||||
var name;
|
||||
for (var i = 0; i < holes.length; i++) {
|
||||
name = base54(holes[i]);
|
||||
if (names[name]) continue;
|
||||
holes.splice(i, 1);
|
||||
scope.names_in_use[name] = true;
|
||||
return name;
|
||||
}
|
||||
while (true) {
|
||||
name = base54(++scope.cname);
|
||||
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||
if (!names[name]) break;
|
||||
holes.push(scope.cname);
|
||||
}
|
||||
scope.names_in_use[name] = true;
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
var def = this.definition();
|
||||
return !def || def.unmangleable(options);
|
||||
return def && def.unmangleable(options);
|
||||
});
|
||||
|
||||
// labels are always mangleable
|
||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function() {
|
||||
return !this.definition().references.length && !this.scope.pinned();
|
||||
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function() {
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||
return this.definition().references.length == 0
|
||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||
return this.definition().undeclared;
|
||||
});
|
||||
|
||||
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Label.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
return this.thedef;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("global", function() {
|
||||
AST_Symbol.DEFMETHOD("global", function(){
|
||||
return this.definition().global;
|
||||
});
|
||||
|
||||
function _default_mangler_options(options) {
|
||||
options = defaults(options, {
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
return defaults(options, {
|
||||
eval : false,
|
||||
ie8 : false,
|
||||
keep_classnames: false,
|
||||
keep_fnames : false,
|
||||
reserved : [],
|
||||
toplevel : false,
|
||||
});
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
// Never mangle arguments
|
||||
push_uniq(options.reserved, "arguments");
|
||||
options.reserved.has = makePredicate(options.reserved);
|
||||
return options;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
|
||||
// Never mangle arguments
|
||||
options.reserved.push('arguments');
|
||||
|
||||
// We only need to mangle declaration nodes. Special logic wired
|
||||
// into the code generator will display the mangled name if it's
|
||||
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||
// the AST_SymbolDeclaration that it points to).
|
||||
var lname = -1;
|
||||
var to_mangle = [];
|
||||
|
||||
if (options.cache && options.cache.props) {
|
||||
var mangled_names = this.mangled_names = Object.create(null);
|
||||
options.cache.props.each(function(mangled_name) {
|
||||
mangled_names[mangled_name] = true;
|
||||
if (options.cache) {
|
||||
this.globals.each(function(symbol){
|
||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||
to_mangle.push(symbol);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var redefined = [];
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
// lname is incremented when we get to the AST_Label
|
||||
var save_nesting = lname;
|
||||
descend();
|
||||
lname = save_nesting;
|
||||
return true;
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
descend();
|
||||
if (options.cache && node instanceof AST_Toplevel) {
|
||||
node.globals.each(mangle);
|
||||
var p = tw.parent(), a = [];
|
||||
node.variables.each(function(symbol){
|
||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||
a.push(symbol);
|
||||
}
|
||||
if (node instanceof AST_Defun && tw.has_directive("use asm")) {
|
||||
var sym = new AST_SymbolRef(node.name);
|
||||
sym.scope = node;
|
||||
sym.reference(options);
|
||||
}
|
||||
node.variables.each(function(def) {
|
||||
if (!defer_redef(def)) mangle(def);
|
||||
});
|
||||
return true;
|
||||
to_mangle.push.apply(to_mangle, a);
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
var name;
|
||||
do {
|
||||
name = base54(++lname);
|
||||
} while (RESERVED_WORDS[name]);
|
||||
do name = base54(++lname); while (!is_identifier(name));
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (!options.ie8 && node instanceof AST_Catch) {
|
||||
var def = node.argname.definition();
|
||||
var redef = defer_redef(def, node.argname);
|
||||
descend();
|
||||
if (!redef) mangle(def);
|
||||
return true;
|
||||
var mangle_with_block_scope =
|
||||
(!options.ie8 && node instanceof AST_SymbolCatch) ||
|
||||
node instanceof AST_SymbolBlockDeclaration;
|
||||
if (mangle_with_block_scope) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
}
|
||||
});
|
||||
this.walk(tw);
|
||||
redefined.forEach(mangle);
|
||||
|
||||
function mangle(def) {
|
||||
if (options.reserved.has[def.name]) return;
|
||||
to_mangle.forEach(function(def){
|
||||
if (def.destructuring && !def.destructuring.is_array) return;
|
||||
def.mangle(options);
|
||||
}
|
||||
|
||||
function defer_redef(def, node) {
|
||||
var redef = def.redefined();
|
||||
if (!redef) return false;
|
||||
redefined.push(def);
|
||||
def.references.forEach(reference);
|
||||
if (node) reference(node);
|
||||
return true;
|
||||
|
||||
function reference(sym) {
|
||||
sym.thedef = redef;
|
||||
sym.reference(options);
|
||||
sym.thedef = def;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
var avoid = Object.create(null);
|
||||
options.reserved.forEach(to_avoid);
|
||||
this.globals.each(add_def);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||
}));
|
||||
return avoid;
|
||||
|
||||
function to_avoid(name) {
|
||||
avoid[name] = true;
|
||||
}
|
||||
|
||||
function add_def(def) {
|
||||
var name = def.name;
|
||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||
else if (!def.unmangleable(options)) return;
|
||||
to_avoid(name);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||
base54.reset();
|
||||
base54.sort();
|
||||
options = _default_mangler_options(options);
|
||||
var avoid = this.find_colliding_names(options);
|
||||
var cname = 0;
|
||||
this.globals.each(rename);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||
}));
|
||||
|
||||
function next_name() {
|
||||
var name;
|
||||
do {
|
||||
name = base54(cname++);
|
||||
} while (avoid[name] || RESERVED_WORDS[name]);
|
||||
return name;
|
||||
}
|
||||
|
||||
function rename(def) {
|
||||
if (def.global && options.cache) return;
|
||||
if (def.unmangleable(options)) return;
|
||||
if (options.reserved.has[def.name]) return;
|
||||
var redef = def.redefined();
|
||||
var name = redef ? redef.rename || redef.name : next_name();
|
||||
def.rename = name;
|
||||
def.orig.forEach(function(sym) {
|
||||
sym.name = name;
|
||||
});
|
||||
def.references.forEach(function(sym) {
|
||||
sym.name = name;
|
||||
|
||||
if (options.cache) {
|
||||
options.cache.cname = this.cname;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (node instanceof AST_Constant)
|
||||
base54.consider(node.print_to_string());
|
||||
else if (node instanceof AST_Return)
|
||||
base54.consider("return");
|
||||
else if (node instanceof AST_Throw)
|
||||
base54.consider("throw");
|
||||
else if (node instanceof AST_Continue)
|
||||
base54.consider("continue");
|
||||
else if (node instanceof AST_Break)
|
||||
base54.consider("break");
|
||||
else if (node instanceof AST_Debugger)
|
||||
base54.consider("debugger");
|
||||
else if (node instanceof AST_Directive)
|
||||
base54.consider(node.value);
|
||||
else if (node instanceof AST_While)
|
||||
base54.consider("while");
|
||||
else if (node instanceof AST_Do)
|
||||
base54.consider("do while");
|
||||
else if (node instanceof AST_If) {
|
||||
base54.consider("if");
|
||||
if (node.alternative) base54.consider("else");
|
||||
}
|
||||
else if (node instanceof AST_Var)
|
||||
base54.consider("var");
|
||||
else if (node instanceof AST_Const)
|
||||
base54.consider("const");
|
||||
else if (node instanceof AST_Lambda)
|
||||
base54.consider("function");
|
||||
else if (node instanceof AST_For)
|
||||
base54.consider("for");
|
||||
else if (node instanceof AST_ForIn)
|
||||
base54.consider("for in");
|
||||
else if (node instanceof AST_Switch)
|
||||
base54.consider("switch");
|
||||
else if (node instanceof AST_Case)
|
||||
base54.consider("case");
|
||||
else if (node instanceof AST_Default)
|
||||
base54.consider("default");
|
||||
else if (node instanceof AST_With)
|
||||
base54.consider("with");
|
||||
else if (node instanceof AST_ObjectSetter)
|
||||
base54.consider("set" + (typeof node.key === "string" ? node.key : ""));
|
||||
else if (node instanceof AST_ObjectGetter)
|
||||
base54.consider("get" + (typeof node.key === "string" ? node.key : ""));
|
||||
else if (node instanceof AST_ObjectKeyVal && typeof node.key === "string")
|
||||
base54.consider(node.key);
|
||||
else if (node instanceof AST_ConciseMethod && typeof node.key === "string")
|
||||
base54.consider(node.key);
|
||||
else if (node instanceof AST_New)
|
||||
base54.consider("new");
|
||||
else if (node instanceof AST_This)
|
||||
base54.consider("this");
|
||||
else if (node instanceof AST_Super)
|
||||
base54.consider("super");
|
||||
else if (node instanceof AST_Try)
|
||||
base54.consider("try");
|
||||
else if (node instanceof AST_Catch)
|
||||
base54.consider("catch");
|
||||
else if (node instanceof AST_Finally)
|
||||
base54.consider("finally");
|
||||
else if (node instanceof AST_Yield)
|
||||
base54.consider("yield");
|
||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||
base54.consider(node.name);
|
||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||
base54.consider(node.operator);
|
||||
else if (node instanceof AST_Dot)
|
||||
base54.consider(node.property);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AST_Node.DEFMETHOD("tail_node", return_this);
|
||||
AST_Sequence.DEFMETHOD("tail_node", function() {
|
||||
return this.expressions[this.expressions.length - 1];
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
base54.reset();
|
||||
try {
|
||||
AST_Node.prototype.print = function(stream, force_parens) {
|
||||
this._print(stream, force_parens);
|
||||
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||
base54.consider(this.name, -1);
|
||||
} else if (options.properties) {
|
||||
if (this instanceof AST_Dot) {
|
||||
base54.consider(this.property, -1);
|
||||
} else if (this instanceof AST_Sub) {
|
||||
skip_string(this.property);
|
||||
}
|
||||
}
|
||||
};
|
||||
base54.consider(this.print_to_string(), 1);
|
||||
} finally {
|
||||
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||
}
|
||||
this.walk(tw);
|
||||
base54.sort();
|
||||
|
||||
function skip_string(node) {
|
||||
if (node instanceof AST_String) {
|
||||
base54.consider(node.value, -1);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
skip_string(node.consequent);
|
||||
skip_string(node.alternative);
|
||||
} else if (node instanceof AST_Sequence) {
|
||||
skip_string(node.tail_node());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var base54 = (function() {
|
||||
var freq = Object.create(null);
|
||||
function init(chars) {
|
||||
var array = [];
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
var ch = chars[i];
|
||||
array.push(ch);
|
||||
freq[ch] = -1e-2 * i;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
var digits = init("0123456789");
|
||||
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
|
||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
||||
var chars, frequency;
|
||||
function reset() {
|
||||
frequency = Object.create(freq);
|
||||
frequency = Object.create(null);
|
||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
||||
}
|
||||
base54.consider = function(str, delta) {
|
||||
base54.consider = function(str){
|
||||
for (var i = str.length; --i >= 0;) {
|
||||
frequency[str[i]] += delta;
|
||||
var code = str.charCodeAt(i);
|
||||
if (code in frequency) ++frequency[code];
|
||||
}
|
||||
};
|
||||
function compare(a, b) {
|
||||
return frequency[b] - frequency[a];
|
||||
}
|
||||
base54.sort = function() {
|
||||
chars = leading.sort(compare).concat(digits.sort(compare));
|
||||
chars = mergeSort(chars, function(a, b){
|
||||
if (is_digit(a) && !is_digit(b)) return 1;
|
||||
if (is_digit(b) && !is_digit(a)) return -1;
|
||||
return frequency[b] - frequency[a];
|
||||
});
|
||||
};
|
||||
base54.reset = reset;
|
||||
reset();
|
||||
base54.get = function(){ return chars };
|
||||
base54.freq = function(){ return frequency };
|
||||
function base54(num) {
|
||||
var ret = "", base = 54;
|
||||
num++;
|
||||
do {
|
||||
num--;
|
||||
ret += chars[num % base];
|
||||
ret += String.fromCharCode(chars[num % base]);
|
||||
num = Math.floor(num / base);
|
||||
base = 64;
|
||||
} while (num > 0);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
return base54;
|
||||
})();
|
||||
|
||||
177
lib/sourcemap.js
177
lib/sourcemap.js
@@ -43,148 +43,55 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var vlq_char = characters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
|
||||
var vlq_bits = vlq_char.reduce(function(map, ch, bits) {
|
||||
map[ch] = bits;
|
||||
return map;
|
||||
}, Object.create(null));
|
||||
|
||||
function vlq_decode(indices, str) {
|
||||
var value = 0;
|
||||
var shift = 0;
|
||||
for (var i = 0, j = 0; i < str.length; i++) {
|
||||
var bits = vlq_bits[str[i]];
|
||||
value += (bits & 31) << shift;
|
||||
if (bits & 32) {
|
||||
shift += 5;
|
||||
} else {
|
||||
indices[j++] += value & 1 ? 0x80000000 | -(value >> 1) : value >> 1;
|
||||
value = shift = 0;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
function vlq_encode(num) {
|
||||
var result = "";
|
||||
num = Math.abs(num) << 1 | num >>> 31;
|
||||
do {
|
||||
var bits = num & 31;
|
||||
if (num >>>= 5) bits |= 32;
|
||||
result += vlq_char[bits];
|
||||
} while (num);
|
||||
return result;
|
||||
}
|
||||
|
||||
function create_array_map() {
|
||||
var map = Object.create(null);
|
||||
var array = [];
|
||||
array.index = function(name) {
|
||||
if (!HOP(map, name)) {
|
||||
map[name] = array.length;
|
||||
array.push(name);
|
||||
}
|
||||
return map[name];
|
||||
};
|
||||
return array;
|
||||
}
|
||||
|
||||
// a small wrapper around fitzgen's source-map library
|
||||
function SourceMap(options) {
|
||||
options = defaults(options, {
|
||||
content: false,
|
||||
file: null,
|
||||
root: null,
|
||||
orig: null,
|
||||
}, true);
|
||||
var sources = create_array_map();
|
||||
var sources_content = options.content && Object.create(null);
|
||||
var names = create_array_map();
|
||||
var mappings = "";
|
||||
if (options.orig) Object.keys(options.orig).forEach(function(name) {
|
||||
var map = options.orig[name];
|
||||
var indices = [ 0, 0, 1, 0, 0 ];
|
||||
options.orig[name] = {
|
||||
names: map.names,
|
||||
mappings: map.mappings.split(/;/).map(function(line) {
|
||||
indices[0] = 0;
|
||||
return line.split(/,/).map(function(segment) {
|
||||
return indices.slice(0, vlq_decode(indices, segment));
|
||||
file : null,
|
||||
root : null,
|
||||
orig : null,
|
||||
|
||||
orig_line_diff : 0,
|
||||
dest_line_diff : 0,
|
||||
});
|
||||
}),
|
||||
sources: map.sources,
|
||||
};
|
||||
if (!sources_content || !map.sourcesContent) return;
|
||||
for (var i = 0; i < map.sources.length; i++) {
|
||||
var content = map.sourcesContent[i];
|
||||
if (content) sources_content[map.sources[i]] = content;
|
||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||
file : options.file,
|
||||
sourceRoot : options.root
|
||||
});
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
|
||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
||||
orig_map._sources.toArray().forEach(function(source) {
|
||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
||||
if (sourceContent) {
|
||||
generator.setSourceContent(source, sourceContent);
|
||||
}
|
||||
});
|
||||
var generated_line = 1;
|
||||
var generated_column = 0;
|
||||
var source_index = 0;
|
||||
var original_line = 1;
|
||||
var original_column = 0;
|
||||
var name_index = 0;
|
||||
return {
|
||||
add: options.orig ? function(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
var map = options.orig[source];
|
||||
if (map) {
|
||||
var segments = map.mappings[orig_line - 1];
|
||||
if (!segments) return;
|
||||
var indices;
|
||||
for (var i = 0; i < segments.length; i++) {
|
||||
var col = segments[i][0];
|
||||
if (orig_col >= col) indices = segments[i];
|
||||
if (orig_col <= col) break;
|
||||
}
|
||||
if (!indices || indices.length < 4) return;
|
||||
source = map.sources[indices[1]];
|
||||
orig_line = indices[2];
|
||||
orig_col = indices[3];
|
||||
if (indices.length > 4) name = map.names[indices[4]];
|
||||
}
|
||||
add(source, gen_line, gen_col, orig_line, orig_col, name);
|
||||
} : add,
|
||||
setSourceContent: sources_content ? function(source, content) {
|
||||
sources_content[source] = content;
|
||||
} : noop,
|
||||
toString: function() {
|
||||
return JSON.stringify({
|
||||
version: 3,
|
||||
file: options.file || undefined,
|
||||
sourceRoot: options.root || undefined,
|
||||
sources: sources,
|
||||
sourcesContent: sources_content ? sources.map(function(source) {
|
||||
return sources_content[source] || null;
|
||||
}) : undefined,
|
||||
names: names,
|
||||
mappings: mappings,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
if (generated_line < gen_line) {
|
||||
generated_column = 0;
|
||||
do {
|
||||
mappings += ";";
|
||||
} while (++generated_line < gen_line);
|
||||
} else if (mappings) {
|
||||
mappings += ",";
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
});
|
||||
if (info.source === null) {
|
||||
return;
|
||||
}
|
||||
mappings += vlq_encode(gen_col - generated_column);
|
||||
generated_column = gen_col;
|
||||
var src_idx = sources.index(source);
|
||||
mappings += vlq_encode(src_idx - source_index);
|
||||
source_index = src_idx;
|
||||
mappings += vlq_encode(orig_line - original_line);
|
||||
original_line = orig_line;
|
||||
mappings += vlq_encode(orig_col - original_column);
|
||||
original_column = orig_col;
|
||||
if (name != null) {
|
||||
var name_idx = names.index(name);
|
||||
mappings += vlq_encode(name_idx - name_index);
|
||||
name_index = name_idx;
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
}
|
||||
}
|
||||
generator.addMapping({
|
||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
||||
original : { line: orig_line + options.orig_line_diff, column: orig_col },
|
||||
source : source,
|
||||
name : name
|
||||
});
|
||||
};
|
||||
return {
|
||||
add : add,
|
||||
get : function() { return generator },
|
||||
toString : function() { return JSON.stringify(generator.toJSON()); }
|
||||
};
|
||||
};
|
||||
|
||||
175
lib/transform.js
175
lib/transform.js
@@ -43,6 +43,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tree transformer helpers.
|
||||
|
||||
function TreeTransformer(before, after) {
|
||||
TreeWalker.call(this);
|
||||
this.before = before;
|
||||
@@ -50,136 +52,207 @@ function TreeTransformer(before, after) {
|
||||
}
|
||||
TreeTransformer.prototype = new TreeWalker;
|
||||
|
||||
(function(DEF) {
|
||||
(function(undefined){
|
||||
|
||||
function _(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list){
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (x === undefined) {
|
||||
if (!tw.after) {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
} else {
|
||||
tw.stack[tw.stack.length - 1] = x = this;
|
||||
descend(x, tw);
|
||||
y = tw.after(x, in_list);
|
||||
if (y !== undefined) x = y;
|
||||
}
|
||||
}
|
||||
tw.pop(this);
|
||||
return x;
|
||||
});
|
||||
};
|
||||
|
||||
function do_list(list, tw) {
|
||||
return List(list, function(node) {
|
||||
return MAP(list, function(node){
|
||||
return node.transform(tw, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
DEF(AST_Node, noop);
|
||||
DEF(AST_LabeledStatement, function(self, tw) {
|
||||
_(AST_Node, noop);
|
||||
|
||||
_(AST_LabeledStatement, function(self, tw){
|
||||
self.label = self.label.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_SimpleStatement, function(self, tw) {
|
||||
|
||||
_(AST_SimpleStatement, function(self, tw){
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_Block, function(self, tw) {
|
||||
|
||||
_(AST_Block, function(self, tw){
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
DEF(AST_Do, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
self.condition = self.condition.transform(tw);
|
||||
});
|
||||
DEF(AST_While, function(self, tw) {
|
||||
|
||||
_(AST_DWLoop, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_For, function(self, tw) {
|
||||
|
||||
_(AST_For, function(self, tw){
|
||||
if (self.init) self.init = self.init.transform(tw);
|
||||
if (self.condition) self.condition = self.condition.transform(tw);
|
||||
if (self.step) self.step = self.step.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_ForIn, function(self, tw) {
|
||||
|
||||
_(AST_ForIn, function(self, tw){
|
||||
self.init = self.init.transform(tw);
|
||||
self.object = self.object.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_With, function(self, tw) {
|
||||
|
||||
_(AST_With, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
DEF(AST_Exit, function(self, tw) {
|
||||
|
||||
_(AST_Exit, function(self, tw){
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
DEF(AST_LoopControl, function(self, tw) {
|
||||
|
||||
_(AST_LoopControl, function(self, tw){
|
||||
if (self.label) self.label = self.label.transform(tw);
|
||||
});
|
||||
DEF(AST_If, function(self, tw) {
|
||||
|
||||
_(AST_If, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
DEF(AST_Switch, function(self, tw) {
|
||||
|
||||
_(AST_Switch, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
DEF(AST_Case, function(self, tw) {
|
||||
|
||||
_(AST_Case, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
DEF(AST_Try, function(self, tw) {
|
||||
|
||||
_(AST_Try, function(self, tw){
|
||||
self.body = do_list(self.body, tw);
|
||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||
});
|
||||
DEF(AST_Catch, function(self, tw) {
|
||||
|
||||
_(AST_Catch, function(self, tw){
|
||||
self.argname = self.argname.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
DEF(AST_Definitions, function(self, tw) {
|
||||
|
||||
_(AST_Definitions, function(self, tw){
|
||||
self.definitions = do_list(self.definitions, tw);
|
||||
});
|
||||
DEF(AST_VarDef, function(self, tw) {
|
||||
|
||||
_(AST_VarDef, function(self, tw){
|
||||
self.name = self.name.transform(tw);
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
DEF(AST_Lambda, function(self, tw) {
|
||||
|
||||
_(AST_Destructuring, function(self, tw) {
|
||||
self.names = do_list(self.names, tw);
|
||||
});
|
||||
|
||||
_(AST_Lambda, function(self, tw){
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
self.argnames = do_list(self.argnames, tw);
|
||||
if (self.body instanceof AST_Node) {
|
||||
self.body = self.body.transform(tw);
|
||||
} else {
|
||||
self.body = do_list(self.body, tw);
|
||||
}
|
||||
});
|
||||
DEF(AST_Call, function(self, tw) {
|
||||
|
||||
_(AST_Call, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
DEF(AST_Sequence, function(self, tw) {
|
||||
|
||||
_(AST_Sequence, function(self, tw){
|
||||
self.expressions = do_list(self.expressions, tw);
|
||||
});
|
||||
DEF(AST_Dot, function(self, tw) {
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
DEF(AST_Sub, function(self, tw) {
|
||||
|
||||
_(AST_Sub, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.property = self.property.transform(tw);
|
||||
});
|
||||
DEF(AST_Unary, function(self, tw) {
|
||||
|
||||
_(AST_Yield, function(self, tw){
|
||||
if (self.expression) self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Unary, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
DEF(AST_Binary, function(self, tw) {
|
||||
|
||||
_(AST_Binary, function(self, tw){
|
||||
self.left = self.left.transform(tw);
|
||||
self.right = self.right.transform(tw);
|
||||
});
|
||||
DEF(AST_Conditional, function(self, tw) {
|
||||
|
||||
_(AST_Conditional, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.consequent = self.consequent.transform(tw);
|
||||
self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
DEF(AST_Array, function(self, tw) {
|
||||
|
||||
_(AST_Array, function(self, tw){
|
||||
self.elements = do_list(self.elements, tw);
|
||||
});
|
||||
DEF(AST_Object, function(self, tw) {
|
||||
|
||||
_(AST_Object, function(self, tw){
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
DEF(AST_ObjectProperty, function(self, tw) {
|
||||
|
||||
_(AST_ObjectProperty, function(self, tw){
|
||||
if (self.key instanceof AST_Node) {
|
||||
self.key = self.key.transform(tw);
|
||||
}
|
||||
self.value = self.value.transform(tw);
|
||||
});
|
||||
})(function(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (typeof x === "undefined") {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
if (tw.after) {
|
||||
y = tw.after(x, in_list);
|
||||
if (typeof y !== "undefined") x = y;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return x;
|
||||
|
||||
_(AST_Class, function(self, tw){
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
if (self.extends) self.extends = self.extends.transform(tw);
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
});
|
||||
|
||||
_(AST_Expansion, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Export, function(self, tw){
|
||||
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_TemplateString, function(self, tw) {
|
||||
for (var i = 0; i < self.segments.length; i++) {
|
||||
if (!(self.segments[i] instanceof AST_TemplateSegment)) {
|
||||
self.segments[i] = self.segments[i].transform(tw);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_(AST_PrefixedTemplateString, function(self, tw) {
|
||||
self.template_string = self.template_string.transform(tw);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
231
lib/utils.js
231
lib/utils.js
@@ -43,25 +43,40 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function array_to_hash(a) {
|
||||
var ret = Object.create(null);
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
ret[a[i]] = true;
|
||||
return ret;
|
||||
};
|
||||
|
||||
function slice(a, start) {
|
||||
return Array.prototype.slice.call(a, start || 0);
|
||||
};
|
||||
|
||||
function characters(str) {
|
||||
return str.split("");
|
||||
}
|
||||
};
|
||||
|
||||
function member(name, array) {
|
||||
return array.indexOf(name) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
function find_if(func, array) {
|
||||
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||
}
|
||||
for (var i = 0, n = array.length; i < n; ++i) {
|
||||
if (func(array[i]))
|
||||
return array[i];
|
||||
}
|
||||
};
|
||||
|
||||
function repeat_string(str, i) {
|
||||
if (i <= 0) return "";
|
||||
if (i == 1) return str;
|
||||
var d = repeat_string(str, i >> 1);
|
||||
d += d;
|
||||
return i & 1 ? d + str : d;
|
||||
}
|
||||
if (i & 1) d += str;
|
||||
return d;
|
||||
};
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
@@ -70,7 +85,7 @@ function configure_error_stack(fn) {
|
||||
err.name = this.name;
|
||||
try {
|
||||
throw err;
|
||||
} catch (e) {
|
||||
} catch(e) {
|
||||
return e.stack;
|
||||
}
|
||||
}
|
||||
@@ -80,23 +95,27 @@ function configure_error_stack(fn) {
|
||||
function DefaultsError(msg, defs) {
|
||||
this.message = msg;
|
||||
this.defs = defs;
|
||||
}
|
||||
};
|
||||
DefaultsError.prototype = Object.create(Error.prototype);
|
||||
DefaultsError.prototype.constructor = DefaultsError;
|
||||
DefaultsError.prototype.name = "DefaultsError";
|
||||
configure_error_stack(DefaultsError);
|
||||
|
||||
DefaultsError.croak = function(msg, defs) {
|
||||
throw new DefaultsError(msg, defs);
|
||||
};
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
if (args === true) args = {};
|
||||
if (args === true)
|
||||
args = {};
|
||||
var ret = args || {};
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
||||
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||
}
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
|
||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
||||
for (var i in defs) if (HOP(defs, i)) {
|
||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
function merge(obj, ext) {
|
||||
var count = 0;
|
||||
@@ -105,7 +124,7 @@ function merge(obj, ext) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
@@ -113,8 +132,8 @@ function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var List = (function() {
|
||||
function List(a, f, backwards) {
|
||||
var MAP = (function(){
|
||||
function MAP(a, f, backwards) {
|
||||
var ret = [], top = [], i;
|
||||
function doit() {
|
||||
var val = f(a[i], i);
|
||||
@@ -127,7 +146,8 @@ var List = (function() {
|
||||
} else {
|
||||
top.push(val);
|
||||
}
|
||||
} else if (val !== skip) {
|
||||
}
|
||||
else if (val !== skip) {
|
||||
if (val instanceof Splice) {
|
||||
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
|
||||
} else {
|
||||
@@ -135,8 +155,8 @@ var List = (function() {
|
||||
}
|
||||
}
|
||||
return is_last;
|
||||
}
|
||||
if (Array.isArray(a)) {
|
||||
};
|
||||
if (a instanceof Array) {
|
||||
if (backwards) {
|
||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||
ret.reverse();
|
||||
@@ -144,56 +164,132 @@ var List = (function() {
|
||||
} else {
|
||||
for (i = 0; i < a.length; ++i) if (doit()) break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
||||
}
|
||||
return top.concat(ret);
|
||||
}
|
||||
List.at_top = function(val) { return new AtTop(val); };
|
||||
List.splice = function(val) { return new Splice(val); };
|
||||
List.last = function(val) { return new Last(val); };
|
||||
var skip = List.skip = {};
|
||||
function AtTop(val) { this.v = val; }
|
||||
function Splice(val) { this.v = val; }
|
||||
function Last(val) { this.v = val; }
|
||||
return List;
|
||||
};
|
||||
MAP.at_top = function(val) { return new AtTop(val) };
|
||||
MAP.splice = function(val) { return new Splice(val) };
|
||||
MAP.last = function(val) { return new Last(val) };
|
||||
var skip = MAP.skip = {};
|
||||
function AtTop(val) { this.v = val };
|
||||
function Splice(val) { this.v = val };
|
||||
function Last(val) { this.v = val };
|
||||
return MAP;
|
||||
})();
|
||||
|
||||
function push_uniq(array, el) {
|
||||
if (array.indexOf(el) < 0) return array.push(el);
|
||||
}
|
||||
if (array.indexOf(el) < 0)
|
||||
array.push(el);
|
||||
};
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||
return props && props[p];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function remove(array, el) {
|
||||
var index = array.indexOf(el);
|
||||
if (index >= 0) array.splice(index, 1);
|
||||
}
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
if (array[i] === el) array.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
||||
function makePredicate(words) {
|
||||
if (!Array.isArray(words)) words = words.split(" ");
|
||||
var map = Object.create(null);
|
||||
words.forEach(function(word) {
|
||||
map[word] = true;
|
||||
function mergeSort(array, cmp) {
|
||||
if (array.length < 2) return array.slice();
|
||||
function merge(a, b) {
|
||||
var r = [], ai = 0, bi = 0, i = 0;
|
||||
while (ai < a.length && bi < b.length) {
|
||||
cmp(a[ai], b[bi]) <= 0
|
||||
? r[i++] = a[ai++]
|
||||
: r[i++] = b[bi++];
|
||||
}
|
||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
||||
return r;
|
||||
};
|
||||
function _ms(a) {
|
||||
if (a.length <= 1)
|
||||
return a;
|
||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
||||
left = _ms(left);
|
||||
right = _ms(right);
|
||||
return merge(left, right);
|
||||
};
|
||||
return _ms(array);
|
||||
};
|
||||
|
||||
function set_difference(a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) < 0;
|
||||
});
|
||||
return map;
|
||||
}
|
||||
};
|
||||
|
||||
function set_intersection(a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) >= 0;
|
||||
});
|
||||
};
|
||||
|
||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||
// [1] https://github.com/marijnh/acorn
|
||||
function makePredicate(words) {
|
||||
if (!(words instanceof Array)) words = words.split(" ");
|
||||
var f = "", cats = [];
|
||||
out: for (var i = 0; i < words.length; ++i) {
|
||||
for (var j = 0; j < cats.length; ++j)
|
||||
if (cats[j][0].length == words[i].length) {
|
||||
cats[j].push(words[i]);
|
||||
continue out;
|
||||
}
|
||||
cats.push([words[i]]);
|
||||
}
|
||||
function quote(word) {
|
||||
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
|
||||
switch (s) {
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
return s;
|
||||
});
|
||||
}
|
||||
function compareTo(arr) {
|
||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
||||
f += "switch(str){";
|
||||
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
|
||||
f += "return true}return false;";
|
||||
}
|
||||
// When there are more than three length categories, an outer
|
||||
// switch first dispatches on the lengths, to save on comparisons.
|
||||
if (cats.length > 3) {
|
||||
cats.sort(function(a, b) {return b.length - a.length;});
|
||||
f += "switch(str.length){";
|
||||
for (var i = 0; i < cats.length; ++i) {
|
||||
var cat = cats[i];
|
||||
f += "case " + cat[0].length + ":";
|
||||
compareTo(cat);
|
||||
}
|
||||
f += "}";
|
||||
// Otherwise, simply generate a flat `switch` statement.
|
||||
} else {
|
||||
compareTo(words);
|
||||
}
|
||||
return new Function("str", f);
|
||||
};
|
||||
|
||||
function all(array, predicate) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (!predicate(array[i], i))
|
||||
if (!predicate(array[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
function Dictionary() {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
}
|
||||
};
|
||||
Dictionary.prototype = {
|
||||
set: function(key, val) {
|
||||
if (!this.has(key)) ++this._size;
|
||||
@@ -217,12 +313,6 @@ Dictionary.prototype = {
|
||||
return this;
|
||||
},
|
||||
has: function(key) { return ("$" + key) in this._values },
|
||||
all: function(predicate) {
|
||||
for (var i in this._values)
|
||||
if (!predicate(this._values[i], i.substr(1)))
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
each: function(f) {
|
||||
for (var i in this._values)
|
||||
f(this._values[i], i.substr(1));
|
||||
@@ -236,13 +326,6 @@ Dictionary.prototype = {
|
||||
ret.push(f(this._values[i], i.substr(1)));
|
||||
return ret;
|
||||
},
|
||||
clone: function() {
|
||||
var ret = new Dictionary();
|
||||
for (var i in this._values)
|
||||
ret._values[i] = this._values[i];
|
||||
ret._size = this._size;
|
||||
return ret;
|
||||
},
|
||||
toObject: function() { return this._values }
|
||||
};
|
||||
Dictionary.fromObject = function(obj) {
|
||||
@@ -260,22 +343,20 @@ function HOP(obj, prop) {
|
||||
// a statement.
|
||||
function first_in_statement(stack) {
|
||||
var node = stack.parent(-1);
|
||||
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||
if (p.TYPE == "Call") {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Binary) {
|
||||
if (p.left === node) continue;
|
||||
} else if (p instanceof AST_Conditional) {
|
||||
if (p.condition === node) continue;
|
||||
} else if (p instanceof AST_PropAccess) {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Sequence) {
|
||||
if (p.expressions[0] === node) continue;
|
||||
} else if (p instanceof AST_Statement) {
|
||||
return p.body === node;
|
||||
} else if (p instanceof AST_UnaryPostfix) {
|
||||
if (p.expression === node) continue;
|
||||
}
|
||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
||||
(p instanceof AST_Dot && p.expression === node ) ||
|
||||
(p instanceof AST_Sub && p.expression === node ) ||
|
||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
||||
(p instanceof AST_Binary && p.left === node ) ||
|
||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
||||
{
|
||||
node = p;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
package.json
48
package.json
@@ -1,17 +1,23 @@
|
||||
{
|
||||
"name": "uglify-js",
|
||||
"name": "uglify-es",
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.9.1",
|
||||
"version": "3.0.7",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"maintainers": [
|
||||
"Alex Lam <alexlamsl@gmail.com>",
|
||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||
],
|
||||
"repository": "mishoo/UglifyJS2",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
||||
},
|
||||
"main": "tools/node.js",
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
@@ -23,37 +29,15 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.20.3"
|
||||
"commander": "~2.9.0",
|
||||
"source-map": "~0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~7.1.0",
|
||||
"semver": "~6.3.0"
|
||||
"acorn": "~5.0.3",
|
||||
"mocha": "~2.3.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/compress.js && node test/mocha.js"
|
||||
"test": "node test/run-tests.js"
|
||||
},
|
||||
"keywords": [
|
||||
"cli",
|
||||
"compress",
|
||||
"compressor",
|
||||
"ecma",
|
||||
"ecmascript",
|
||||
"es",
|
||||
"es5",
|
||||
"javascript",
|
||||
"js",
|
||||
"jsmin",
|
||||
"min",
|
||||
"minification",
|
||||
"minifier",
|
||||
"minify",
|
||||
"optimize",
|
||||
"optimizer",
|
||||
"pack",
|
||||
"packer",
|
||||
"parse",
|
||||
"parser",
|
||||
"uglifier",
|
||||
"uglify"
|
||||
]
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
|
||||
}
|
||||
|
||||
@@ -4,45 +4,43 @@
|
||||
"use strict";
|
||||
|
||||
var createHash = require("crypto").createHash;
|
||||
var fetch = require("./fetch");
|
||||
var spawn = require("child_process").spawn;
|
||||
var zlib = require("zlib");
|
||||
var fork = require("child_process").fork;
|
||||
var args = process.argv.slice(2);
|
||||
args.unshift("bin/uglifyjs");
|
||||
if (!args.length) args.push("-mc");
|
||||
args.push("--timings");
|
||||
if (!args.length) {
|
||||
args.push("-mc");
|
||||
}
|
||||
args.push("--stats");
|
||||
var urls = [
|
||||
"https://code.jquery.com/jquery-3.4.1.js",
|
||||
"https://code.angularjs.org/1.7.8/angular.js",
|
||||
"https://unpkg.com/mathjs@6.2.3/dist/math.js",
|
||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.js",
|
||||
"https://code.jquery.com/jquery-3.2.1.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
|
||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.12.2/ember.prod.js",
|
||||
"https://raw.githubusercontent.com/kangax/html-minifier/v4.0.0/dist/htmlminifier.js",
|
||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
||||
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
||||
];
|
||||
var results = {};
|
||||
var remaining = 2 * urls.length;
|
||||
function done() {
|
||||
if (!--remaining) {
|
||||
var failures = [];
|
||||
var sum = { input: 0, output: 0, gzip: 0 };
|
||||
urls.forEach(function(url) {
|
||||
var info = results[url];
|
||||
console.log();
|
||||
console.log(url);
|
||||
console.log(info.log);
|
||||
var elapsed = 0;
|
||||
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
||||
elapsed += 1e-3 * parseInt(time);
|
||||
return "";
|
||||
}));
|
||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||
console.log("Original:", info.input, "bytes");
|
||||
console.log("Uglified:", info.output, "bytes");
|
||||
console.log("GZipped: ", info.gzip, "bytes");
|
||||
console.log("SHA1 sum:", info.sha1);
|
||||
if (info.code) {
|
||||
failures.push(url);
|
||||
}
|
||||
sum.input += info.input;
|
||||
sum.output += info.output;
|
||||
sum.gzip += info.gzip;
|
||||
});
|
||||
if (failures.length) {
|
||||
console.error("Benchmark failed:");
|
||||
@@ -50,13 +48,6 @@ function done() {
|
||||
console.error(url);
|
||||
});
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log();
|
||||
console.log("Subtotal");
|
||||
console.log();
|
||||
console.log("Original:", sum.input, "bytes");
|
||||
console.log("Uglified:", sum.output, "bytes");
|
||||
console.log("GZipped: ", sum.gzip, "bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,25 +55,17 @@ urls.forEach(function(url) {
|
||||
results[url] = {
|
||||
input: 0,
|
||||
output: 0,
|
||||
gzip: 0,
|
||||
log: ""
|
||||
};
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
var uglifyjs = spawn(process.argv[0], args, { silent: true });
|
||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||
res.on("data", function(data) {
|
||||
results[url].input += data.length;
|
||||
}).pipe(uglifyjs.stdin);
|
||||
var sha1 = createHash("sha1");
|
||||
uglifyjs.stdout.on("data", function(data) {
|
||||
results[url].output += data.length;
|
||||
}).pipe(zlib.createGzip({
|
||||
level: zlib.Z_BEST_COMPRESSION
|
||||
})).on("data", function(data) {
|
||||
results[url].gzip += data.length;
|
||||
sha1.update(data);
|
||||
}).on("end", function() {
|
||||
results[url].sha1 = sha1.digest("hex");
|
||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||
results[url].sha1 = data.toString("hex");
|
||||
done();
|
||||
});
|
||||
uglifyjs.stderr.setEncoding("utf8");
|
||||
|
||||
458
test/compress.js
458
test/compress.js
@@ -1,458 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
require("../tools/exit");
|
||||
|
||||
var assert = require("assert");
|
||||
var child_process = require("child_process");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var sandbox = require("./sandbox");
|
||||
var semver = require("semver");
|
||||
var U = require("./node");
|
||||
|
||||
var file = process.argv[2];
|
||||
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||
if (file) {
|
||||
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
|
||||
log("--- {file}", { file: file });
|
||||
var tests = parse_test(path.resolve(dir, file));
|
||||
process.exit(Object.keys(tests).filter(function(name) {
|
||||
return !test_case(tests[name]);
|
||||
}).length);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir).filter(function(name) {
|
||||
return /\.js$/i.test(name);
|
||||
});
|
||||
var failures = 0;
|
||||
var failed_files = Object.create(null);
|
||||
(function next() {
|
||||
var file = files.shift();
|
||||
if (file) {
|
||||
child_process.spawn(process.argv[0], [ process.argv[1], file ], {
|
||||
stdio: [ "ignore", 1, 2 ]
|
||||
}).on("exit", function(code) {
|
||||
if (code) {
|
||||
failures += code;
|
||||
failed_files[file] = code;
|
||||
}
|
||||
next();
|
||||
});
|
||||
} else if (failures) {
|
||||
console.error();
|
||||
console.error("!!! Failed " + failures + " test case(s).");
|
||||
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
function evaluate(code) {
|
||||
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
|
||||
return new Function("return(" + code + ")")();
|
||||
}
|
||||
|
||||
function log() {
|
||||
console.log("%s", tmpl.apply(null, arguments));
|
||||
}
|
||||
|
||||
function make_code(ast, options) {
|
||||
var stream = U.OutputStream(options);
|
||||
ast.print(stream);
|
||||
return stream.get();
|
||||
}
|
||||
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
// TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS2/issues/348
|
||||
try {
|
||||
var ast = U.parse(script, {
|
||||
filename: file
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
var tests = Object.create(null);
|
||||
var tw = new U.TreeWalker(function(node, descend) {
|
||||
if (node instanceof U.AST_LabeledStatement
|
||||
&& tw.parent() instanceof U.AST_Toplevel) {
|
||||
var name = node.label.name;
|
||||
if (name in tests) {
|
||||
throw new Error('Duplicated test name "' + name + '" in ' + file);
|
||||
}
|
||||
tests[name] = get_one_test(name, node.body);
|
||||
return true;
|
||||
}
|
||||
if (!(node instanceof U.AST_Toplevel)) croak(node);
|
||||
});
|
||||
ast.walk(tw);
|
||||
return tests;
|
||||
|
||||
function croak(node) {
|
||||
throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
|
||||
file: file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
code: make_code(node, { beautify: false })
|
||||
}));
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
switch(body.TYPE) {
|
||||
case "String":
|
||||
return body.value;
|
||||
case "Array":
|
||||
return body.elements.map(function(element) {
|
||||
if (element.TYPE !== "String")
|
||||
throw new Error("Should be array of strings");
|
||||
return element.value;
|
||||
}).join("\n");
|
||||
}
|
||||
}
|
||||
throw new Error("Should be string or array of strings");
|
||||
}
|
||||
|
||||
function get_one_test(name, block) {
|
||||
var test = { name: name, options: {} };
|
||||
var tw = new U.TreeWalker(function(node, descend) {
|
||||
if (node instanceof U.AST_Assign) {
|
||||
if (!(node.left instanceof U.AST_SymbolRef)) {
|
||||
croak(node);
|
||||
}
|
||||
var name = node.left.name;
|
||||
test[name] = evaluate(node.right);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U.AST_LabeledStatement) {
|
||||
var label = node.label;
|
||||
assert.ok([
|
||||
"input",
|
||||
"expect",
|
||||
"expect_exact",
|
||||
"expect_warnings",
|
||||
"expect_stdout",
|
||||
"node_version",
|
||||
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
test[label.name] = read_string(stat);
|
||||
} else if (label.name == "expect_stdout") {
|
||||
var body = stat.body;
|
||||
if (body instanceof U.AST_Boolean) {
|
||||
test[label.name] = body.value;
|
||||
} else if (body instanceof U.AST_Call) {
|
||||
var ctor = global[body.expression.name];
|
||||
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
return node.value;
|
||||
}));
|
||||
} else {
|
||||
test[label.name] = read_string(stat) + "\n";
|
||||
}
|
||||
} else {
|
||||
test[label.name] = stat;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
block.walk(tw);
|
||||
return test;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (options.compress) [
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
].forEach(function(name) {
|
||||
if (name in orig_options) {
|
||||
options.compress[name] = orig_options[name];
|
||||
}
|
||||
});
|
||||
var options_formatted = JSON.stringify(options, null, 4);
|
||||
var result = U.minify(input_code, options);
|
||||
if (result.error) {
|
||||
log([
|
||||
"!!! failed input reminify",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OPTIONS---",
|
||||
"{options}",
|
||||
"--ERROR---",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
options: options_formatted,
|
||||
error: result.error,
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
var toplevel = sandbox.has_toplevel(options);
|
||||
var expected = stdout[toplevel ? 1 : 0];
|
||||
var actual = run_code(result.code, toplevel);
|
||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||
actual = expected;
|
||||
}
|
||||
if (!sandbox.same_stdout(expected, actual)) {
|
||||
log([
|
||||
"!!! failed running reminified input",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OPTIONS---",
|
||||
"{options}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
options: options_formatted,
|
||||
output: result.code,
|
||||
expected_type: typeof expected == "string" ? "STDOUT" : "ERROR",
|
||||
expected: expected,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function run_code(code, toplevel) {
|
||||
var result = sandbox.run_code(code, toplevel);
|
||||
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
||||
}
|
||||
|
||||
function test_case(test) {
|
||||
log(" Running test [{name}]", { name: test.name });
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||
} else {
|
||||
expect = test.expect_exact;
|
||||
}
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input_formatted = make_code(test.input, {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3,
|
||||
});
|
||||
try {
|
||||
U.parse(input_code);
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Cannot parse input",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"--PARSE ERROR--",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var warnings_emitted = [];
|
||||
if (test.expect_warnings) {
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
U.AST_Node.log_function(function(text) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
}
|
||||
if (test.rename) {
|
||||
input.figure_out_scope(test.mangle);
|
||||
input.expand_names(test.mangle);
|
||||
}
|
||||
var cmp = new U.Compressor(test.options, true);
|
||||
var output = cmp.compress(input);
|
||||
output.figure_out_scope(test.mangle);
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (test.mangle.properties) {
|
||||
output = U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
}
|
||||
output = make_code(output, output_options);
|
||||
if (expect != output) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"---EXPECTED---",
|
||||
"{expected}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
expected: expect
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// expect == output
|
||||
try {
|
||||
U.parse(output);
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"--REPARSE ERROR--",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (test.expect_warnings) {
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED WARNINGS---",
|
||||
"{expected_warnings}",
|
||||
"---ACTUAL WARNINGS---",
|
||||
"{actual_warnings}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = [ run_code(input_code), run_code(input_code, true) ];
|
||||
var toplevel = sandbox.has_toplevel({
|
||||
compress: test.options,
|
||||
mangle: test.mangle
|
||||
});
|
||||
var actual = stdout[toplevel ? 1 : 0];
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = actual;
|
||||
}
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! Invalid input or expected stdout",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = run_code(output, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function tmpl() {
|
||||
return U.string_template.apply(null, arguments);
|
||||
}
|
||||
|
||||
function to_toplevel(input, mangle_options) {
|
||||
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||
var directive = true;
|
||||
var offset = input.start.line;
|
||||
var tokens = [];
|
||||
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||
if (!directive || node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
} else {
|
||||
directive = false;
|
||||
}
|
||||
})));
|
||||
toplevel.figure_out_scope(mangle_options);
|
||||
return toplevel;
|
||||
}
|
||||
@@ -1,778 +0,0 @@
|
||||
replace_index: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, b) {
|
||||
var c = a;
|
||||
var d = b;
|
||||
var a = "foo";
|
||||
b++;
|
||||
a = "moo";
|
||||
b *= 2;
|
||||
console.log(a, b, c, d, a, b);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "moo 86 bar 42 moo 86"
|
||||
}
|
||||
|
||||
modified_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "foo 43 bar 42 moo 84"
|
||||
}
|
||||
|
||||
duplicate_argname: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], arguments[1], arguments[2]);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], b, a);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect_stdout: "bar 42 foo 42 bar"
|
||||
}
|
||||
|
||||
issue_3273: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_keep_fargs_false: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"use strict";
|
||||
arguments[0]++;
|
||||
console.log(arguments[0]);
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
(function(argument_0) {
|
||||
"use strict";
|
||||
argument_0++;
|
||||
console.log(argument_0);
|
||||
})(0);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3273_keep_fargs_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"use strict";
|
||||
arguments[0]++;
|
||||
console.log(arguments[0]);
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
(function(argument_0) {
|
||||
"use strict";
|
||||
argument_0++;
|
||||
console.log(argument_0);
|
||||
})(0);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3282_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_1_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return function() {
|
||||
return arguments[0];
|
||||
};
|
||||
}().length);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return function() {
|
||||
return arguments[0];
|
||||
};
|
||||
}().length);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_3420_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_3: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_4: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
console.log(arguments[0]);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
!function(argument_0) {
|
||||
console.log(argument_0);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3420_5: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
!function() {
|
||||
console.log(arguments[0]);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
!function(argument_0) {
|
||||
console.log(argument_0);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3420_6: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3420_7: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// NOTE trailing comma doesn't contribute to length of an array
|
||||
// That also means the array changes length if previous element is a hole too and got cut off
|
||||
holes_and_undefined: {
|
||||
input: {
|
||||
w = [1,,];
|
||||
@@ -15,10 +17,9 @@ holes_and_undefined: {
|
||||
|
||||
constant_join: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
unsafe: true,
|
||||
}
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
input: {
|
||||
var a = [ "foo", "bar", "baz" ].join("");
|
||||
var a1 = [ "foo", "bar", "baz" ].join();
|
||||
@@ -65,10 +66,9 @@ constant_join: {
|
||||
|
||||
constant_join_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
unsafe: true,
|
||||
}
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
input: {
|
||||
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
|
||||
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
|
||||
@@ -93,14 +93,85 @@ constant_join_2: {
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_variable_as_last_element: {
|
||||
input: {
|
||||
var values = [4, 5, 6];
|
||||
var a = [1, 2, 3, ...values];
|
||||
}
|
||||
expect: {
|
||||
var values = [4, 5, 6];
|
||||
var a = [1, 2, 3, ...values];
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_variable_in_middle: {
|
||||
input: {
|
||||
var values = [4, 5, 6];
|
||||
var a = [1, 2, 3, ...values, 7,,,];
|
||||
}
|
||||
expect: {
|
||||
var values = [4, 5, 6];
|
||||
var a = [1, 2, 3, ...values, 7,,,];
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_variable_at_front: {
|
||||
input: {
|
||||
var values = [1, 2, 3];
|
||||
var a = [...values, 4, 5, 6];
|
||||
}
|
||||
expect: {
|
||||
var values = [1, 2, 3];
|
||||
var a = [...values, 4, 5, 6];
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_variable_at_front_after_elisions: {
|
||||
input: {
|
||||
var values = [1, 2, 3];
|
||||
var a = [,,,...values, 4, 5, 6];
|
||||
}
|
||||
expect: {
|
||||
var values = [1, 2, 3];
|
||||
var a = [,,,...values, 4, 5, 6];
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_array_at_end: {
|
||||
input: {
|
||||
var a = [1, 2, ...[4, 5, 6]];
|
||||
}
|
||||
expect: {
|
||||
var a = [1, 2, ...[4, 5, 6]];
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_logical_expression_at_end: {
|
||||
options = { evaluate: true }
|
||||
input: {
|
||||
var a = [1, 2, 3, ...[2+2]]
|
||||
}
|
||||
expect: {
|
||||
var a = [1, 2, 3, ...[4]]
|
||||
}
|
||||
}
|
||||
|
||||
spread_with_logical_expression_at_middle: {
|
||||
options = { evaluate: true }
|
||||
input: {
|
||||
var a = [1, 1, ...[1+1, 1+2, 2+3], 8]
|
||||
}
|
||||
expect: {
|
||||
var a = [1, 1, ...[2, 3, 5], 8]
|
||||
}
|
||||
}
|
||||
|
||||
constant_join_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
unsafe: true,
|
||||
}
|
||||
evaluate: true,
|
||||
};
|
||||
input: {
|
||||
var foo, bar, baz;
|
||||
var a = [ null ].join();
|
||||
var b = [ , ].join();
|
||||
var c = [ , 1, , 3 ].join();
|
||||
@@ -115,7 +186,6 @@ constant_join_3: {
|
||||
var l = [ foo, bar + "baz" ].join("");
|
||||
}
|
||||
expect: {
|
||||
var foo, bar, baz;
|
||||
var a = "";
|
||||
var b = "";
|
||||
var c = ",1,,3";
|
||||
@@ -133,224 +203,50 @@ constant_join_3: {
|
||||
|
||||
for_loop: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
unsafe : true,
|
||||
unused : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true
|
||||
};
|
||||
input: {
|
||||
function f0() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
for (var i = 0; i < a.length; i++)
|
||||
b += a[i];
|
||||
return b;
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
console.log(a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
for (var i = 0, len = a.length; i < len; i++)
|
||||
b += a[i];
|
||||
return b;
|
||||
for (var i = 0, len = a.length; i < len; i++) {
|
||||
console.log(a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a = [1, 2, 3];
|
||||
for (var i = 0; i < a.length; i++)
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
a[i]++;
|
||||
return a[2];
|
||||
}
|
||||
console.log(f0(), f1(), f2());
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f0() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
for (var i = 0; i < 3; i++)
|
||||
b += a[i];
|
||||
return b;
|
||||
console.log(a[i]);
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
for (var i = 0; i < 3; i++)
|
||||
b += a[i];
|
||||
return b;
|
||||
console.log(a[i]);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a = [1, 2, 3];
|
||||
for (var i = 0; i < a.length; i++)
|
||||
a[i]++;
|
||||
return a[2];
|
||||
}
|
||||
console.log(f0(), f1(), f2());
|
||||
}
|
||||
expect_stdout: "6 6 4"
|
||||
}
|
||||
|
||||
index: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ 1, 2 ];
|
||||
console.log(a[0], a[1]);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 2);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
length: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ 1, 2 ];
|
||||
console.log(a.length);
|
||||
}
|
||||
expect: {
|
||||
console.log(2);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
index_length: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ 1, 2 ];
|
||||
console.log(a[0], a.length);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 2);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
constructor_bad: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
|
||||
]
|
||||
}
|
||||
|
||||
constructor_good: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
console.log(Array());
|
||||
console.log(Array(0));
|
||||
console.log(Array(1));
|
||||
console.log(Array(6));
|
||||
console.log(Array(7));
|
||||
console.log(Array(1, 2));
|
||||
console.log(Array(false));
|
||||
console.log(Array("foo"));
|
||||
console.log(Array(Array));
|
||||
console.log(new Array());
|
||||
console.log(new Array(0));
|
||||
console.log(new Array(1));
|
||||
console.log(new Array(6));
|
||||
console.log(new Array(7));
|
||||
console.log(new Array(1, 2));
|
||||
console.log(new Array(false));
|
||||
console.log(new Array("foo"));
|
||||
console.log(new Array(Array));
|
||||
}
|
||||
expect: {
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
137
test/compress/arrow.js
Normal file
137
test/compress/arrow.js
Normal file
@@ -0,0 +1,137 @@
|
||||
arrow_functions_without_body: {
|
||||
input: {
|
||||
var a1 = () => 42;
|
||||
var a2 = (p) => p;
|
||||
var a3 = p => p;
|
||||
var a4 = (...p) => p;
|
||||
var a5 = (b, c) => b + c;
|
||||
var a6 = (b, ...c) => b + c[0];
|
||||
var a7 = (...b) => b.join();
|
||||
}
|
||||
expect: {
|
||||
var a1 = () => 42;
|
||||
var a2 = (p) => p;
|
||||
var a3 = p => p;
|
||||
var a4 = (...p) => p;
|
||||
var a5 = (b, c) => b + c;
|
||||
var a6 = (b, ...c) => b + c[0];
|
||||
var a7 = (...b) => b.join();
|
||||
}
|
||||
}
|
||||
|
||||
arrow_functions_with_body: {
|
||||
input: {
|
||||
var a1 = () => {
|
||||
var a = 42 * Math.random();
|
||||
return a;
|
||||
};
|
||||
var a2 = (p) => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a3 = p => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a4 = (...p) => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a5 = (b, c) => {
|
||||
var result = b * c + b / c;
|
||||
return result
|
||||
};
|
||||
var a6 = (b, ...c) => {
|
||||
var result = b;
|
||||
for (var i = 0; i < c.length; i++)
|
||||
result += c[i];
|
||||
return result
|
||||
};
|
||||
var a7 = (...b) => {
|
||||
b.join();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a1 = () => {
|
||||
var a = 42 * Math.random();
|
||||
return a;
|
||||
};
|
||||
var a2 = (p) => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a3 = p => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a4 = (...p) => {
|
||||
var a = Math.random() * p;
|
||||
return a;
|
||||
};
|
||||
var a5 = (b, c) => {
|
||||
var result = b * c + b / c;
|
||||
return result
|
||||
};
|
||||
var a6 = (b, ...c) => {
|
||||
var result = b;
|
||||
for (var i = 0; i < c.length; i++)
|
||||
result += c[i];
|
||||
return result
|
||||
};
|
||||
var a7 = (...b) => {
|
||||
b.join();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
arrow_function_with_single_parameter_with_default: {
|
||||
input: {
|
||||
var foo = (a = 0) => doSomething(a);
|
||||
}
|
||||
expect_exact: "var foo=(a=0)=>doSomething(a);"
|
||||
}
|
||||
|
||||
arrow_binding_pattern: {
|
||||
input: {
|
||||
var foo = ([]) => "foo";
|
||||
var bar = ({}) => "bar";
|
||||
var with_default = (foo = "default") => foo;
|
||||
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
|
||||
var array_after_spread = (...[foo]) => foo;
|
||||
var array_after_spread = (...{foo}) => foo;
|
||||
var computed = ({ [compute()]: x }) => {};
|
||||
var array_hole = ([, , ...x] = [1, 2]) => {};
|
||||
var object_trailing_elision = ({foo,}) => {};
|
||||
var spread_empty_array = (...[]) => "foo";
|
||||
var spread_empty_object = (...{}) => "foo";
|
||||
}
|
||||
expect: {
|
||||
var foo = ([]) => "foo";
|
||||
var bar = ({}) => "bar";
|
||||
var with_default = (foo = "default") => foo;
|
||||
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
|
||||
var array_after_spread = (...[foo]) => foo;
|
||||
var array_after_spread = (...{foo}) => foo;
|
||||
var computed = ({ [compute()]: x }) => {};
|
||||
var array_hole = ([, , ...x] = [1, 2]) => {};
|
||||
var object_trailing_elision = ({foo,}) => {};
|
||||
var spread_empty_array = (...[]) => "foo";
|
||||
var spread_empty_object = (...{}) => "foo";
|
||||
}
|
||||
}
|
||||
|
||||
arrow_binding_pattern_strict: {
|
||||
input: {
|
||||
var foo = ([,]) => "foo";
|
||||
}
|
||||
expect_exact: 'var foo=([,])=>"foo";'
|
||||
}
|
||||
|
||||
arrow_with_regexp: {
|
||||
input: {
|
||||
num => /\d{11,14}/.test( num )
|
||||
}
|
||||
expect: {
|
||||
num => /\d{11,14}/.test( num )
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||
}
|
||||
|
||||
ascii_only_false: {
|
||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
asm_mixed: {
|
||||
options = {
|
||||
assignments: true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
drop_debugger : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
negate_iife : true
|
||||
};
|
||||
input: {
|
||||
// adapted from http://asmjs.org/spec/latest/
|
||||
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
@@ -96,7 +96,7 @@ asm_mixed: {
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
return start |= 0, end |= 0, +exp(logSum(start, end) / (end - start | 0));
|
||||
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
|
||||
}
|
||||
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
||||
return { geometricMean: geometricMean };
|
||||
@@ -104,131 +104,3 @@ asm_mixed: {
|
||||
}
|
||||
}
|
||||
|
||||
asm_toplevel: {
|
||||
options = {}
|
||||
input: {
|
||||
"use asm";
|
||||
0.0;
|
||||
function f() {
|
||||
0.0;
|
||||
(function(){
|
||||
0.0;
|
||||
});
|
||||
}
|
||||
0.0;
|
||||
}
|
||||
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
||||
}
|
||||
|
||||
asm_function_expression: {
|
||||
options = {}
|
||||
input: {
|
||||
0.0;
|
||||
var a = function() {
|
||||
"use asm";
|
||||
0.0;
|
||||
}
|
||||
function f() {
|
||||
0.0;
|
||||
return function(){
|
||||
"use asm";
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
}
|
||||
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
||||
}
|
||||
|
||||
asm_nested_functions: {
|
||||
options = {}
|
||||
input: {
|
||||
0.0;
|
||||
function a() {
|
||||
"use asm";
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
function b() {
|
||||
0.0;
|
||||
function c(){
|
||||
"use asm";
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
function d(){
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
}
|
||||
0.0;
|
||||
}
|
||||
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
||||
}
|
||||
|
||||
issue_3636_1: {
|
||||
mangle = {}
|
||||
input: {
|
||||
function n(stdlib, foreign, buffer) {
|
||||
"use asm";
|
||||
function add(x, y) {
|
||||
x = x | 0;
|
||||
y = y | 0;
|
||||
return x + y | 0;
|
||||
}
|
||||
return {
|
||||
add: add
|
||||
};
|
||||
}
|
||||
console.log(new n().add("foo", 42));
|
||||
}
|
||||
expect: {
|
||||
function n(o, e, u) {
|
||||
"use asm";
|
||||
function d(n, o) {
|
||||
n = n | 0;
|
||||
o = o | 0;
|
||||
return n + o | 0;
|
||||
}
|
||||
return {
|
||||
add: d
|
||||
};
|
||||
}
|
||||
console.log(new n().add("foo", 42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_3636_2: {
|
||||
mangle = {}
|
||||
input: {
|
||||
var n = function(stdlib, foreign, buffer) {
|
||||
"use asm";
|
||||
function add(x, y) {
|
||||
x = x | 0;
|
||||
y = y | 0;
|
||||
return x + y | 0;
|
||||
}
|
||||
return {
|
||||
add: add
|
||||
};
|
||||
};
|
||||
console.log(new n().add("foo", 42));
|
||||
}
|
||||
expect: {
|
||||
var n = function(n, o, e) {
|
||||
"use asm";
|
||||
function r(n, o) {
|
||||
n = n | 0;
|
||||
o = o | 0;
|
||||
return n + o | 0;
|
||||
}
|
||||
return {
|
||||
add: r
|
||||
};
|
||||
};
|
||||
console.log(new n().add("foo", 42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
op_equals_left_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -61,7 +60,6 @@ op_equals_left_local_var: {
|
||||
|
||||
op_equals_right_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -125,7 +123,6 @@ op_equals_right_local_var: {
|
||||
}
|
||||
op_equals_left_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -182,7 +179,6 @@ op_equals_left_global_var: {
|
||||
|
||||
op_equals_right_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -240,170 +236,3 @@ op_equals_right_global_var: {
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
|
||||
increment_decrement_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
increment_decrement_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a = a + 1;
|
||||
a = a - 1;
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_3375_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect_stdout: "string object1"
|
||||
}
|
||||
|
||||
issue_3375_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b -= 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = --b;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect_stdout: "number NaN"
|
||||
}
|
||||
|
||||
issue_3427: {
|
||||
options = {
|
||||
assignments: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a;
|
||||
a || (a = {});
|
||||
})();
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3429_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b && (b = a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b = b && (a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3429_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(function(b) {
|
||||
b || (b = a = "FAIL");
|
||||
})(42);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
(function(b) {
|
||||
b = b || (a = "FAIL");
|
||||
})(42);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
177
test/compress/block-scope.js
Normal file
177
test/compress/block-scope.js
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
let_statement: {
|
||||
input: {
|
||||
let x = 6;
|
||||
}
|
||||
expect_exact: "let x=6;"
|
||||
}
|
||||
|
||||
do_not_hoist_let: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
};
|
||||
input: {
|
||||
function x() {
|
||||
if (FOO) {
|
||||
let let1;
|
||||
let let2;
|
||||
var var1;
|
||||
var var2;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
var var1, var2;
|
||||
if (FOO) {
|
||||
let let1;
|
||||
let let2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_not_remove_anon_blocks_if_they_have_decls: {
|
||||
input: {
|
||||
function x() {
|
||||
{
|
||||
let x;
|
||||
}
|
||||
{
|
||||
var x;
|
||||
}
|
||||
{
|
||||
const y;
|
||||
class Zee {};
|
||||
}
|
||||
}
|
||||
{
|
||||
let y;
|
||||
}
|
||||
{
|
||||
var y;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x(){
|
||||
{
|
||||
let x
|
||||
}
|
||||
var x;
|
||||
{
|
||||
const y;
|
||||
class Zee {}
|
||||
}
|
||||
}
|
||||
{
|
||||
let y
|
||||
}
|
||||
var y;
|
||||
}
|
||||
}
|
||||
|
||||
remove_unused_in_global_block: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
let x;
|
||||
const y;
|
||||
class Zee {};
|
||||
var w;
|
||||
}
|
||||
let ex;
|
||||
const why;
|
||||
class Zed {};
|
||||
var wut;
|
||||
console.log(x, y, Zee);
|
||||
}
|
||||
expect: {
|
||||
var w;
|
||||
let ex;
|
||||
const why;
|
||||
class Zed {};
|
||||
var wut;
|
||||
console.log(x, y, Zee);
|
||||
}
|
||||
}
|
||||
|
||||
regression_block_scope_resolves: {
|
||||
mangle = { };
|
||||
options = {
|
||||
dead_code: false
|
||||
};
|
||||
input: {
|
||||
(function () {
|
||||
if(1) {
|
||||
let x;
|
||||
const y;
|
||||
class Zee {};
|
||||
}
|
||||
if(1) {
|
||||
let ex;
|
||||
const why;
|
||||
class Zi {};
|
||||
}
|
||||
console.log(x, y, Zee, ex, why, Zi);
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function () {
|
||||
if (1) {
|
||||
let o;
|
||||
const n;
|
||||
class c {};
|
||||
}
|
||||
if (1) {
|
||||
let o;
|
||||
const n;
|
||||
class c {};
|
||||
}
|
||||
console.log(x, y, Zee, ex, why, Zi);
|
||||
}());
|
||||
}
|
||||
}
|
||||
|
||||
switch_block_scope_mangler: {
|
||||
mangle = {}
|
||||
input: {
|
||||
var fn = function(code) {
|
||||
switch (code) {
|
||||
case 1:
|
||||
let apple = code + 1;
|
||||
let dog = code + 4;
|
||||
console.log(apple, dog);
|
||||
break;
|
||||
case 2:
|
||||
let banana = code + 2;
|
||||
console.log(banana);
|
||||
break;
|
||||
default:
|
||||
let cat = code + 3;
|
||||
console.log(cat);
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var fn = function(o) {
|
||||
switch (o) {
|
||||
case 1:
|
||||
let e = o + 1
|
||||
let c = o + 4;
|
||||
console.log(e, c);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
let l = o + 2;
|
||||
console.log(l);
|
||||
break;
|
||||
|
||||
default:
|
||||
let a = o + 3;
|
||||
console.log(a);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
iife_boolean_context: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return Object(1) || false;
|
||||
}() ? "PASS" : "FAIL");
|
||||
console.log(function() {
|
||||
return [].length || true;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return Object(1);
|
||||
}() ? "PASS" : "FAIL");
|
||||
console.log(function() {
|
||||
return [].length, 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Dropping side-effect-free || [test/compress/booleans.js:2,19]",
|
||||
"WARN: Boolean || always true [test/compress/booleans.js:5,19]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3465_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3465_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
if (!a) console.log(f(42));
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
if (!a) console.log(f(42));
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: [
|
||||
"number",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3465_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
passes: 2,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2737_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(bar) {
|
||||
for (;bar();) break;
|
||||
})(function qux() {
|
||||
return console.log("PASS"), qux;
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(bar) {
|
||||
for (;bar();) break;
|
||||
})(function() {
|
||||
return console.log("PASS"), 1;
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3658: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
console || f();
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {
|
||||
console || f();
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3690: {
|
||||
options = {
|
||||
booleans: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return function() {
|
||||
return a = [ this ];
|
||||
}() ? "PASS" : "FAIL";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return function() {
|
||||
return 1;
|
||||
}() ? "PASS" : "FAIL";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
76
test/compress/comparing.js
Normal file
76
test/compress/comparing.js
Normal file
@@ -0,0 +1,76 @@
|
||||
keep_comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: false
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
keep_comparisons_with_unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: true
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj2 >= obj1;
|
||||
var result2 = obj2 > obj1;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
}
|
||||
@@ -1,442 +0,0 @@
|
||||
comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj2 <= obj1;
|
||||
var result4 = obj2 < obj1;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
obj1 <= obj2 ? f1() : g1();
|
||||
obj1 < obj2 ? f2() : g2();
|
||||
obj1 >= obj2 ? f3() : g3();
|
||||
obj1 > obj2 ? f4() : g4();
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
(obj2 < obj1 ? g1 : f1)();
|
||||
(obj1 < obj2 ? f2 : g2)();
|
||||
(obj1 < obj2 ? g3 : f3)();
|
||||
(obj2 < obj1 ? f4 : g4)();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a === a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c !== b.c;
|
||||
}
|
||||
expect: {
|
||||
a == a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c != b.c;
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(f != f, o === o);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(false, true);
|
||||
}
|
||||
expect_stdout: "false true"
|
||||
}
|
||||
|
||||
issue_2857_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a) {
|
||||
a === undefined || a === null;
|
||||
a === undefined || a !== null;
|
||||
a !== undefined || a === null;
|
||||
a !== undefined || a !== null;
|
||||
a === undefined && a === null;
|
||||
a === undefined && a !== null;
|
||||
a !== undefined && a === null;
|
||||
a !== undefined && a !== null;
|
||||
}
|
||||
function f2(a) {
|
||||
a === null || a === undefined;
|
||||
a === null || a !== undefined;
|
||||
a !== null || a === undefined;
|
||||
a !== null || a !== undefined;
|
||||
a === null && a === undefined;
|
||||
a === null && a !== undefined;
|
||||
a !== null && a === undefined;
|
||||
a !== null && a !== undefined;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1(a) {
|
||||
null == a;
|
||||
void 0 === a || null !== a;
|
||||
void 0 !== a || null === a;
|
||||
void 0 !== a || null !== a;
|
||||
void 0 === a && null === a;
|
||||
void 0 === a && null !== a;
|
||||
void 0 !== a && null === a;
|
||||
null != a;
|
||||
}
|
||||
function f2(a) {
|
||||
null == a;
|
||||
null === a || void 0 !== a;
|
||||
null !== a || void 0 === a;
|
||||
null !== a || void 0 !== a;
|
||||
null === a && void 0 === a;
|
||||
null === a && void 0 !== a;
|
||||
null !== a && void 0 === a;
|
||||
null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null || p;
|
||||
a === undefined || a !== null || p;
|
||||
a !== undefined || a === null || p;
|
||||
a !== undefined || a !== null || p;
|
||||
a === undefined && a === null || p;
|
||||
a === undefined && a !== null || p;
|
||||
a !== undefined && a === null || p;
|
||||
a !== undefined && a !== null || p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
null == a || p;
|
||||
void 0 === a || null !== a || p;
|
||||
void 0 !== a || null === a || p;
|
||||
void 0 !== a || null !== a || p;
|
||||
void 0 === a && null === a || p;
|
||||
void 0 === a && null !== a || p;
|
||||
void 0 !== a && null === a || p;
|
||||
null != a || p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_3: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null && p;
|
||||
a === undefined || a !== null && p;
|
||||
a !== undefined || a === null && p;
|
||||
a !== undefined || a !== null && p;
|
||||
a === undefined && a === null && p;
|
||||
a === undefined && a !== null && p;
|
||||
a !== undefined && a === null && p;
|
||||
a !== undefined && a !== null && p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
void 0 === a || null === a && p;
|
||||
void 0 === a || null !== a && p;
|
||||
void 0 !== a || null === a && p;
|
||||
void 0 !== a || null !== a && p;
|
||||
void 0 === a && null === a && p;
|
||||
void 0 === a && null !== a && p;
|
||||
void 0 !== a && null === a && p;
|
||||
null != a && p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_4: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p || a === undefined || a === null;
|
||||
p || a === undefined || a !== null;
|
||||
p || a !== undefined || a === null;
|
||||
p || a !== undefined || a !== null;
|
||||
p || a === undefined && a === null;
|
||||
p || a === undefined && a !== null;
|
||||
p || a !== undefined && a === null;
|
||||
p || a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p || null == a;
|
||||
p || void 0 === a || null !== a;
|
||||
p || void 0 !== a || null === a;
|
||||
p || void 0 !== a || null !== a;
|
||||
p || void 0 === a && null === a;
|
||||
p || void 0 === a && null !== a;
|
||||
p || void 0 !== a && null === a;
|
||||
p || null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_5: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p && a === undefined || a === null;
|
||||
p && a === undefined || a !== null;
|
||||
p && a !== undefined || a === null;
|
||||
p && a !== undefined || a !== null;
|
||||
p && a === undefined && a === null;
|
||||
p && a === undefined && a !== null;
|
||||
p && a !== undefined && a === null;
|
||||
p && a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p && void 0 === a || null === a;
|
||||
p && void 0 === a || null !== a;
|
||||
p && void 0 !== a || null === a;
|
||||
p && void 0 !== a || null !== a;
|
||||
p && void 0 === a && null === a;
|
||||
p && void 0 === a && null !== a;
|
||||
p && void 0 !== a && null === a;
|
||||
p && null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (({}).b === undefined || {}.b === null)
|
||||
return a.b !== undefined && a.b !== null;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (null == {}.b)
|
||||
return void 0 !== a.b && null !== a.b;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
|
||||
}
|
||||
expect: {
|
||||
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_number_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(Math.acos(42) !== "foo".charCodeAt(4));
|
||||
}
|
||||
expect: {
|
||||
console.log(Math.acos(42) != "foo".charCodeAt(4));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_var: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] === c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] == c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
is_defined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function a() {
|
||||
return void 0 === a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function a() {
|
||||
return a, false;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
expect_warnings: [
|
||||
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
|
||||
]
|
||||
}
|
||||
|
||||
unsafe_indexOf: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = Object.keys({ foo: 42 });
|
||||
if (a.indexOf("bar") < 0) console.log("PASS");
|
||||
if (0 > a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("foo") >= 0) console.log("PASS");
|
||||
if (0 <= a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("foo") > -1) console.log("PASS");
|
||||
if (-1 < a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("bar") == -1) console.log("PASS");
|
||||
if (-1 == a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("bar") === -1) console.log("PASS");
|
||||
if (-1 === a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("foo") != -1) console.log("PASS");
|
||||
if (-1 != a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("foo") !== -1) console.log("PASS");
|
||||
if (-1 !== a.indexOf("foo")) console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = Object.keys({ foo: 42 });
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3413: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var b;
|
||||
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var b;
|
||||
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
concat_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
evaluate: true
|
||||
};
|
||||
input: {
|
||||
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
|
||||
var b = "foo" + 1 + x() + 2 + "boo";
|
||||
@@ -21,14 +21,12 @@ concat_1: {
|
||||
var c = 1 + x() + 2 + "boo";
|
||||
var d = 1 + x() + 2 + 3 + "boo";
|
||||
var e = 1 + x() + 2 + "X3boo";
|
||||
var f = "\x00360\x008\0";
|
||||
var f = "\x00360\08\0";
|
||||
}
|
||||
}
|
||||
|
||||
concat_2: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + (2 + 3),
|
||||
@@ -57,9 +55,7 @@ concat_2: {
|
||||
}
|
||||
|
||||
concat_3: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + 2 + (3 + 4 + 5),
|
||||
@@ -88,9 +84,7 @@ concat_3: {
|
||||
}
|
||||
|
||||
concat_4: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + "2" + (3 + 4 + 5),
|
||||
@@ -119,9 +113,7 @@ concat_4: {
|
||||
}
|
||||
|
||||
concat_5: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
"1" + 2 + (3 + 4 + 5),
|
||||
@@ -150,9 +142,7 @@ concat_5: {
|
||||
}
|
||||
|
||||
concat_6: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
"1" + "2" + (3 + 4 + 5),
|
||||
@@ -181,9 +171,6 @@ concat_6: {
|
||||
}
|
||||
|
||||
concat_7: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
"" + 1,
|
||||
@@ -210,9 +197,6 @@ concat_7: {
|
||||
}
|
||||
|
||||
concat_8: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
1 + "",
|
||||
@@ -237,20 +221,3 @@ concat_8: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3689: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return a + ("" + (a[0] = 0));
|
||||
}([]));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return a + ("" + (a[0] = 0));
|
||||
}([]));
|
||||
}
|
||||
expect_stdout: "00"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ifs_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
if (foo) bar();
|
||||
if (!foo); else bar();
|
||||
@@ -18,8 +18,8 @@ ifs_1: {
|
||||
|
||||
ifs_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
if (foo) {
|
||||
x();
|
||||
@@ -41,18 +41,18 @@ ifs_2: {
|
||||
}
|
||||
expect: {
|
||||
foo ? x() : bar ? y() : baz && z();
|
||||
(foo ? x : bar ? y : baz ? z : t)();
|
||||
foo ? x() : bar ? y() : baz ? z() : t();
|
||||
}
|
||||
}
|
||||
|
||||
ifs_3_should_warn: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
var x, y;
|
||||
if (x && !(x + "1") && y) { // 1
|
||||
@@ -78,8 +78,8 @@ ifs_3_should_warn: {
|
||||
|
||||
ifs_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
if (foo && bar) {
|
||||
x(foo)[10].bar.baz = something();
|
||||
@@ -95,10 +95,10 @@ ifs_4: {
|
||||
|
||||
ifs_5: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
};
|
||||
input: {
|
||||
function f() {
|
||||
if (foo) return;
|
||||
@@ -132,9 +132,9 @@ ifs_5: {
|
||||
|
||||
ifs_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
}
|
||||
comparisons: true
|
||||
};
|
||||
input: {
|
||||
var x, y;
|
||||
if (!foo && !bar && !baz && !boo) {
|
||||
@@ -161,74 +161,52 @@ ifs_6: {
|
||||
}
|
||||
}
|
||||
|
||||
ifs_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (A); else;
|
||||
if (A) while (B); else;
|
||||
if (A); else while (C);
|
||||
if (A) while (B); else while (C);
|
||||
}
|
||||
expect: {
|
||||
A;
|
||||
if (A) while (B);
|
||||
if (!A) while (C);
|
||||
if (A) while (B); else while (C);
|
||||
}
|
||||
}
|
||||
|
||||
cond_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
function foo(do_something, some_condition) {
|
||||
if (some_condition) {
|
||||
var do_something; // if undeclared it's assumed to have side-effects
|
||||
if (some_condition()) {
|
||||
do_something(x);
|
||||
} else {
|
||||
do_something(y);
|
||||
}
|
||||
if (some_condition) {
|
||||
if (some_condition()) {
|
||||
side_effects(x);
|
||||
} else {
|
||||
side_effects(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(do_something, some_condition) {
|
||||
do_something(some_condition ? x : y);
|
||||
some_condition ? side_effects(x) : side_effects(y);
|
||||
}
|
||||
var do_something;
|
||||
do_something(some_condition() ? x : y);
|
||||
some_condition() ? side_effects(x) : side_effects(y);
|
||||
}
|
||||
}
|
||||
|
||||
cond_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
function foo(x, FooBar, some_condition) {
|
||||
if (some_condition) {
|
||||
var x, FooBar;
|
||||
if (some_condition()) {
|
||||
x = new FooBar(1);
|
||||
} else {
|
||||
x = new FooBar(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(x, FooBar, some_condition) {
|
||||
x = new FooBar(some_condition ? 1 : 2);
|
||||
}
|
||||
var x, FooBar;
|
||||
x = new FooBar(some_condition() ? 1 : 2);
|
||||
}
|
||||
}
|
||||
|
||||
cond_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
var FooBar;
|
||||
if (some_condition()) {
|
||||
@@ -245,8 +223,8 @@ cond_3: {
|
||||
|
||||
cond_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
var do_something;
|
||||
if (some_condition()) {
|
||||
@@ -269,8 +247,8 @@ cond_4: {
|
||||
|
||||
cond_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
@@ -289,56 +267,17 @@ cond_5: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
(some_condition() && some_other_condition() ? do_something : alternate)();
|
||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||
some_condition() && some_other_condition() && do_something();
|
||||
}
|
||||
}
|
||||
|
||||
cond_6: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
x ? a : b;
|
||||
x ? a : a;
|
||||
|
||||
x ? y ? a : b : c;
|
||||
x ? y ? a : a : b;
|
||||
x ? y ? a : b : b;
|
||||
x ? y ? a : b : a;
|
||||
x ? y ? a : a : a;
|
||||
|
||||
x ? a : y ? b : c;
|
||||
x ? a : y ? a : b;
|
||||
x ? a : y ? b : b;
|
||||
x ? a : y ? b : a;
|
||||
x ? a : y ? a : a;
|
||||
}
|
||||
expect: {
|
||||
x ? a : b;
|
||||
x, a;
|
||||
|
||||
x ? y ? a : b : c;
|
||||
x ? (y, a) : b;
|
||||
x && y ? a : b;
|
||||
!x || y ? a : b;
|
||||
x && y, a;
|
||||
|
||||
x ? a : y ? b : c;
|
||||
x || y ? a : b;
|
||||
x ? a : (y, b);
|
||||
!x && y ? b : a;
|
||||
!x && y, a;
|
||||
}
|
||||
}
|
||||
|
||||
cond_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
evaluate : true,
|
||||
side_effects: true,
|
||||
}
|
||||
};
|
||||
input: {
|
||||
var x, y, z, a, b;
|
||||
// compress these
|
||||
@@ -389,7 +328,7 @@ cond_7: {
|
||||
x = 'foo';
|
||||
x = 'foo';
|
||||
x = (condition(), 20);
|
||||
x = (z || condition(), 'fuji');
|
||||
x = z ? 'fuji' : (condition(), 'fuji');
|
||||
x = (condition(), 'foobar');
|
||||
x = y ? a : b;
|
||||
x = y ? 'foo' : 'fo';
|
||||
@@ -399,8 +338,8 @@ cond_7: {
|
||||
cond_7_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
evaluate : true
|
||||
};
|
||||
input: {
|
||||
var x;
|
||||
// access to global should be assumed to have side effects
|
||||
@@ -418,10 +357,10 @@ cond_7_1: {
|
||||
|
||||
cond_8: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
evaluate : true,
|
||||
booleans : false
|
||||
};
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -502,10 +441,10 @@ cond_8: {
|
||||
|
||||
cond_8b: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -585,10 +524,10 @@ cond_8b: {
|
||||
|
||||
cond_8c: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate: false,
|
||||
}
|
||||
evaluate : false,
|
||||
booleans : false
|
||||
};
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -666,140 +605,11 @@ cond_8c: {
|
||||
}
|
||||
}
|
||||
|
||||
cond_9: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
g() ? x(1) : x(2);
|
||||
x ? (y || x)() : (y || x)();
|
||||
x ? y(a, b) : y(d, b, c);
|
||||
x ? y(a, b, c) : y(a, b, c);
|
||||
x ? y(a, b, c) : y(a, b, f);
|
||||
x ? y(a, b, c) : y(a, e, c);
|
||||
x ? y(a, b, c) : y(a, e, f);
|
||||
x ? y(a, b, c) : y(d, b, c);
|
||||
x ? y(a, b, c) : y(d, b, f);
|
||||
x ? y(a, b, c) : y(d, e, c);
|
||||
x ? y(a, b, c) : y(d, e, f);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
g() ? x(1) : x(2);
|
||||
x, (y || x)();
|
||||
x ? y(a, b) : y(d, b, c);
|
||||
x, y(a, b, c);
|
||||
y(a, b, x ? c : f);
|
||||
y(a, x ? b : e, c);
|
||||
x ? y(a, b, c) : y(a, e, f);
|
||||
y(x ? a : d, b, c);
|
||||
x ? y(a, b, c) : y(d, b, f);
|
||||
x ? y(a, b, c) : y(d, e, c);
|
||||
x ? y(a, b, c) : y(d, e, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cond_10: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (1 == a) return "foo";
|
||||
if (2 == a) return "foo";
|
||||
if (3 == a) return "foo";
|
||||
if (4 == a) return 42;
|
||||
if (5 == a) return "foo";
|
||||
if (6 == a) return "foo";
|
||||
return "bar";
|
||||
}
|
||||
console.log(f(1), f(2), f(3), f(4), f(5), f(6), f(7));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return 1 == a || 2 == a || 3 == a ? "foo" : 4 == a ? 42 : 5 == a || 6 == a ? "foo" : "bar";
|
||||
}
|
||||
console.log(f(1), f(2), f(3), f(4), f(5), f(6), f(7));
|
||||
}
|
||||
expect_stdout: "foo foo foo 42 foo foo bar"
|
||||
}
|
||||
|
||||
cond_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: "foo",
|
||||
q: function() {
|
||||
return this.p;
|
||||
}
|
||||
};
|
||||
function f() {
|
||||
return "bar";
|
||||
}
|
||||
function g(a) {
|
||||
return a ? f() : o.q();
|
||||
}
|
||||
console.log(g(0), g(1));
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
p: "foo",
|
||||
q: function() {
|
||||
return this.p;
|
||||
}
|
||||
};
|
||||
function f() {
|
||||
return "bar";
|
||||
}
|
||||
function g(a) {
|
||||
return a ? f() : o.q();
|
||||
}
|
||||
console.log(g(0), g(1));
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
}
|
||||
|
||||
cond_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
x ? y && a : a;
|
||||
x ? y || a : a;
|
||||
x ? a : y && a;
|
||||
x ? a : y || a;
|
||||
}
|
||||
expect: {
|
||||
(!x || y) && a;
|
||||
x && y || a;
|
||||
(x || y) && a;
|
||||
!x && y || a;
|
||||
}
|
||||
}
|
||||
|
||||
ternary_boolean_consequent: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? true : x; }
|
||||
@@ -825,21 +635,9 @@ ternary_boolean_consequent: {
|
||||
|
||||
ternary_boolean_alternative: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? x : true; }
|
||||
@@ -865,11 +663,10 @@ ternary_boolean_alternative: {
|
||||
|
||||
trivial_boolean_ternary_expressions : {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
input: {
|
||||
f('foo' in m ? true : false);
|
||||
f('foo' in m ? false : true);
|
||||
@@ -940,11 +737,11 @@ trivial_boolean_ternary_expressions : {
|
||||
|
||||
issue_1154: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
side_effects: true,
|
||||
}
|
||||
};
|
||||
input: {
|
||||
function f1(x) { return x ? -1 : -1; }
|
||||
function f2(x) { return x ? +2 : +2; }
|
||||
@@ -980,7 +777,7 @@ issue_1154: {
|
||||
no_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: false,
|
||||
evaluate : false,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1218,451 +1015,3 @@ delete_conditional_2: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2535_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (true || x()) y();
|
||||
if (true && x()) y();
|
||||
if (x() || true) y();
|
||||
if (x() && true) y();
|
||||
if (false || x()) y();
|
||||
if (false && x()) y();
|
||||
if (x() || false) y();
|
||||
if (x() && false) y();
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
x() && y();
|
||||
x(), y();
|
||||
x() && y();
|
||||
x() && y();
|
||||
x() && y();
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2535_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function x() {}
|
||||
function y() {
|
||||
return "foo";
|
||||
}
|
||||
console.log((x() || true) || y());
|
||||
console.log((y() || true) || x());
|
||||
console.log((x() || true) && y());
|
||||
console.log((y() || true) && x());
|
||||
console.log((x() && true) || y());
|
||||
console.log((y() && true) || x());
|
||||
console.log((x() && true) && y());
|
||||
console.log((y() && true) && x());
|
||||
console.log((x() || false) || y());
|
||||
console.log((y() || false) || x());
|
||||
console.log((x() || false) && y());
|
||||
console.log((y() || false) && x());
|
||||
console.log((x() && false) || y());
|
||||
console.log((y() && false) || x());
|
||||
console.log((x() && false) && y());
|
||||
console.log((y() && false) && x());
|
||||
}
|
||||
expect: {
|
||||
function x() {}
|
||||
function y() {
|
||||
return "foo";
|
||||
}
|
||||
console.log(x() || !0);
|
||||
console.log(y() || !0);
|
||||
console.log((x(), y()));
|
||||
console.log((y(), x()));
|
||||
console.log(!!x() || y());
|
||||
console.log(!!y() || x());
|
||||
console.log(x() && y());
|
||||
console.log(y() && x());
|
||||
console.log(x() || y());
|
||||
console.log(y() || x());
|
||||
console.log(!!x() && y());
|
||||
console.log(!!y() && x());
|
||||
console.log((x(), y()));
|
||||
console.log((y(), x()));
|
||||
console.log(x() && !1);
|
||||
console.log(y() && !1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"foo",
|
||||
"foo",
|
||||
"undefined",
|
||||
"foo",
|
||||
"true",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"foo",
|
||||
"foo",
|
||||
"false",
|
||||
"undefined",
|
||||
"foo",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"false",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2560: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function log(x) {
|
||||
console.log(x);
|
||||
}
|
||||
function foo() {
|
||||
return log;
|
||||
}
|
||||
function bar() {
|
||||
if (x !== (x = foo())) {
|
||||
x(1);
|
||||
} else {
|
||||
x(2);
|
||||
}
|
||||
}
|
||||
var x = function() {
|
||||
console.log("init");
|
||||
};
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
function log(x) {
|
||||
console.log(x);
|
||||
}
|
||||
function bar() {
|
||||
x !== (x = log) ? x(1) : x(2);
|
||||
}
|
||||
var x = function() {
|
||||
console.log("init");
|
||||
};
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if (x()) {
|
||||
var a;
|
||||
y();
|
||||
} else {
|
||||
z();
|
||||
var b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
x() ? y() : z();
|
||||
}
|
||||
}
|
||||
|
||||
to_and_or: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x ? y || z : z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x && y || z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
cond_seq_assign_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
t = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
t = a ? (t = "foo", "bar") : (console.log(t), 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
a = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_3: {
|
||||
options = {
|
||||
assignments: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
if (this)
|
||||
c = 1 + c, c = c + 1;
|
||||
else
|
||||
c = 1 + c, c = c + 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
this, c = 1 + c, c += 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_3271: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
if (a) {
|
||||
b[i++] = 4,
|
||||
b[i++] = 1;
|
||||
} else {
|
||||
b[i++] = 3,
|
||||
b[i++] = 2,
|
||||
b[i++] = 1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
a ? b[i++] = 4 : (b[i++] = 3, b[i++] = 2),
|
||||
b[i++] = 1;
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
iife_condition: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (function() {
|
||||
return console;
|
||||
}())
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
return console;
|
||||
}() || console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
angularjs_chain: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function nonComputedMember(left, right, context, create) {
|
||||
var lhs = left();
|
||||
if (create && create !== 1) {
|
||||
if (lhs && lhs[right] == null) {
|
||||
lhs[right] = {};
|
||||
}
|
||||
}
|
||||
var value = lhs != null ? lhs[right] : undefined;
|
||||
if (context) {
|
||||
return { context: lhs, name: right, value: value };
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function nonComputedMember(left, right, context, create) {
|
||||
var lhs = left();
|
||||
create && 1 !== create && lhs && null == lhs[right] && (lhs[right] = {});
|
||||
var value = null != lhs ? lhs[right] : void 0;
|
||||
return context ? {
|
||||
context: lhs,
|
||||
name: right,
|
||||
value: value
|
||||
} : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3576: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
(a = -1) ? (a && (a.a = 0)) : (a && (a.a = 0));
|
||||
a && a[c = "PASS"]++;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
a = -1, a, a.a = 0;
|
||||
a, a[c = "PASS"]++;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3668: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
var undefined = typeof f;
|
||||
if (!f) return undefined;
|
||||
return;
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
var undefined = typeof f;
|
||||
return f ? void 0 : undefined;
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
166
test/compress/const.js
Normal file
166
test/compress/const.js
Normal file
@@ -0,0 +1,166 @@
|
||||
issue_1191: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function foo(rot) {
|
||||
const rotTol = 5;
|
||||
if (rot < -rotTol || rot > rotTol)
|
||||
bar();
|
||||
baz();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(rot) {
|
||||
(rot < -5 || rot > 5) && bar();
|
||||
baz();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1194: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function f1() {const a = "X"; return a + a;}
|
||||
function f2() {const aa = "X"; return aa + aa;}
|
||||
function f3() {const aaa = "X"; return aaa + aaa;}
|
||||
}
|
||||
expect: {
|
||||
function f1(){return"XX"}
|
||||
function f2(){return"XX"}
|
||||
function f3(){return"XX"}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1396: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
function foo(a) {
|
||||
const VALUE = 1;
|
||||
console.log(2 | VALUE);
|
||||
console.log(VALUE + 1);
|
||||
console.log(VALUE);
|
||||
console.log(a & VALUE);
|
||||
}
|
||||
function bar() {
|
||||
const s = "01234567890123456789";
|
||||
console.log(s + s + s + s + s);
|
||||
|
||||
const CONSTANT = "abc";
|
||||
console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(a) {
|
||||
console.log(3);
|
||||
console.log(2);
|
||||
console.log(1);
|
||||
console.log(1 & a);
|
||||
}
|
||||
function bar() {
|
||||
const s = "01234567890123456789";
|
||||
console.log(s + s + s + s + s);
|
||||
|
||||
console.log("abcabcabcabcabc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unused_regexp_literal: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
}
|
||||
input: {
|
||||
function f(){ var a = /b/; }
|
||||
}
|
||||
expect: {
|
||||
function f(){}
|
||||
}
|
||||
}
|
||||
|
||||
regexp_literal_not_const: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
sequences : false,
|
||||
collapse_vars : false,
|
||||
reduce_vars : true,
|
||||
}
|
||||
input: {
|
||||
(function(){
|
||||
var result;
|
||||
const s = 'acdabcdeabbb';
|
||||
const REGEXP_LITERAL = /ab*/g;
|
||||
while (result = REGEXP_LITERAL.exec(s)) {
|
||||
console.log(result[0]);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var result;
|
||||
const REGEXP_LITERAL = /ab*/g;
|
||||
while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
keep_debugger: {
|
||||
options = {
|
||||
drop_debugger: false,
|
||||
}
|
||||
drop_debugger: false
|
||||
};
|
||||
input: {
|
||||
debugger;
|
||||
}
|
||||
@@ -12,8 +12,8 @@ keep_debugger: {
|
||||
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true,
|
||||
}
|
||||
drop_debugger: true
|
||||
};
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
|
||||
332
test/compress/destructuring.js
Normal file
332
test/compress/destructuring.js
Normal file
@@ -0,0 +1,332 @@
|
||||
destructuring_arrays: {
|
||||
input: {
|
||||
{const [aa, bb] = cc;}
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, bb] = cc;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, bb] = cc;
|
||||
var [aa, [bb, cc]] = dd;
|
||||
var [,[,,,,,],,,zz,] = xx; // Trailing comma
|
||||
var [,,zzz,,] = xxx; // Trailing comma after hole
|
||||
}
|
||||
expect: {
|
||||
{const [aa, bb] = cc;}
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, bb] = cc;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, bb] = cc;
|
||||
var [aa, [bb, cc]] = dd;
|
||||
var [,[,,,,,],,,zz] = xx;
|
||||
var [,,zzz,,] = xxx;
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_arrays_holes: {
|
||||
input: {
|
||||
var [,,,,] = a;
|
||||
var [,,b,] = c;
|
||||
var [d,,] = e;
|
||||
}
|
||||
expect_exact: "var[,,,,]=a;var[,,b]=c;var[d,,]=e;"
|
||||
}
|
||||
|
||||
destructuring_objects: {
|
||||
input: {
|
||||
{const {aa, bb} = {aa:1, bb:2};}
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb} = {aa:1, bb:2};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb} = {aa:1, bb:2};
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
}
|
||||
expect: {
|
||||
{const {aa, bb} = {aa:1, bb:2};}
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb} = {aa:1, bb:2};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb} = {aa:1, bb:2};
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_objects_trailing_elision: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
var {cc,} = foo;
|
||||
}
|
||||
expect_exact: "var{cc}=foo;"
|
||||
}
|
||||
|
||||
nested_destructuring_objects: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
const [{a},b] = c;
|
||||
let [{a},b] = c;
|
||||
var [{a},b] = c;
|
||||
}
|
||||
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
|
||||
}
|
||||
|
||||
destructuring_constdef_in_loops: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
for (const [x,y] in pairs);
|
||||
for (const [a] = 0;;);
|
||||
for (const {c} of cees);
|
||||
}
|
||||
expect_exact: "for(const[x,y]in pairs);for(const[a]=0;;);for(const{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_letdef_in_loops: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
for (let [x,y] in pairs);
|
||||
for (let [a] = 0;;);
|
||||
for (let {c} of cees);
|
||||
}
|
||||
expect_exact: "for(let[x,y]in pairs);for(let[a]=0;;);for(let{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_vardef_in_loops: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
for (var [x,y] in pairs);
|
||||
for (var [a] = 0;;);
|
||||
for (var {c} of cees);
|
||||
}
|
||||
expect_exact: "for(var[x,y]in pairs);for(var[a]=0;;);for(var{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_expressions: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
({a, b});
|
||||
[{a}];
|
||||
f({x});
|
||||
}
|
||||
expect_exact: "({a,b});[{a}];f({x});"
|
||||
}
|
||||
|
||||
destructuring_remove_unused_1: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
var unused = "foo";
|
||||
var a = [1];
|
||||
var [b] = a;
|
||||
f(b);
|
||||
}
|
||||
function b() {
|
||||
var unused = "foo";
|
||||
var a = {b: 1};
|
||||
var {b} = a;
|
||||
f(b);
|
||||
}
|
||||
function c() {
|
||||
var unused = "foo";
|
||||
var a = [[1]];
|
||||
var [[b]] = a;
|
||||
f(b);
|
||||
}
|
||||
function d() {
|
||||
var unused = "foo";
|
||||
var a = {b: {b:1}};
|
||||
var {b:{b}} = a;
|
||||
f(b);
|
||||
}
|
||||
function e() {
|
||||
var unused = "foo";
|
||||
var a = [1, 2, 3, 4, 5];
|
||||
var x = [[1, 2, 3]];
|
||||
var y = {h: 1};
|
||||
var [b, ...c] = a;
|
||||
var [...[e, f]] = x;
|
||||
var [...{g: h}] = y;
|
||||
f(b, c, e, f, g);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var a = [1];
|
||||
var [b] = a;
|
||||
f(b);
|
||||
}
|
||||
function b() {
|
||||
var a = {b: 1};
|
||||
var {b} = a;
|
||||
f(b);
|
||||
}
|
||||
function c() {
|
||||
var a = [[1]];
|
||||
var [[b]] = a;
|
||||
f(b);
|
||||
}
|
||||
function d() {
|
||||
var a = {b: {b:1}};
|
||||
var {b:{b}} = a;
|
||||
f(b);
|
||||
}
|
||||
function e() {
|
||||
var a = [1, 2, 3, 4, 5];
|
||||
var x = [[1, 2, 3]];
|
||||
var y = {h: 1};
|
||||
var [b, ...c] = a;
|
||||
var [...[e, f]] = x;
|
||||
var [...{g: h}] = y;
|
||||
f(b, c, e, f, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_remove_unused_2: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
var unused = "foo";
|
||||
var a = [,,1];
|
||||
var [b] = a;
|
||||
f(b);
|
||||
}
|
||||
function b() {
|
||||
var unused = "foo";
|
||||
var a = [{a: [1]}];
|
||||
var [{b: a}] = a;
|
||||
f(b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var a = [,,1];
|
||||
var [b] = a;
|
||||
f(b);
|
||||
}
|
||||
function b() {
|
||||
var a = [{a: [1]}];
|
||||
var [{b: a}] = a;
|
||||
f(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object_destructuring_may_need_parentheses: {
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
({a, b} = {a: 1, b: 2});
|
||||
}
|
||||
expect_exact: "({a,b}={a:1,b:2});"
|
||||
}
|
||||
|
||||
destructuring_with_undefined_as_default_assignment: {
|
||||
options = {
|
||||
evaluate: true
|
||||
}
|
||||
input: {
|
||||
[foo = undefined] = bar;
|
||||
[foo = void 0] = bar;
|
||||
}
|
||||
expect: {
|
||||
[foo] = bar;
|
||||
[foo] = bar;
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_dont_evaluate_with_undefined_as_default_assignment: {
|
||||
options = {
|
||||
evaluate: false
|
||||
}
|
||||
input: {
|
||||
[foo = undefined] = bar;
|
||||
}
|
||||
expect: {
|
||||
[foo = void 0] = bar;
|
||||
}
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, [bb, cc]] = dd;
|
||||
[aa, [bb, cc]] = dd;
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||
const [{a},b] = c;
|
||||
let [{a},b] = c;
|
||||
var [{a},b] = c;
|
||||
[{a},b] = c;
|
||||
for (const [x,y] in pairs);
|
||||
for (let [x,y] in pairs);
|
||||
for (var [x,y] in pairs);
|
||||
for ([x,y] in pairs);
|
||||
}
|
||||
expect: {
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, [bb, cc]] = dd;
|
||||
[aa, [bb, cc]] = dd;
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||
const [{a},b] = c;
|
||||
let [{a},b] = c;
|
||||
var [{a},b] = c;
|
||||
[{a},b] = c;
|
||||
for (const [x,y] in pairs);
|
||||
for (let [x,y] in pairs);
|
||||
for (var [x,y] in pairs);
|
||||
for ([x,y] in pairs);
|
||||
}
|
||||
}
|
||||
|
||||
unused: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1886: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
let [a] = [1];
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
let [a] = [1];
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: "1"
|
||||
}
|
||||
@@ -1,133 +1,10 @@
|
||||
simple_statement_is_not_a_directive: {
|
||||
class_directives_compression: {
|
||||
input: {
|
||||
"use strict"
|
||||
.split(" ")
|
||||
.forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this); // is strict mode?
|
||||
(function() {
|
||||
"directive"
|
||||
""
|
||||
"use strict"
|
||||
"hello world"
|
||||
.split(" ")
|
||||
.forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this); // is strict mode?
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict".split(" ").forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this);
|
||||
(function() {
|
||||
"directive";
|
||||
"";
|
||||
class foo {
|
||||
foo() {
|
||||
"use strict";
|
||||
"hello world".split(" ").forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this);
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"use",
|
||||
"strict",
|
||||
"false",
|
||||
"hello",
|
||||
"world",
|
||||
"true",
|
||||
]
|
||||
}
|
||||
|
||||
drop_lone_use_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
"use strict";
|
||||
}
|
||||
function f2() {
|
||||
"use strict";
|
||||
function f3() {
|
||||
"use strict";
|
||||
}
|
||||
}
|
||||
(function f4() {
|
||||
"use strict";
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
}
|
||||
function f2() {
|
||||
"use strict";
|
||||
function f3() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3166: {
|
||||
options = {
|
||||
directives: true,
|
||||
}
|
||||
input: {
|
||||
"foo";
|
||||
"use strict";
|
||||
function f() {
|
||||
"use strict";
|
||||
"bar";
|
||||
"use asm";
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
"use asm";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valid_after_invalid_1: {
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
valid_after_invalid_2: {
|
||||
options = {
|
||||
directives: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
}
|
||||
expect_exact: "class foo{foo(){}}"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
drop_console_1: {
|
||||
options = {}
|
||||
options = {};
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
@@ -11,9 +11,7 @@ drop_console_1: {
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = {
|
||||
drop_console: true,
|
||||
}
|
||||
options = { drop_console: true };
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
28
test/compress/expansions.js
Normal file
28
test/compress/expansions.js
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
expand_arguments: {
|
||||
input: {
|
||||
func(a, ...rest);
|
||||
func(...all);
|
||||
}
|
||||
expect_exact: "func(a,...rest);func(...all);"
|
||||
}
|
||||
|
||||
expand_expression_arguments: {
|
||||
input: {
|
||||
f(...a.b);
|
||||
f(...a.b());
|
||||
f(...(a));
|
||||
f(...(a.b));
|
||||
f(...a[i]);
|
||||
}
|
||||
expect_exact: "f(...a.b);f(...a.b());f(...a);f(...a.b);f(...a[i]);"
|
||||
}
|
||||
|
||||
expand_parameters: {
|
||||
input: {
|
||||
(function (a, ...b){});
|
||||
(function (...args){});
|
||||
}
|
||||
expect_exact: "(function(a,...b){});(function(...args){});"
|
||||
}
|
||||
|
||||
52
test/compress/expression.js
Normal file
52
test/compress/expression.js
Normal file
@@ -0,0 +1,52 @@
|
||||
pow: {
|
||||
input: {
|
||||
var a = 2 ** 7;
|
||||
var b = 3;
|
||||
b **= 2;
|
||||
}
|
||||
expect: {
|
||||
var a = 2 ** 7;
|
||||
var b = 3;
|
||||
b **= 2;
|
||||
}
|
||||
}
|
||||
|
||||
pow_with_number_constants: {
|
||||
input: {
|
||||
var a = 5 ** NaN;
|
||||
var b = 42 ** +0;
|
||||
var c = 42 ** -0;
|
||||
var d = NaN ** 1;
|
||||
var e = 2 ** Infinity;
|
||||
var f = 2 ** -Infinity;
|
||||
}
|
||||
expect: {
|
||||
var a = 5 ** NaN;
|
||||
var b = 42 ** +0;
|
||||
var c = 42 ** -0;
|
||||
var d = NaN ** 1;
|
||||
var e = 2 ** (1/0);
|
||||
var f = 2 ** (-1/0);
|
||||
}
|
||||
}
|
||||
|
||||
pow_with_parentheses: {
|
||||
input: {
|
||||
var g = (-7) ** (0.5);
|
||||
var h = 2324334 ** 34343443;
|
||||
var i = (-2324334) ** 34343443;
|
||||
var j = 2 ** (-3);
|
||||
var k = 2.0 ** -3;
|
||||
var l = 2.0 ** (5 - 7);
|
||||
}
|
||||
expect_exact: "var g=(-7)**.5;var h=2324334**34343443;var i=(-2324334)**34343443;var j=2**-3;var k=2**-3;var l=2**(5-7);"
|
||||
}
|
||||
|
||||
pow_with_unary_between_brackets: {
|
||||
input: {
|
||||
var a = (-(+5)) ** 3;
|
||||
}
|
||||
expect: {
|
||||
var a = (-+5)**3;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ must_replace: {
|
||||
options = {
|
||||
global_defs: {
|
||||
D: "foo bar",
|
||||
},
|
||||
}
|
||||
}
|
||||
input: {
|
||||
console.log(D);
|
||||
@@ -37,7 +37,6 @@ object: {
|
||||
VALUE: 42,
|
||||
},
|
||||
},
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
@@ -121,7 +120,7 @@ mixed: {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var FOO = { BAR: 0 };
|
||||
const FOO = { BAR: 0 };
|
||||
console.log(FOO.BAR);
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
@@ -131,7 +130,7 @@ mixed: {
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect: {
|
||||
var FOO = { BAR: 0 };
|
||||
const FOO = { BAR: 0 };
|
||||
console.log("moo");
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
@@ -141,8 +140,9 @@ mixed: {
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -160,59 +160,3 @@ issue_1801: {
|
||||
console.log(!0);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1986: {
|
||||
options = {
|
||||
global_defs: {
|
||||
"@alert": "console.log",
|
||||
},
|
||||
}
|
||||
input: {
|
||||
alert(42);
|
||||
}
|
||||
expect: {
|
||||
console.log(42);
|
||||
}
|
||||
}
|
||||
|
||||
issue_2167: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
"@isDevMode": "function(){}",
|
||||
},
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (isDevMode()) {
|
||||
greetOverlord();
|
||||
}
|
||||
doWork();
|
||||
}
|
||||
expect: {
|
||||
doWork();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3217: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
global_defs: {
|
||||
"@o": "{fn:function(){var a=42;console.log(a)}}",
|
||||
},
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
o.fn();
|
||||
}
|
||||
expect: {
|
||||
console.log(42);
|
||||
}
|
||||
}
|
||||
|
||||
511
test/compress/harmony.js
Normal file
511
test/compress/harmony.js
Normal file
@@ -0,0 +1,511 @@
|
||||
arrow_function_parens: {
|
||||
input: {
|
||||
something && (() => {});
|
||||
}
|
||||
expect_exact: "something&&(()=>{});"
|
||||
}
|
||||
arrow_function_parens_2: {
|
||||
input: {
|
||||
(() => null)();
|
||||
}
|
||||
expect_exact: "(()=>null)();"
|
||||
}
|
||||
|
||||
typeof_arrow_functions: {
|
||||
options = {
|
||||
evaluate: true
|
||||
}
|
||||
input: {
|
||||
var foo = typeof (x) => null;
|
||||
}
|
||||
expect_exact: "var foo=\"function\";"
|
||||
}
|
||||
|
||||
classes: {
|
||||
input: {
|
||||
class SomeClass {
|
||||
constructor() {
|
||||
};
|
||||
foo() {};
|
||||
};
|
||||
class NoSemi {
|
||||
constructor(...args) {
|
||||
}
|
||||
foo() {}
|
||||
};
|
||||
class ChildClass extends SomeClass {};
|
||||
var asExpression = class AsExpression {};
|
||||
var nameless = class {};
|
||||
}
|
||||
expect_exact: "class SomeClass{constructor(){}foo(){}}class NoSemi{constructor(...args){}foo(){}}class ChildClass extends SomeClass{}var asExpression=class AsExpression{};var nameless=class{};"
|
||||
}
|
||||
|
||||
class_statics: {
|
||||
input: {
|
||||
x = class {
|
||||
static staticMethod() {}
|
||||
static get foo() {}
|
||||
static set bar() {}
|
||||
static() { /* "static" can be a method name! */ }
|
||||
get() { /* "get" can be a method name! */ }
|
||||
set() { /* "set" can be a method name! */ }
|
||||
}
|
||||
}
|
||||
expect_exact: "x=class{static staticMethod(){}static get foo(){}static set bar(){}static(){}get(){}set(){}};"
|
||||
}
|
||||
|
||||
class_name_can_be_mangled: {
|
||||
mangle = { };
|
||||
input: {
|
||||
function x() {
|
||||
class Foo {
|
||||
}
|
||||
var class1 = Foo
|
||||
var class2 = class Bar {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
class a { }
|
||||
var n = a
|
||||
var r = class a {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_name_can_be_preserved: {
|
||||
mangle = {
|
||||
keep_classnames: true
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
(class Baz { });
|
||||
class Foo {};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
(class Baz { });
|
||||
class Foo {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classes_can_have_generators: {
|
||||
input: {
|
||||
class Foo {
|
||||
*bar() {}
|
||||
static *baz() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
class Foo {
|
||||
*bar() {}
|
||||
static *baz() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classes_can_have_computed_generators: {
|
||||
input: {
|
||||
class C4 {
|
||||
*['constructor']() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
class C4 {
|
||||
*['constructor']() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classes_can_have_computed_static: {
|
||||
input: {
|
||||
class C4 {
|
||||
static ['constructor']() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
class C4 {
|
||||
static ['constructor']() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_methods_and_getters_with_keep_quoted_props_enabled: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
class clss {
|
||||
a() {}
|
||||
"b"() {}
|
||||
get c() { return "c"}
|
||||
get "d"() { return "d"}
|
||||
set e(a) { doSomething(a); }
|
||||
set 'f'(a) { doSomething(b); }
|
||||
static g() {}
|
||||
static "h"() {}
|
||||
}
|
||||
}
|
||||
expect_exact: 'class clss{a(){}"b"(){}get c(){return"c"}get"d"(){return"d"}set e(a){doSomething(a)}set\'f\'(a){doSomething(b)}static g(){}static"h"(){}}'
|
||||
}
|
||||
|
||||
classes_with_expression_as_expand: {
|
||||
input: {
|
||||
class D extends (calls++, C) {}
|
||||
}
|
||||
expect_exact: "class D extends(calls++,C){}"
|
||||
}
|
||||
|
||||
new_target: {
|
||||
input: {
|
||||
new.target;
|
||||
new.target.name;
|
||||
}
|
||||
expect_exact: "new.target;new.target.name;"
|
||||
}
|
||||
|
||||
number_literals: {
|
||||
input: {
|
||||
0b1001;
|
||||
0B1001;
|
||||
0o11;
|
||||
0O11;
|
||||
}
|
||||
|
||||
expect: {
|
||||
9;
|
||||
9;
|
||||
9;
|
||||
9;
|
||||
}
|
||||
}
|
||||
|
||||
import_statement: {
|
||||
input: {
|
||||
import "mod-name";
|
||||
import Foo from "bar";
|
||||
import { Bar, Baz } from 'lel';
|
||||
import Bar, { Foo } from 'lel';
|
||||
import { Bar as kex, Baz as food } from 'lel';
|
||||
}
|
||||
expect_exact: 'import"mod-name";import Foo from"bar";import{Bar,Baz}from"lel";import Bar,{Foo}from"lel";import{Bar as kex,Baz as food}from"lel";'
|
||||
}
|
||||
|
||||
import_all_statement: {
|
||||
input: {
|
||||
import * from 'lel';
|
||||
import * as Lel from 'lel';
|
||||
}
|
||||
expect_exact: 'import*from"lel";import*as Lel from"lel";'
|
||||
}
|
||||
|
||||
export_statement: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
export default 1 + 2;
|
||||
export var foo = 4;
|
||||
export let foo = 6;
|
||||
export const foo = 6;
|
||||
export function foo() {};
|
||||
export class foo { };
|
||||
}
|
||||
expect_exact: "export default 3;export var foo=4;export let foo=6;export const foo=6;export function foo(){};export class foo{};"
|
||||
}
|
||||
|
||||
export_default_object_expression: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
export default {
|
||||
foo: 1 + 2,
|
||||
bar() { return 4; },
|
||||
get baz() { return this.foo; },
|
||||
};
|
||||
}
|
||||
expect_exact: "export default{foo:3,bar(){return 4},get baz(){return this.foo}};"
|
||||
}
|
||||
|
||||
export_default_array: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
export default [ 1 + 2, foo ];
|
||||
}
|
||||
expect_exact: "export default[3,foo];"
|
||||
}
|
||||
|
||||
export_module_statement: {
|
||||
input: {
|
||||
export * from "a.js";
|
||||
export {A} from "a.js";
|
||||
export {A, B} from "a.js";
|
||||
export {C};
|
||||
}
|
||||
expect_exact: 'export*from"a.js";export{A}from"a.js";export{A,B}from"a.js";export{C};'
|
||||
}
|
||||
|
||||
import_statement_mangling: {
|
||||
mangle = { toplevel: true };
|
||||
input: {
|
||||
import Foo from "foo";
|
||||
import Bar, {Food} from "lel";
|
||||
import {What as Whatever} from "lel";
|
||||
Foo();
|
||||
Bar();
|
||||
Food();
|
||||
Whatever();
|
||||
}
|
||||
expect: {
|
||||
import l from "foo";
|
||||
import e, {Food as o} from "lel";
|
||||
import {What as f} from "lel";
|
||||
l();
|
||||
e();
|
||||
o();
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
export_statement_mangling: {
|
||||
mangle = { };
|
||||
input: {
|
||||
export var foo = 6;
|
||||
export function bar() { }
|
||||
export class Baz { }
|
||||
bar(foo, Baz)
|
||||
}
|
||||
expect: {
|
||||
export var foo = 6;
|
||||
export function bar() { }
|
||||
export class Baz { }
|
||||
bar(foo, Baz)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/1021
|
||||
regression_for_of_const: {
|
||||
input: {
|
||||
for (const x of y) {}
|
||||
for (const x in y) {}
|
||||
}
|
||||
expect: {
|
||||
for (const x of y);for (const x in y);
|
||||
}
|
||||
}
|
||||
|
||||
// Fabio: My patches accidentally caused a crash whenever
|
||||
// there's an extraneous set of parens around an object.
|
||||
regression_cannot_destructure: {
|
||||
input: {
|
||||
var x = ({ x : 3 });
|
||||
x(({ x: 3 }));
|
||||
}
|
||||
expect_exact: "var x={x:3};x({x:3});";
|
||||
}
|
||||
|
||||
regression_cannot_use_of: {
|
||||
input: {
|
||||
function of() {
|
||||
}
|
||||
var of = "is a valid variable name";
|
||||
of = { of: "is ok" };
|
||||
x.of;
|
||||
of: foo()
|
||||
}
|
||||
expect: {
|
||||
function of(){}
|
||||
var of="is a valid variable name";
|
||||
of={of:"is ok"};
|
||||
x.of;
|
||||
foo(); /* Label statement missing? No prob. */
|
||||
}
|
||||
}
|
||||
|
||||
fat_arrow_as_param: {
|
||||
input: {
|
||||
foo(x => x);
|
||||
foo(x => x, y => y);
|
||||
|
||||
foo(x => (x, x));
|
||||
foo(x => (x, x), y => (y, y));
|
||||
}
|
||||
expect_exact: "foo(x=>x);foo(x=>x,y=>y);foo(x=>(x,x));foo(x=>(x,x),y=>(y,y));"
|
||||
}
|
||||
|
||||
default_assign: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b = 3) {
|
||||
console.log(a);
|
||||
}
|
||||
|
||||
g = ([[] = 123]) => {};
|
||||
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
|
||||
|
||||
function i([[x, y, z] = [4, 5, 6]] = []) {
|
||||
console.log(b);
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a);
|
||||
}
|
||||
|
||||
g = ([[] = 123]) => {};
|
||||
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
|
||||
|
||||
function i([[x, y, z] = [4, 5, 6]] = []) {
|
||||
console.log(b);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
expansion: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, ...b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1613: {
|
||||
mangle = { toplevel: true };
|
||||
input: {
|
||||
const name = 1;
|
||||
const foo = {
|
||||
name
|
||||
};
|
||||
}
|
||||
expect_exact: "const n=1;const c={name:n};"
|
||||
}
|
||||
|
||||
format_methods: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
class A extends B {constructor(a){x()} static s(b,c){y()} run(d,e,f){z()}}
|
||||
}
|
||||
expect_exact: [
|
||||
"class A extends B {",
|
||||
" constructor(a) {",
|
||||
" x();",
|
||||
" }",
|
||||
" static s(b, c) {",
|
||||
" y();",
|
||||
" }",
|
||||
" run(d, e, f) {",
|
||||
" z();",
|
||||
" }",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1898: {
|
||||
options = {
|
||||
}
|
||||
mangle = {
|
||||
}
|
||||
input: {
|
||||
class Foo {
|
||||
bar() {
|
||||
for (const x of [ 6, 5 ]) {
|
||||
for (let y of [ 4, 3 ]) {
|
||||
for (var z of [ 2, 1 ]) {
|
||||
console.log(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
new Foo().bar();
|
||||
}
|
||||
expect: {
|
||||
class Foo {
|
||||
bar() {
|
||||
for (const n of [ 6, 5 ])
|
||||
for (let r of [ 4, 3 ])
|
||||
for (var o of [ 2, 1 ])
|
||||
console.log(n, r, o);
|
||||
}
|
||||
}
|
||||
new Foo().bar();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1753: {
|
||||
mangle = { safari10: true };
|
||||
input: {
|
||||
class SomeClass {
|
||||
constructor(props) {
|
||||
let pickedSets = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
pickedSets.push({
|
||||
mainDrawNumbers: [],
|
||||
extraDrawNumbers: []
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
class SomeClass {
|
||||
constructor(r) {
|
||||
let a = [];
|
||||
for (let s = 0; s < 6; s++)
|
||||
a.push({
|
||||
mainDrawNumbers: [],
|
||||
extraDrawNumbers: []
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1753_disable: {
|
||||
mangle = { safari10: false }
|
||||
input: {
|
||||
class SomeClass {
|
||||
constructor(props) {
|
||||
let pickedSets = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
pickedSets.push({
|
||||
mainDrawNumbers: [],
|
||||
extraDrawNumbers: []
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
class SomeClass {
|
||||
constructor(r) {
|
||||
let a = [];
|
||||
for (let r = 0; r < 6; r++)
|
||||
a.push({
|
||||
mainDrawNumbers: [],
|
||||
extraDrawNumbers: []
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
test/compress/hoist.js
Normal file
85
test/compress/hoist.js
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
bar();
|
||||
var var1;
|
||||
var var2;
|
||||
}
|
||||
function b(anArg) {
|
||||
bar();
|
||||
var var1;
|
||||
var anArg;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var var1, var2; // Vars go up and are joined
|
||||
bar();
|
||||
}
|
||||
function b(anArg) {
|
||||
var var1;
|
||||
bar();
|
||||
// But vars named like arguments go away!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
bar();
|
||||
function foo() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
function foo() {} // Funs go up
|
||||
bar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hoist_no_destructurings: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
hoist_funs: true
|
||||
}
|
||||
input: {
|
||||
function a([anArg]) {
|
||||
bar();
|
||||
var var1;
|
||||
var anArg; // Because anArg is already declared, this goes away!
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a([anArg]) {
|
||||
var var1;
|
||||
bar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dont_hoist_var_destructurings: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
hoist_funs: true
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
// If foo is null or undefined, this should be an exception
|
||||
var {x,y} = foo;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
var {x,y} = foo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,916 +0,0 @@
|
||||
issue_2377_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
var obj_foo = 1, obj_cube = function(x) {
|
||||
return x * x * x;
|
||||
};
|
||||
console.log(obj_foo, obj_cube(3));
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
issue_2377_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
console.log(1, (x = 3, x * x * x));
|
||||
var x;
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
issue_2377_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 4,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 27);
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
direct_access_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
for (var k in obj) a++;
|
||||
console.log(a, obj.a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
for (var k in obj) a++;
|
||||
console.log(a, obj.a);
|
||||
}
|
||||
expect_stdout: "2 1"
|
||||
}
|
||||
|
||||
direct_access_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { a: 1 };
|
||||
var f = function(k) {
|
||||
if (o[k]) return "PASS";
|
||||
};
|
||||
console.log(f("a"));
|
||||
}
|
||||
expect: {
|
||||
var o = { a: 1 };
|
||||
console.log(function(k) {
|
||||
if (o[k]) return "PASS";
|
||||
}("a"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
direct_access_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { a: 1 };
|
||||
o.b;
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = { a: 1 };
|
||||
o.b;
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
single_use: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
bar: function() {
|
||||
return 42;
|
||||
},
|
||||
};
|
||||
console.log(obj.bar());
|
||||
}
|
||||
expect: {
|
||||
console.log({
|
||||
bar: function() {
|
||||
return 42;
|
||||
},
|
||||
}.bar());
|
||||
}
|
||||
}
|
||||
|
||||
name_collision_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var obj_foo = 1;
|
||||
var obj_bar = 2;
|
||||
function f() {
|
||||
var obj = {
|
||||
foo: 3,
|
||||
bar: 4,
|
||||
"b-r": 5,
|
||||
"b+r": 6,
|
||||
"b!r": 7,
|
||||
};
|
||||
console.log(obj_foo, obj.foo, obj.bar, obj["b-r"], obj["b+r"], obj["b!r"]);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var obj_foo = 1;
|
||||
var obj_bar = 2;
|
||||
function f() {
|
||||
var obj_foo$0 = 3,
|
||||
obj_bar = 4,
|
||||
obj_b_r = 5,
|
||||
obj_b_r$0 = 6,
|
||||
obj_b_r$1 = 7;
|
||||
console.log(obj_foo, obj_foo$0, obj_bar, obj_b_r, obj_b_r$0, obj_b_r$1);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "1 3 4 5 6 7"
|
||||
}
|
||||
|
||||
name_collision_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
"-": function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
o__$2 = function(x) {
|
||||
return x + 1;
|
||||
},
|
||||
o__$0 = 2,
|
||||
o__$1 = 3;
|
||||
console.log(o_p === o_p, o__(4), o__$2(5), o__$0, o__$1);
|
||||
}
|
||||
expect_stdout: "true 4 6 2 3"
|
||||
}
|
||||
|
||||
name_collision_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
"-": function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
o__$2 = function(x) {
|
||||
return x + 1;
|
||||
},
|
||||
o__$0 = 2,
|
||||
o__$1 = 3;
|
||||
console.log(o_p === o_p, o__(4), o__$2(5));
|
||||
}
|
||||
expect_stdout: "true 4 6"
|
||||
}
|
||||
|
||||
contains_this_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 1);
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
contains_this_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 1, function() {
|
||||
return this === this;
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
contains_this_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u());
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u());
|
||||
}
|
||||
expect_stdout: "1 1 true"
|
||||
}
|
||||
|
||||
new_this: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
f: function(a) {
|
||||
this.b = a;
|
||||
}
|
||||
};
|
||||
console.log(new o.f(o.a).b, o.b);
|
||||
}
|
||||
expect: {
|
||||
console.log(new function(a) {
|
||||
this.b = a;
|
||||
}(1).b, 2);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2473_1: {
|
||||
options = {
|
||||
hoist_props: false,
|
||||
reduce_vars: true,
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
var z = {};
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
}
|
||||
|
||||
issue_2473_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
var z = {};
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
}
|
||||
|
||||
issue_2473_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: "o",
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2473_4: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: "o",
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var o_a = 1, o_b = 2;
|
||||
console.log(o_a, o_b);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2508_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: [ 1 ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x);
|
||||
})([ 1 ]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: { b: 2 },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x);
|
||||
})({ b: 2 });
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: [ o ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: [ o ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: { b: o },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: { b: o },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.f);
|
||||
}
|
||||
expect: {
|
||||
var o_f = function(x) {
|
||||
console.log(x);
|
||||
};
|
||||
o_f(o_f);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2519: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function testFunc() {
|
||||
var dimensions = {
|
||||
minX: 5,
|
||||
maxX: 6,
|
||||
};
|
||||
var scale = 1;
|
||||
var d = {
|
||||
x: (dimensions.maxX + dimensions.minX) / 2,
|
||||
};
|
||||
return d.x * scale;
|
||||
}
|
||||
console.log(testFunc());
|
||||
}
|
||||
expect: {
|
||||
function testFunc() {
|
||||
return +((6 + 5) / 2);
|
||||
}
|
||||
console.log(testFunc());
|
||||
}
|
||||
expect_stdout: "5.5"
|
||||
}
|
||||
|
||||
undefined_key: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 4,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, o = {};
|
||||
o[a] = 1;
|
||||
o.b = 2;
|
||||
console.log(o[a] + o.b);
|
||||
}
|
||||
expect: {
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
issue_3021: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
issue_3046: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b = {
|
||||
c: a++
|
||||
};
|
||||
} while (b.c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b_c = a++;
|
||||
} while (b_c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2_toplevel: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_3411: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 1;
|
||||
!function f() {
|
||||
var o = {
|
||||
p: --c && f()
|
||||
};
|
||||
+o || console.log("PASS");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var c = 1;
|
||||
!function f() {
|
||||
var o_p = --c && f();
|
||||
+{} || console.log("PASS");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3440: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(o.p);
|
||||
}
|
||||
var o = {
|
||||
p: "PASS",
|
||||
};
|
||||
return f;
|
||||
})()();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var o_p = "PASS";
|
||||
return function() {
|
||||
console.log(o_p);
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -88,24 +88,3 @@ sequences_funs: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2295: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
function foo(o) {
|
||||
var a = o.a;
|
||||
if (a) return a;
|
||||
var a = 1;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(o) {
|
||||
var a = o.a;
|
||||
if (a) return a;
|
||||
a = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +1,64 @@
|
||||
html_comment_in_expression: {
|
||||
input: {
|
||||
(function(a, b) {
|
||||
console.log(a < !--b && a-- > b, a, b);
|
||||
})(1, 2);
|
||||
function f(a, b, x, y) { return a < !--b && x-- > y; }
|
||||
}
|
||||
expect_exact: "(function(a,b){console.log(a<! --b&&a-- >b,a,b)})(1,2);"
|
||||
expect_stdout: "false 1 1"
|
||||
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
|
||||
}
|
||||
|
||||
html_comment_in_less_than: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a < !--b,
|
||||
a < !--b + c,
|
||||
a + b < !--c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
function f(a, b) { return a < !--b; }
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a<! --b,a<! --b+c,a+b<! --c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false true false 1 0 2"
|
||||
expect_exact: "function f(a,b){return a< !--b}";
|
||||
}
|
||||
|
||||
html_comment_in_left_shift: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a << !--b,
|
||||
a << !--b + c,
|
||||
a + b << !--c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
function f(a, b) { return a << !--b; }
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a<<! --b,a<<! --b+c,a+b<<! --c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "1 16 1 1 0 2"
|
||||
}
|
||||
|
||||
html_comment_in_greater_than: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- > b,
|
||||
a-- > b + c,
|
||||
a + b-- > c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >b,a-- >b+c,a+b-- >c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false false false -1 1 3"
|
||||
}
|
||||
|
||||
html_comment_in_greater_than_or_equal: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >= b,
|
||||
a-- >= b + c,
|
||||
a + b-- >= c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >=b,a-- >=b+c,a+b-- >=c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false false false -1 1 3"
|
||||
expect_exact: "function f(a,b){return a<< !--b}";
|
||||
}
|
||||
|
||||
html_comment_in_right_shift: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >> b,
|
||||
a-- >> b + c,
|
||||
a + b-- >> c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
function f(a, b) { return a-- >> b; }
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >>b,a-- >>b+c,a+b-- >>c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "0 0 0 -1 1 3"
|
||||
expect_exact: "function f(a,b){return a-- >>b}";
|
||||
}
|
||||
|
||||
html_comment_in_zero_fill_right_shift: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >>> b,
|
||||
a-- >>> b + c,
|
||||
a + b-- >>> c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
function f(a, b) { return a-- >>> b; }
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >>>b,a-- >>>b+c,a+b-- >>>c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "0 0 0 -1 1 3"
|
||||
expect_exact: "function f(a,b){return a-- >>>b}";
|
||||
}
|
||||
|
||||
html_comment_in_greater_than: {
|
||||
input: {
|
||||
function f(a, b) { return a-- > b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >b}";
|
||||
}
|
||||
|
||||
html_comment_in_greater_than_or_equal: {
|
||||
input: {
|
||||
function f(a, b) { return a-- >= b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >=b}";
|
||||
}
|
||||
|
||||
html_comment_in_string_literal: {
|
||||
input: {
|
||||
console.log("<!--HTML-->comment in<!--string literal-->".length);
|
||||
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
|
||||
}
|
||||
expect_exact: 'console.log("\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e".length);'
|
||||
expect_stdout: "42"
|
||||
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
||||
}
|
||||
|
||||
html_comment_after_multiline_comment: {
|
||||
input: {
|
||||
var foo; /*
|
||||
*/--> var bar;
|
||||
var foobar;
|
||||
}
|
||||
expect_exact: "var foo;var foobar;"
|
||||
}
|
||||
|
||||
2422
test/compress/ie8.js
2422
test/compress/ie8.js
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,14 @@
|
||||
if_return_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -24,15 +24,15 @@ if_return_1: {
|
||||
|
||||
if_return_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -49,15 +49,15 @@ if_return_2: {
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -75,15 +75,15 @@ if_return_3: {
|
||||
|
||||
if_return_4: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -100,15 +100,15 @@ if_return_4: {
|
||||
|
||||
if_return_5: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -126,15 +126,15 @@ if_return_5: {
|
||||
|
||||
if_return_6: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -150,15 +150,15 @@ if_return_6: {
|
||||
|
||||
if_return_7: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -176,10 +176,10 @@ if_return_7: {
|
||||
|
||||
if_return_8: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
conditionals: true,
|
||||
side_effects : true,
|
||||
}
|
||||
input: {
|
||||
function f(e) {
|
||||
@@ -220,15 +220,15 @@ if_return_8: {
|
||||
|
||||
issue_1089: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -243,7 +243,7 @@ issue_1089: {
|
||||
expect: {
|
||||
function x() {
|
||||
var f = document.getElementById("fname");
|
||||
if (12345 < f.files[0].size)
|
||||
if (f.files[0].size > 12345)
|
||||
return alert("alert"), f.focus(), !1;
|
||||
}
|
||||
}
|
||||
@@ -251,9 +251,9 @@ issue_1089: {
|
||||
|
||||
issue_1437: {
|
||||
options = {
|
||||
conditionals: false,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : false
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -281,9 +281,9 @@ issue_1437: {
|
||||
|
||||
issue_1437_conditionals: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
conditionals : true,
|
||||
if_return : true,
|
||||
sequences : true
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -302,274 +302,3 @@ issue_1437_conditionals: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_512: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
if (b()) {
|
||||
c();
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
if (!b()) throw e;
|
||||
c();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_var_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
return;
|
||||
var b;
|
||||
}
|
||||
function g() {
|
||||
var a;
|
||||
if (u()) {
|
||||
var b;
|
||||
return v();
|
||||
var c;
|
||||
}
|
||||
var d;
|
||||
if (w()) {
|
||||
var e;
|
||||
return x();
|
||||
var f;
|
||||
} else {
|
||||
var g;
|
||||
y();
|
||||
var h;
|
||||
}
|
||||
var i;
|
||||
z();
|
||||
var j;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a, b;
|
||||
}
|
||||
function g() {
|
||||
var a, b, c, d, e, f, g, h, i, j;
|
||||
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_if_return_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b)
|
||||
return b;
|
||||
return;
|
||||
}
|
||||
g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
if (a)
|
||||
return b || void 0;
|
||||
g();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_body_return_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 == a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 != a) return true;
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3600: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function() {
|
||||
if ([ ][c++]); else return;
|
||||
return void function() {
|
||||
var b = --b, a = c = 42;
|
||||
return c;
|
||||
}();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function() {
|
||||
if ([][c++]) b = --b, c = 42;
|
||||
var b;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
8
test/compress/issue-1001.js
Normal file
8
test/compress/issue-1001.js
Normal file
@@ -0,0 +1,8 @@
|
||||
parenthesis_strings_in_parenthesis: {
|
||||
input: {
|
||||
var foo = ('(');
|
||||
a(')');
|
||||
|
||||
}
|
||||
expect_exact: 'var foo="(";a(")");'
|
||||
}
|
||||
@@ -1,17 +1,8 @@
|
||||
non_hoisted_function_after_return: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -30,35 +21,25 @@ non_hoisted_function_after_return: {
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return (x ? bar : baz)();
|
||||
return x ? bar() : baz();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]"
|
||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -84,37 +65,26 @@ non_hoisted_function_after_return_2a: {
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 37",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
|
||||
"INFO: pass 1: last_count: 37, count: 18",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:51,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -138,173 +108,11 @@ non_hoisted_function_after_return_2b: {
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_strict: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar();
|
||||
not_called1();
|
||||
} else {
|
||||
return baz();
|
||||
not_called2();
|
||||
}
|
||||
function bar() { return 7; }
|
||||
return not_reached;
|
||||
function UnusedFunction() {}
|
||||
function baz() { return 8; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return (x ? bar : baz)();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "8 7"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:11,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:12,21]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a_strict: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
var a = not_called(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b = not_called(2);
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) { return 7 - x; }
|
||||
function nope() {}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 48",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
|
||||
"INFO: pass 1: last_count: 48, count: 29",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b_strict: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b;
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) { return 7 - x; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
// duplicate warnings no longer emitted
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
const_declaration: {
|
||||
options = {
|
||||
evaluate: true
|
||||
};
|
||||
|
||||
input: {
|
||||
const goog = goog || {};
|
||||
}
|
||||
expect: {
|
||||
const goog = goog || {};
|
||||
}
|
||||
}
|
||||
|
||||
const_pragma: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: {
|
||||
/** @const */ var goog = goog || {};
|
||||
@@ -17,9 +29,8 @@ const_pragma: {
|
||||
not_const: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: {
|
||||
var goog = goog || {};
|
||||
|
||||
30
test/compress/issue-1043.js
Normal file
30
test/compress/issue-1043.js
Normal file
@@ -0,0 +1,30 @@
|
||||
issue_1043: {
|
||||
options = {
|
||||
side_effects: true
|
||||
};
|
||||
|
||||
input: {
|
||||
function* range(start = 0, end = null, step = 1) {
|
||||
if (end == null) {
|
||||
end = start;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
for (let i = start; i < end; i += step) {
|
||||
yield i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect: {
|
||||
function* range(start = 0, end = null, step = 1) {
|
||||
if (null == end) {
|
||||
end = start;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
for (let i = start; i < end; i += step)
|
||||
yield i;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
test/compress/issue-1044.js
Normal file
9
test/compress/issue-1044.js
Normal file
@@ -0,0 +1,9 @@
|
||||
issue_1044: {
|
||||
options = { evaluate: true, conditionals: true };
|
||||
input: {
|
||||
const mixed = Base ? class extends Base {} : class {}
|
||||
}
|
||||
expect: {
|
||||
const mixed = Base ? class extends Base {} : class {}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +1,90 @@
|
||||
multiple_functions: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window );
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
single_function: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( window );
|
||||
function f() {}
|
||||
|
||||
if ( window );
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
deeply_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
if ( !document ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
|
||||
function h() {}
|
||||
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window )
|
||||
if (document);
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
not_hoisted_when_already_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
options = { if_return: true, hoist_funs: false };
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( foo ) function f() {}
|
||||
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
@@ -95,70 +94,3 @@ not_hoisted_when_already_nested: {
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
defun_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
if (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_else_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
else return;
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
with_in_global_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = 42;
|
||||
@@ -18,7 +18,7 @@ with_in_global_scope: {
|
||||
}
|
||||
with_in_function_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -40,7 +40,7 @@ with_in_function_scope: {
|
||||
}
|
||||
compress_with_with_in_other_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
|
||||
}
|
||||
with_using_existing_variable_outside_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
|
||||
}
|
||||
check_drop_unused_in_peer_function: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function outer() {
|
||||
@@ -148,7 +148,7 @@ check_drop_unused_in_peer_function: {
|
||||
|
||||
Infinity_not_in_with_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -164,7 +164,7 @@ Infinity_not_in_with_scope: {
|
||||
|
||||
Infinity_in_with_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -180,19 +180,20 @@ Infinity_in_with_scope: {
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: false,
|
||||
sequences: false,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
sequences: false,
|
||||
keep_infinity: false,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
@@ -242,19 +243,20 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: true,
|
||||
sequences: false,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
sequences: false,
|
||||
keep_infinity: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
keep_name_of_getter: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
options = { unused: true };
|
||||
input: { a = { get foo () {} } }
|
||||
expect: { a = { get foo () {} } }
|
||||
}
|
||||
|
||||
keep_name_of_setter: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
options = { unused: true };
|
||||
input: { a = { set foo () {} } }
|
||||
expect: { a = { set foo () {} } }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mangle_keep_fnames_false: {
|
||||
options = {
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
@@ -26,8 +26,8 @@ mangle_keep_fnames_false: {
|
||||
|
||||
mangle_keep_fnames_true: {
|
||||
options = {
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
|
||||
76
test/compress/issue-1212.js
Normal file
76
test/compress/issue-1212.js
Normal file
@@ -0,0 +1,76 @@
|
||||
issue_1212_debug_false: {
|
||||
options = {
|
||||
global_defs : { DEBUG: false },
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
}
|
||||
input: {
|
||||
class foo {
|
||||
bar() {
|
||||
if (DEBUG)
|
||||
console.log("DEV");
|
||||
else
|
||||
console.log("PROD");
|
||||
}
|
||||
}
|
||||
new foo().bar();
|
||||
}
|
||||
expect: {
|
||||
class foo{
|
||||
bar() { console.log("PROD") }
|
||||
}
|
||||
(new foo).bar();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1212_debug_true: {
|
||||
options = {
|
||||
global_defs : { DEBUG: true },
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
}
|
||||
input: {
|
||||
class foo {
|
||||
bar() {
|
||||
if (DEBUG)
|
||||
console.log("DEV");
|
||||
else
|
||||
console.log("PROD");
|
||||
}
|
||||
}
|
||||
new foo().bar();
|
||||
}
|
||||
expect: {
|
||||
class foo{
|
||||
bar() { console.log("DEV") }
|
||||
}
|
||||
(new foo).bar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
pure_function_calls: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
negate_iife : true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -48,28 +49,29 @@ pure_function_calls: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:25,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
|
||||
]
|
||||
}
|
||||
|
||||
pure_function_calls_toplevel: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
negate_iife : true,
|
||||
toplevel : true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -94,13 +96,6 @@ pure_function_calls_toplevel: {
|
||||
})();
|
||||
})();
|
||||
|
||||
// pure top-level calls will be dropped regardless of the leading comments position
|
||||
var MyClass = /*#__PURE__*//*@class*/(function(){
|
||||
function MyClass() {}
|
||||
MyClass.prototype.method = function() {};
|
||||
return MyClass;
|
||||
})();
|
||||
|
||||
// comment #__PURE__ comment
|
||||
bar(), baz(), quux();
|
||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||
@@ -110,17 +105,15 @@ pure_function_calls_toplevel: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:31,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:32,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:8,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:24,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -155,29 +148,29 @@ should_warn: {
|
||||
baz();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:7,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:9,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:9,24]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:10,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:10,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
string_plus_optimization: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
hoist_funs : true,
|
||||
};
|
||||
input: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
issue_1321_no_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
mangle_props = {
|
||||
keep_quoted: true
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
@@ -12,19 +10,17 @@ issue_1321_no_debug: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["a"] = 2 * x.x;
|
||||
console.log(x.x, x["a"]);
|
||||
x.b = 1;
|
||||
x["a"] = 2 * x.b;
|
||||
console.log(x.b, x["a"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
debug: "",
|
||||
mangle_props = {
|
||||
keep_quoted: true,
|
||||
},
|
||||
debug: ""
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
@@ -34,18 +30,16 @@ issue_1321_debug: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["_$foo$_"] = 2 * x.x;
|
||||
console.log(x.x, x["_$foo$_"]);
|
||||
x.a = 1;
|
||||
x["_$foo$_"] = 2 * x.a;
|
||||
console.log(x.a, x["_$foo$_"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_with_quoted: {
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: false,
|
||||
},
|
||||
mangle_props = {
|
||||
keep_quoted: false
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
@@ -55,9 +49,9 @@ issue_1321_with_quoted: {
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["o"] = 2 * x.x;
|
||||
console.log(x.x, x["o"]);
|
||||
x.a = 1;
|
||||
x["b"] = 2 * x.a;
|
||||
console.log(x.a, x["b"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
tranformation_sort_order_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: { (a = parseInt('100')) == a }
|
||||
expect: { (a = parseInt('100')) == a }
|
||||
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
|
||||
tranformation_sort_order_unequal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: { (a = parseInt('100')) != a }
|
||||
expect: { (a = parseInt('100')) != a }
|
||||
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
|
||||
tranformation_sort_order_lesser_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: { (a = parseInt('100')) <= a }
|
||||
expect: { (a = parseInt('100')) <= a }
|
||||
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
|
||||
tranformation_sort_order_greater_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
};
|
||||
|
||||
input: { (a = parseInt('100')) >= a }
|
||||
expect: { (a = parseInt('100')) >= a }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
level_zero: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -29,7 +29,7 @@ level_zero: {
|
||||
|
||||
level_one: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -58,7 +58,7 @@ level_one: {
|
||||
|
||||
level_two: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -97,7 +97,7 @@ level_two: {
|
||||
|
||||
level_three: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe_undefined: true,
|
||||
unsafe: true
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe_undefined: true,
|
||||
unsafe: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
typeof_eq_undefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
comparisons: true
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
@@ -25,7 +24,6 @@ typeof_eq_undefined_ie8: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
ie8: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
@@ -47,8 +45,7 @@ typeof_eq_undefined_ie8: {
|
||||
|
||||
undefined_redefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
comparisons: true
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
@@ -61,8 +58,7 @@ undefined_redefined: {
|
||||
|
||||
undefined_redefined_mangle: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
comparisons: true
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
|
||||
@@ -22,17 +22,18 @@ else_with_empty_statement: {
|
||||
|
||||
conditional_false_stray_else_in_loop: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: false,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
evaluate : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
loops : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
hoist_vars : true,
|
||||
join_vars : true,
|
||||
if_return : true,
|
||||
cascade : true,
|
||||
conditionals : false,
|
||||
}
|
||||
input: {
|
||||
for (var i = 1; i <= 4; ++i) {
|
||||
|
||||
291
test/compress/issue-1466.js
Normal file
291
test/compress/issue-1466.js
Normal file
@@ -0,0 +1,291 @@
|
||||
same_variable_in_multiple_for_loop: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let a = 100;
|
||||
console.log(i, a);
|
||||
for (let i = 0; i < 2; i++) {
|
||||
console.log(i, a);
|
||||
let c = 2;
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for (let o = 0; o < 3; o++) {
|
||||
let l = 100;
|
||||
console.log(o, l);
|
||||
for (let o = 0; o < 2; o++) {
|
||||
console.log(o, l);
|
||||
let c = 2;
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forOf: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp of test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let tmp of dd) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let o of test) {
|
||||
console.log(o);
|
||||
let e;
|
||||
e = [ "e", "f", "g" ];
|
||||
for (let o of e)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forIn: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: false,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp in test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let tmp in test) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let o in test) {
|
||||
console.log(o);
|
||||
let e;
|
||||
e = [ "e", "f", "g" ];
|
||||
for (let o in test)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
different_variable_in_multiple_for_loop: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let a = 100;
|
||||
console.log(i, a);
|
||||
for (let j = 0; j < 2; j++) {
|
||||
console.log(j, a);
|
||||
let c = 2;
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for (let o = 0; o < 3; o++) {
|
||||
let l = 100;
|
||||
console.log(o, l);
|
||||
for (let o = 0; o < 2; o++) {
|
||||
console.log(o, l);
|
||||
let c = 2;
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
different_variable_in_multiple_forOf: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp of test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let t of dd) {
|
||||
console.log(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let o of test) {
|
||||
console.log(o);
|
||||
let e;
|
||||
e = [ "e", "f", "g" ];
|
||||
for (let o of e)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
different_variable_in_multiple_forIn: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: false,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp in test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let t in test) {
|
||||
console.log(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let o in test) {
|
||||
console.log(o);
|
||||
let e;
|
||||
e = [ "e", "f", "g" ];
|
||||
for (let o in test)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
more_variable_in_multiple_for: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: false,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
for (let a = 9, i = 0; i < 20; i += a) {
|
||||
let b = a++ + i;
|
||||
console.log(a, b, i);
|
||||
for (let k = b, m = b*b, i = 0; i < 10; i++) {
|
||||
console.log(a, b, m, k, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for (let o = 9, l = 0; l < 20; l += o) {
|
||||
let c = o++ + l;
|
||||
console.log(o, c, l);
|
||||
for (let l = c, e = c * c, f = 0; f < 10; f++)
|
||||
console.log(o, c, e, l, f);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe_undefined: true,
|
||||
unsafe: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
@@ -85,3 +85,15 @@ unsafe_undefined: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
runtime_error: {
|
||||
input: {
|
||||
const a = 1;
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
const a = 1;
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ chained_evaluation_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -29,7 +28,6 @@ chained_evaluation_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -52,30 +50,3 @@ chained_evaluation_2: {
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
chained_evaluation_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: 10,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = "long piece of string";
|
||||
(function() {
|
||||
var b = a, c;
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
f("long piece of string").bar = "long piece of string";
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
issue_1639_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
@@ -11,6 +12,7 @@ issue_1639_1: {
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
|
||||
var L1 = 5;
|
||||
while (--L1 > 0) {
|
||||
if ((--b), false) {
|
||||
@@ -19,20 +21,21 @@ issue_1639_1: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
||||
if (--b, 0) var ignore = 0;
|
||||
if (--b, !1) var ignore = 0;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "100 6"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1639_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
@@ -41,12 +44,14 @@ issue_1639_2: {
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
|
||||
function f19() {
|
||||
if (++a, false)
|
||||
if (a)
|
||||
if (++a);
|
||||
}
|
||||
f19();
|
||||
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
@@ -57,13 +62,13 @@ issue_1639_2: {
|
||||
f19(),
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "101 10"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1639_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
cascade: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
@@ -79,5 +84,5 @@ issue_1639_3: {
|
||||
a++,
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "101 10"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
f7: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
@@ -14,7 +15,6 @@ f7: {
|
||||
negate_iife: true,
|
||||
passes: 3,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
@@ -38,7 +38,7 @@ f7: {
|
||||
"var b = 10;",
|
||||
"",
|
||||
"!function() {",
|
||||
" b = 100;",
|
||||
" for (;b = 100, !1; ) ;",
|
||||
"}(), console.log(100, b);",
|
||||
]
|
||||
expect_stdout: true
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
side_effects_catch: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -35,7 +34,6 @@ side_effects_catch: {
|
||||
|
||||
side_effects_else: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -64,7 +62,6 @@ side_effects_else: {
|
||||
|
||||
side_effects_finally: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -101,7 +98,6 @@ side_effects_finally: {
|
||||
|
||||
side_effects_label: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -134,7 +130,6 @@ side_effects_label: {
|
||||
|
||||
side_effects_switch: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
|
||||
@@ -104,7 +104,7 @@ mangle_catch_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ mangle_catch_var_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -345,95 +345,3 @@ mangle_catch_redef_2_ie8_toplevel: {
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_toplevel: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8_toplevel: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ function_iife_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ function_iife_catch_ie8: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ function_catch_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
|
||||
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
|
||||
@@ -7,7 +7,7 @@ case_1: {
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
switch (true) {
|
||||
case a || true:
|
||||
case a, true:
|
||||
default:
|
||||
b = 2;
|
||||
case true:
|
||||
@@ -17,7 +17,7 @@ case_1: {
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
switch (true) {
|
||||
case a || true:
|
||||
case a, true:
|
||||
b = 2;
|
||||
}
|
||||
console.log(a, b);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
mangle_props: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
mangle_props = {}
|
||||
input: {
|
||||
var obj = {
|
||||
undefined: 1,
|
||||
@@ -46,7 +44,7 @@ mangle_props: {
|
||||
obj[1/0],
|
||||
obj["Infinity"],
|
||||
obj[-1/0],
|
||||
obj[-(1/0)],
|
||||
obj[-1/0],
|
||||
obj["-Infinity"],
|
||||
obj[null],
|
||||
obj["null"]
|
||||
@@ -56,12 +54,10 @@ mangle_props: {
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
mangle_props = {}
|
||||
input: {
|
||||
var obj = {
|
||||
0: 0,
|
||||
@@ -84,19 +80,19 @@ numeric_literal: {
|
||||
' 0: 0,',
|
||||
' "-0": 1,',
|
||||
' 42: 2,',
|
||||
' 42: 3,',
|
||||
' "42": 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' a: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' 1e42: 8',
|
||||
' "1e+42": 8',
|
||||
'};',
|
||||
'',
|
||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||
'',
|
||||
'console.log(obj[42], obj["42"]);',
|
||||
'',
|
||||
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
||||
'',
|
||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||
]
|
||||
@@ -107,139 +103,3 @@ numeric_literal: {
|
||||
"8 7 8",
|
||||
]
|
||||
}
|
||||
|
||||
identifier: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
abstract: 1,
|
||||
boolean: 2,
|
||||
byte: 3,
|
||||
char: 4,
|
||||
class: 5,
|
||||
double: 6,
|
||||
enum: 7,
|
||||
export: 8,
|
||||
extends: 9,
|
||||
final: 10,
|
||||
float: 11,
|
||||
goto: 12,
|
||||
implements: 13,
|
||||
import: 14,
|
||||
int: 15,
|
||||
interface: 16,
|
||||
let: 17,
|
||||
long: 18,
|
||||
native: 19,
|
||||
package: 20,
|
||||
private: 21,
|
||||
protected: 22,
|
||||
public: 23,
|
||||
short: 24,
|
||||
static: 25,
|
||||
super: 26,
|
||||
synchronized: 27,
|
||||
this: 28,
|
||||
throws: 29,
|
||||
transient: 30,
|
||||
volatile: 31,
|
||||
yield: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
break: 36,
|
||||
case: 37,
|
||||
catch: 38,
|
||||
const: 39,
|
||||
continue: 40,
|
||||
debugger: 41,
|
||||
default: 42,
|
||||
delete: 43,
|
||||
do: 44,
|
||||
else: 45,
|
||||
finally: 46,
|
||||
for: 47,
|
||||
function: 48,
|
||||
if: 49,
|
||||
in: 50,
|
||||
instanceof: 51,
|
||||
new: 52,
|
||||
return: 53,
|
||||
switch: 54,
|
||||
throw: 55,
|
||||
try: 56,
|
||||
typeof: 57,
|
||||
var: 58,
|
||||
void: 59,
|
||||
while: 60,
|
||||
with: 61,
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var obj = {
|
||||
e: 1,
|
||||
t: 2,
|
||||
n: 3,
|
||||
a: 4,
|
||||
i: 5,
|
||||
o: 6,
|
||||
r: 7,
|
||||
l: 8,
|
||||
s: 9,
|
||||
c: 10,
|
||||
f: 11,
|
||||
u: 12,
|
||||
d: 13,
|
||||
h: 14,
|
||||
p: 15,
|
||||
b: 16,
|
||||
v: 17,
|
||||
w: 18,
|
||||
y: 19,
|
||||
g: 20,
|
||||
m: 21,
|
||||
k: 22,
|
||||
x: 23,
|
||||
j: 24,
|
||||
z: 25,
|
||||
q: 26,
|
||||
A: 27,
|
||||
B: 28,
|
||||
C: 29,
|
||||
D: 30,
|
||||
F: 31,
|
||||
G: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
H: 36,
|
||||
I: 37,
|
||||
J: 38,
|
||||
K: 39,
|
||||
L: 40,
|
||||
M: 41,
|
||||
N: 42,
|
||||
O: 43,
|
||||
P: 44,
|
||||
Q: 45,
|
||||
R: 46,
|
||||
S: 47,
|
||||
T: 48,
|
||||
U: 49,
|
||||
V: 50,
|
||||
W: 51,
|
||||
X: 52,
|
||||
Y: 53,
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
unary_prefix: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
iife_for: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -27,7 +26,6 @@ iife_for: {
|
||||
iife_for_in: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -53,7 +51,6 @@ iife_for_in: {
|
||||
iife_do: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -83,7 +80,6 @@ iife_do: {
|
||||
iife_while: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -125,8 +121,8 @@ label_do: {
|
||||
|
||||
label_while: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
@@ -134,5 +130,5 @@ label_while: {
|
||||
L: while (0) continue L;
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){L:0}"
|
||||
expect_exact: "function f(){L:;}"
|
||||
}
|
||||
|
||||
34
test/compress/issue-203.js
Normal file
34
test/compress/issue-203.js
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
compress_new_function: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
new Function("aa, bb", 'return aa;');
|
||||
}
|
||||
expect: {
|
||||
Function("a", "b", "return a");
|
||||
}
|
||||
}
|
||||
|
||||
compress_new_function_with_destruct: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
ecma: 6
|
||||
}
|
||||
beautify = {
|
||||
ecma: 6
|
||||
}
|
||||
input: {
|
||||
new Function("aa, [bb]", 'return aa;');
|
||||
new Function("aa, {bb}", 'return aa;');
|
||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||
}
|
||||
expect: {
|
||||
Function("a", "[b]", "return a");
|
||||
Function("a", "{bb}", "return a");
|
||||
Function("[[a]]", "[{bb}]", 'return a');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
do_not_update_lhs: {
|
||||
options = {
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
global_defs: { DEBUG: 0 }
|
||||
}
|
||||
input: {
|
||||
DEBUG++;
|
||||
@@ -18,9 +16,7 @@ do_not_update_lhs: {
|
||||
|
||||
do_update_rhs: {
|
||||
options = {
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
global_defs: { DEBUG: 0 }
|
||||
}
|
||||
input: {
|
||||
MY_DEBUG = DEBUG;
|
||||
@@ -39,10 +35,10 @@ mixed: {
|
||||
DEBUG: 0,
|
||||
ENV: 1,
|
||||
FOO: 2,
|
||||
},
|
||||
}
|
||||
}
|
||||
input: {
|
||||
var ENV = 3;
|
||||
const ENV = 3;
|
||||
var FOO = 4;
|
||||
f(ENV * 10);
|
||||
--FOO;
|
||||
@@ -53,7 +49,7 @@ mixed: {
|
||||
x = DEBUG;
|
||||
}
|
||||
expect: {
|
||||
var ENV = 3;
|
||||
const ENV = 3;
|
||||
var FOO = 4;
|
||||
f(10);
|
||||
--FOO;
|
||||
@@ -64,11 +60,11 @@ mixed: {
|
||||
x = 0;
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: global_defs ENV redefined [test/compress/issue-208.js:1,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:2,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:4,10]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:5,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:6,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:7,8]",
|
||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,14]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
return_with_no_value_in_if_body: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
options = { conditionals: true };
|
||||
input: {
|
||||
function foo(bar) {
|
||||
if (bar) {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
insert_semicolon: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
var a
|
||||
/* foo */ var b
|
||||
}
|
||||
expect_exact: [
|
||||
"var a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"var b;",
|
||||
]
|
||||
}
|
||||
|
||||
unary_postfix: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
a
|
||||
/* foo */++b
|
||||
}
|
||||
expect_exact: [
|
||||
"a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"++b;",
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
issue_267: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
options = { comparisons: true };
|
||||
input: {
|
||||
x = a % b / b * c * 2;
|
||||
x = a % b * 2
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
issue_269_1: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
options = {unsafe: true};
|
||||
input: {
|
||||
var x = {};
|
||||
console.log(
|
||||
f(
|
||||
String(x),
|
||||
Number(x),
|
||||
Boolean(x),
|
||||
@@ -15,42 +12,32 @@ issue_269_1: {
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
console.log(
|
||||
x + "", +x, !!x,
|
||||
"", 0, false
|
||||
f(
|
||||
x + '', +x, !!x,
|
||||
'', 0, false
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_269_dangers: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
options = {unsafe: true};
|
||||
input: {
|
||||
var x = {};
|
||||
console.log(
|
||||
f(
|
||||
String(x, x),
|
||||
Number(x, x),
|
||||
Boolean(x, x)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
console.log(String(x, x), Number(x, x), Boolean(x, x));
|
||||
f(String(x, x), Number(x, x), Boolean(x, x));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_269_in_scope: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
options = {unsafe: true};
|
||||
input: {
|
||||
var String, Number, Boolean;
|
||||
var x = {};
|
||||
console.log(
|
||||
f(
|
||||
String(x),
|
||||
Number(x, x),
|
||||
Boolean(x)
|
||||
@@ -58,54 +45,22 @@ issue_269_in_scope: {
|
||||
}
|
||||
expect: {
|
||||
var String, Number, Boolean;
|
||||
var x = {};
|
||||
console.log(String(x), Number(x, x), Boolean(x));
|
||||
f(String(x), Number(x, x), Boolean(x));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
strings_concat: {
|
||||
options = {
|
||||
strings: true,
|
||||
unsafe: true,
|
||||
}
|
||||
options = {unsafe: true};
|
||||
input: {
|
||||
var x = {};
|
||||
console.log(
|
||||
String(x + "str"),
|
||||
String("str" + x)
|
||||
f(
|
||||
String(x + 'str'),
|
||||
String('str' + x)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
console.log(
|
||||
x + "str",
|
||||
"str" + x
|
||||
f(
|
||||
x + 'str',
|
||||
'str' + x
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
regexp: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
RegExp("foo");
|
||||
RegExp("bar", "ig");
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect: {
|
||||
/foo/;
|
||||
/bar/ig;
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:5,8]',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
warn: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g();
|
||||
}
|
||||
function g() {
|
||||
return g["call" + "er"].arguments;
|
||||
}
|
||||
// 3
|
||||
console.log(f(1, 2, 3).length);
|
||||
}
|
||||
expect: {
|
||||
// TypeError: Cannot read property 'arguments' of null
|
||||
console.log(function g() {
|
||||
return g.caller.arguments;
|
||||
}().length);
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Function.prototype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
||||
"WARN: Function.prototype.caller not supported [test/compress/issue-2719.js:5,19]",
|
||||
]
|
||||
}
|
||||
@@ -1,498 +0,0 @@
|
||||
collapse_vars_constants: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(x) {
|
||||
var a = 4, b = x.prop, c = 5, d = sideeffect1(), e = sideeffect2();
|
||||
return b + (function() { return d - a * e - c; })();
|
||||
}
|
||||
function f2(x) {
|
||||
var a = 4, b = x.prop, c = 5, not_used = sideeffect1(), e = sideeffect2();
|
||||
return b + (function() { return -a * e - c; })();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1(x) {
|
||||
var b = x.prop, d = sideeffect1(), e = sideeffect2();
|
||||
return b + (d - 4 * e - 5);
|
||||
}
|
||||
function f2(x) {
|
||||
var b = x.prop;
|
||||
sideeffect1();
|
||||
return b + (-4 * sideeffect2() - 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f5(b) {
|
||||
var a = function() {
|
||||
return b;
|
||||
}();
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f5(1));
|
||||
}
|
||||
expect: {
|
||||
function f5(b) {
|
||||
var a = b;
|
||||
return b++ + a;
|
||||
}
|
||||
console.log(f5(1));
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
ref_scope: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
var a = c++, b = b /= a;
|
||||
return function() {
|
||||
return a;
|
||||
}() + b;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = b /= a = c++;
|
||||
return a + b;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
safe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
unsafe: false,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var a, c;
|
||||
console.log(function(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}(1)());
|
||||
}
|
||||
expect: {
|
||||
var a, c;
|
||||
console.log(a ? b : c ? d : void 0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? console.log(true) : console.log(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? foo(true) : bar(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
t ? foo(true) : bar(false), void console.log("something");
|
||||
}
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))()()();'
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
this.x = a;
|
||||
console.log(this);
|
||||
};
|
||||
}(7))();
|
||||
}
|
||||
expect: {
|
||||
new function() {
|
||||
this.x = 7,
|
||||
console.log(this);
|
||||
}();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1288_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
(function f() {})();
|
||||
}
|
||||
if (!x) {
|
||||
(function() {
|
||||
x = {};
|
||||
})();
|
||||
}
|
||||
if (y)
|
||||
(function() {})();
|
||||
else
|
||||
(function(z) {
|
||||
return z;
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w;
|
||||
x || (x = {});
|
||||
y;
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_in_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(a, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
x(a, b, c, d);
|
||||
}
|
||||
x(a, b, c, d);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in x(1, b, c)) {
|
||||
var c = 3, d = 4;
|
||||
x(1, b, c, d);
|
||||
}
|
||||
x(1, b, c, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
return g(a + 1);
|
||||
})(2);
|
||||
}
|
||||
expect: {
|
||||
g(3);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1758: {
|
||||
options = {
|
||||
inline: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(c) {
|
||||
var undefined = 42;
|
||||
return function() {
|
||||
c--;
|
||||
c--, c.toString();
|
||||
return;
|
||||
}();
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(c) {
|
||||
var undefined = 42;
|
||||
return c--, c--, void c.toString();
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
wrap_iife: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
}
|
||||
|
||||
wrap_iife_in_expression: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function() {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
expect_exact: 'foo=bar();'
|
||||
}
|
||||
|
||||
wrap_iife_in_return_call: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return (function() {
|
||||
console.log('test')
|
||||
})();
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))();'
|
||||
}
|
||||
|
||||
pure_annotation_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(function() {
|
||||
console.log("hello");
|
||||
}());
|
||||
}
|
||||
expect_exact: ""
|
||||
}
|
||||
|
||||
pure_annotation_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(function(n) {
|
||||
console.log("hello", n);
|
||||
}(42));
|
||||
}
|
||||
expect_exact: ""
|
||||
}
|
||||
|
||||
drop_fargs: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
keep_fargs: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
comparison_with_undefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a == undefined;
|
||||
a != undefined;
|
||||
a === undefined;
|
||||
a !== undefined;
|
||||
|
||||
undefined == a;
|
||||
undefined != a;
|
||||
undefined === a;
|
||||
undefined !== a;
|
||||
|
||||
void 0 == a;
|
||||
void 0 != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
expect: {
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
inline_script_off: {
|
||||
beautify = {
|
||||
inline_script: false,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("</sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
|
||||
inline_script_on: {
|
||||
beautify = {
|
||||
inline_script: true,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("<\\/sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
collapse: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
cascade: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -41,7 +41,7 @@ collapse: {
|
||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||
}
|
||||
function f2(b) {
|
||||
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
mangle: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var e = eval, x = 42;
|
||||
(function() {
|
||||
console.log(e("typeof x"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var e = eval, x = 42;
|
||||
(function() {
|
||||
console.log(e("typeof x"));
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
compress: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = 42;
|
||||
return eval("typeof a");
|
||||
}(), function(e) {
|
||||
var a = null;
|
||||
return e("typeof a");
|
||||
}(eval), function(eval) {
|
||||
var a = false;
|
||||
return eval("typeof a");
|
||||
}(eval), function(f) {
|
||||
var a = "STRING";
|
||||
var eval = f;
|
||||
return eval("typeof a");
|
||||
}(eval), function(g) {
|
||||
var a = eval;
|
||||
function eval() {
|
||||
return g;
|
||||
}
|
||||
return eval()("typeof a");
|
||||
}(eval));
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 42;
|
||||
return eval("typeof a");
|
||||
}(), (0, eval)("typeof a"), function(eval) {
|
||||
var a = false;
|
||||
return eval("typeof a");
|
||||
}(eval), function(f) {
|
||||
var a = "STRING";
|
||||
var eval = f;
|
||||
return eval("typeof a");
|
||||
}(eval), function(g) {
|
||||
var a = eval;
|
||||
function eval() {
|
||||
return g;
|
||||
}
|
||||
return eval()("typeof a");
|
||||
}(eval));
|
||||
}
|
||||
expect_stdout: "number undefined boolean string undefined"
|
||||
}
|
||||
|
||||
call_arg_1: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var z = "foo";
|
||||
(function() {
|
||||
var z = false;
|
||||
(function(e) {
|
||||
var z = 42;
|
||||
e("console.log(typeof z)");
|
||||
})(eval);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var z = "foo";
|
||||
(function() {
|
||||
var o = false;
|
||||
(function(o) {
|
||||
var a = 42;
|
||||
o("console.log(typeof z)");
|
||||
})(eval);
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
call_arg_2: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function eval() {
|
||||
console.log("PASS");
|
||||
}
|
||||
var z = "foo";
|
||||
(function() {
|
||||
var z = false;
|
||||
(function(e) {
|
||||
var z = 42;
|
||||
e("console.log(typeof z)");
|
||||
})(eval);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
function n() {
|
||||
console.log("PASS");
|
||||
}
|
||||
var o = "foo";
|
||||
(function() {
|
||||
var o = false;
|
||||
(function(o) {
|
||||
var n = 42;
|
||||
o("console.log(typeof z)");
|
||||
})(n);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
issue_44_valid_ast_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
options = { unused: true };
|
||||
input: {
|
||||
function a(b) {
|
||||
for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
@@ -16,9 +14,7 @@ issue_44_valid_ast_1: {
|
||||
}
|
||||
|
||||
issue_44_valid_ast_2: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
options = { unused: true };
|
||||
input: {
|
||||
function a(b) {
|
||||
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
keep_continue: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
}
|
||||
evaluate: true
|
||||
};
|
||||
input: {
|
||||
while (a) {
|
||||
if (b) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
NaN_and_Infinity_must_have_parens: {
|
||||
options = {}
|
||||
options = {};
|
||||
input: {
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
@@ -11,7 +11,7 @@ NaN_and_Infinity_must_have_parens: {
|
||||
}
|
||||
|
||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||
options = {}
|
||||
options = {};
|
||||
input: {
|
||||
var Infinity, NaN;
|
||||
Infinity.toString();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user