Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c01511f84 | ||
|
|
9faee3b66a | ||
|
|
8ea1ced389 | ||
|
|
24619daf68 | ||
|
|
b89cc84c3a | ||
|
|
3016a78d85 | ||
|
|
2508481e33 | ||
|
|
48c46fa9a7 | ||
|
|
7da49b5709 | ||
|
|
d837a46ebd | ||
|
|
d4303b62cc | ||
|
|
7d595e2eac | ||
|
|
9fc0ff5953 | ||
|
|
997d09bb33 | ||
|
|
b244b4ec21 | ||
|
|
b872ffee01 | ||
|
|
9a9543013c | ||
|
|
b98ce6c84f | ||
|
|
7b43b6396f | ||
|
|
67f8fcb103 | ||
|
|
352a944868 | ||
|
|
77c9116c91 | ||
|
|
e821787095 | ||
|
|
aa6e33e208 | ||
|
|
176581d732 | ||
|
|
01aa078e9c | ||
|
|
149d75c092 | ||
|
|
2619bff3cf | ||
|
|
4fb54b066f | ||
|
|
e124ef57e3 | ||
|
|
73e6b2550b | ||
|
|
241113200e | ||
|
|
6f3ab09319 | ||
|
|
3b5d5014e0 | ||
|
|
c36c3cb470 | ||
|
|
24b73a95fa | ||
|
|
862b1b77b5 | ||
|
|
b4944a31a4 | ||
|
|
58362d5ec7 | ||
|
|
01fa430a3e | ||
|
|
f4ee0f651c | ||
|
|
077512d151 | ||
|
|
e4848a7f5a | ||
|
|
f52b0e7c31 | ||
|
|
31e7d25cad | ||
|
|
12babdfe20 | ||
|
|
397e48b97e | ||
|
|
c7520b4b97 | ||
|
|
ad903e9240 | ||
|
|
83c3838b07 | ||
|
|
fa09f87589 | ||
|
|
2db1a141ab | ||
|
|
dd30ed6a9b | ||
|
|
cb50a2d192 | ||
|
|
20be5209c0 | ||
|
|
2a49760032 | ||
|
|
04ed818f0a | ||
|
|
10ca578ee5 | ||
|
|
955411e065 | ||
|
|
adcafce048 | ||
|
|
b1e05fd48a | ||
|
|
23b51287aa | ||
|
|
74dee5c445 | ||
|
|
ee27d87a08 | ||
|
|
62887f2c66 | ||
|
|
68b2dadc58 |
53
.github/workflows/build.yml
vendored
Normal file
53
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Build testing
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
jobs:
|
||||
ufuzz:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
options: [ '-mb braces', '--ie8 -c', '-mc', '--toplevel -mc passes=3,pure_getters,unsafe' ]
|
||||
script:
|
||||
- acorn.sh
|
||||
- bootstrap.sh
|
||||
- buble.sh
|
||||
- butternut.sh
|
||||
- mathjs.sh
|
||||
- rollup-es.sh
|
||||
- rollup-ts.sh
|
||||
- sucrase.sh
|
||||
- web-tooling-benchmark.sh
|
||||
include:
|
||||
- node: '14'
|
||||
script: acorn.sh
|
||||
- node: '14'
|
||||
script: bootstrap.sh
|
||||
- node: '14'
|
||||
script: buble.sh
|
||||
- node: '14'
|
||||
script: butternut.sh
|
||||
- node: '14'
|
||||
script: mathjs.sh
|
||||
- node: '8'
|
||||
script: rollup-es.sh
|
||||
- node: '14'
|
||||
script: rollup-ts.sh
|
||||
- node: '14'
|
||||
script: sucrase.sh
|
||||
- node: '14'
|
||||
script: web-tooling-benchmark.sh
|
||||
name: ${{ matrix.script }} ${{ matrix.options }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
OPTIONS: ${{ matrix.options }}
|
||||
SCRIPT: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Perform uglify, build & test
|
||||
shell: bash
|
||||
run: |
|
||||
. ./test/release/install.sh
|
||||
./test/release/$SCRIPT $OPTIONS
|
||||
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', latest ]
|
||||
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', '14', latest ]
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||
exclude:
|
||||
@@ -29,20 +29,5 @@ jobs:
|
||||
- name: Perform tests
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --branch v1.6.0 --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
|
||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||
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
|
||||
. ./test/release/install.sh
|
||||
node test/$TYPE
|
||||
|
||||
25
.github/workflows/ufuzz.yml
vendored
25
.github/workflows/ufuzz.yml
vendored
@@ -30,33 +30,10 @@ jobs:
|
||||
NODE: ${{ matrix.node }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install GNU Core Utilities
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
env:
|
||||
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 1
|
||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||
shell: bash
|
||||
run: |
|
||||
while !(brew install coreutils); do echo "'brew install' failed - retrying..."; done
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --branch v1.6.0 --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
|
||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||
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
|
||||
. ./test/release/install.sh
|
||||
if [[ $CAUSE == "schedule" ]]; then
|
||||
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
|
||||
else
|
||||
|
||||
270
README.md
270
README.md
@@ -92,6 +92,9 @@ a double dash to prevent input files being used as option arguments:
|
||||
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
||||
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
||||
as JSON to STDOUT respectively.
|
||||
--annotations Process and preserve comment annotations.
|
||||
(`/*@__PURE__*/` or `/*#__PURE__*/`)
|
||||
--no-annotations Ignore and discard comment annotations.
|
||||
--comments [filter] Preserve copyright comments in the output. By
|
||||
default this works like Google Closure, keeping
|
||||
JSDoc-style comments that contain "@license" or
|
||||
@@ -221,10 +224,10 @@ Example:
|
||||
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
||||
(comma-separated) options are supported:
|
||||
|
||||
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or
|
||||
- `eval` (default: `false`) — mangle names visible in scopes where `eval` or
|
||||
`with` are used.
|
||||
|
||||
- `reserved` (default: `[]`) -- when mangling is enabled but you want to
|
||||
- `reserved` (default: `[]`) — when mangling is enabled but you want to
|
||||
prevent certain names from being mangled, you can declare those names with
|
||||
`--mangle reserved` — pass a comma-separated list of names. For example:
|
||||
|
||||
@@ -491,46 +494,51 @@ if (result.error) throw result.error;
|
||||
|
||||
## Minify options
|
||||
|
||||
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
||||
- `annotations` — pass `false` to ignore all comment annotations and elide them
|
||||
from output. Useful when, for instance, external tools incorrectly applied
|
||||
`/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain
|
||||
comment annotations in output to allow for further processing downstream.
|
||||
|
||||
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||
Pass an object to specify custom [compress options](#compress-options).
|
||||
|
||||
- `ie8` (default `false`) -- set to `true` to support IE8.
|
||||
- `ie8` (default: `false`) — set to `true` to support IE8.
|
||||
|
||||
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
|
||||
- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||
of function names. Useful for code relying on `Function.prototype.name`.
|
||||
|
||||
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
||||
- `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
|
||||
an object to specify [mangle options](#mangle-options) (see below).
|
||||
|
||||
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
|
||||
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
|
||||
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
property names across multiple invocations of `minify()`. Note: this is
|
||||
a read/write property. `minify()` will read the name cache state of this
|
||||
object and update it during minification so that it may be
|
||||
reused or externally persisted by the user.
|
||||
|
||||
- `output` (default `null`) — pass an object if you wish to specify
|
||||
- `output` (default: `null`) — pass an object if you wish to specify
|
||||
additional [output options](#output-options). The defaults are optimized
|
||||
for best compression.
|
||||
|
||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||
- `parse` (default: `{}`) — pass an object if you wish to specify some
|
||||
additional [parse options](#parse-options).
|
||||
|
||||
- `sourceMap` (default `false`) -- pass an object if you wish to specify
|
||||
- `sourceMap` (default: `false`) — pass an object if you wish to specify
|
||||
[source map options](#source-map-options).
|
||||
|
||||
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
||||
- `toplevel` (default: `false`) — set to `true` if you wish to enable top level
|
||||
variable and function name mangling and to drop unused variables and functions.
|
||||
|
||||
- `v8` (default `false`) -- enable workarounds for Chrome & Node.js bugs.
|
||||
- `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
|
||||
|
||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||
- `warnings` (default: `false`) — pass `true` to return compressor warnings
|
||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||
|
||||
- `webkit` (default `false`) -- enable workarounds for Safari/WebKit bugs.
|
||||
- `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs.
|
||||
PhantomJS users should set this option to `true`.
|
||||
|
||||
## Minify options structure
|
||||
@@ -615,116 +623,121 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
## Parse options
|
||||
|
||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||
|
||||
- `html5_comments` (default `true`)
|
||||
- `html5_comments` (default: `true`)
|
||||
|
||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
||||
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||
|
||||
## Compress options
|
||||
|
||||
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
||||
- `annotations` (default: `true`) — Pass `false` to disable potentially dropping
|
||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||
example: `/*@__PURE__*/foo();`
|
||||
|
||||
- `arguments` (default: `true`) — replace `arguments[index]` with function
|
||||
parameter name whenever possible.
|
||||
|
||||
- `arrows` (default: `true`) -- apply optimizations to arrow functions
|
||||
- `arrows` (default: `true`) — apply optimizations to arrow functions
|
||||
|
||||
- `assignments` (default: `true`) -- apply optimizations to assignment expressions
|
||||
- `assignments` (default: `true`) — apply optimizations to assignment expressions
|
||||
|
||||
- `awaits` (default: `true`) -- apply optimizations to `await` expressions
|
||||
- `awaits` (default: `true`) — apply optimizations to `await` expressions
|
||||
|
||||
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
||||
- `booleans` (default: `true`) — various optimizations for boolean context,
|
||||
for example `!!a ? b : c → a ? b : c`
|
||||
|
||||
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
||||
- `collapse_vars` (default: `true`) — Collapse single-use non-constant variables,
|
||||
side effects permitting.
|
||||
|
||||
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
||||
- `comparisons` (default: `true`) — apply certain optimizations to binary nodes,
|
||||
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
|
||||
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||
|
||||
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
|
||||
- `conditionals` (default: `true`) — apply optimizations for `if`-s and conditional
|
||||
expressions
|
||||
|
||||
- `dead_code` (default: `true`) -- remove unreachable code
|
||||
- `dead_code` (default: `true`) — remove unreachable code
|
||||
|
||||
- `default_values` (default: `true`) -- drop overshadowed default values
|
||||
- `default_values` (default: `true`) — drop overshadowed default values
|
||||
|
||||
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
||||
- `directives` (default: `true`) — remove redundant or non-standard directives
|
||||
|
||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
||||
- `drop_console` (default: `false`) — Pass `true` to discard calls to
|
||||
`console.*` functions. If you wish to drop a specific function call
|
||||
such as `console.info` and/or retain side effects from function arguments
|
||||
after dropping the function call then use `pure_funcs` instead.
|
||||
|
||||
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
|
||||
- `drop_debugger` (default: `true`) — remove `debugger;` statements
|
||||
|
||||
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
|
||||
- `evaluate` (default: `true`) — Evaluate expression for shorter constant
|
||||
representation. Pass `"eager"` to always replace function calls whenever
|
||||
possible, or a positive integer to specify an upper bound for each individual
|
||||
evaluation in number of characters.
|
||||
|
||||
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
||||
- `expression` (default: `false`) — Pass `true` to preserve completion values
|
||||
from terminal statements without `return`, e.g. in bookmarklets.
|
||||
|
||||
- `functions` (default: `true`) -- convert declarations from `var` to `function`
|
||||
- `functions` (default: `true`) — convert declarations from `var` to `function`
|
||||
whenever possible.
|
||||
|
||||
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
||||
- `global_defs` (default: `{}`) — see [conditional compilation](#conditional-compilation)
|
||||
|
||||
- `hoist_exports` (default: `true`) -- hoist `export` statements to facilitate
|
||||
- `hoist_exports` (default: `true`) — hoist `export` statements to facilitate
|
||||
various `compress` and `mangle` optimizations.
|
||||
|
||||
- `hoist_funs` (default: `false`) -- hoist function declarations
|
||||
- `hoist_funs` (default: `false`) — hoist function declarations
|
||||
|
||||
- `hoist_props` (default: `true`) -- hoist properties from constant object and
|
||||
- `hoist_props` (default: `true`) — hoist properties from constant object and
|
||||
array literals into regular variables subject to a set of constraints. For example:
|
||||
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
|
||||
works best with `toplevel` and `mangle` enabled, alongside with `compress` option
|
||||
`passes` set to `2` or higher.
|
||||
|
||||
- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
|
||||
- `hoist_vars` (default: `false`) — hoist `var` declarations (this is `false`
|
||||
by default because it seems to increase the size of the output in general)
|
||||
|
||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||
- `if_return` (default: `true`) — optimizations for if/return and if/continue
|
||||
|
||||
- `imports` (default: `true`) -- drop unreferenced import symbols when used with `unused`
|
||||
- `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
|
||||
|
||||
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||
- `false` -- same as `0`
|
||||
- `0` -- disabled inlining
|
||||
- `1` -- inline simple functions
|
||||
- `2` -- inline functions with arguments
|
||||
- `3` -- inline functions with arguments and variables
|
||||
- `true` -- same as `3`
|
||||
- `inline` (default: `true`) — inline calls to function with simple/`return` statement:
|
||||
- `false` — same as `0`
|
||||
- `0` — disabled inlining
|
||||
- `1` — inline simple functions
|
||||
- `2` — inline functions with arguments
|
||||
- `3` — inline functions with arguments and variables
|
||||
- `true` — same as `3`
|
||||
|
||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||
- `join_vars` (default: `true`) — join consecutive `var` statements
|
||||
|
||||
- `keep_fargs` (default: `false`) -- discard unused function arguments except
|
||||
- `keep_fargs` (default: `false`) — discard unused function arguments except
|
||||
when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
|
||||
Pass `true` to always retain function arguments.
|
||||
|
||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
||||
- `keep_infinity` (default: `false`) — Pass `true` to prevent `Infinity` from
|
||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||
|
||||
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
|
||||
- `loops` (default: `true`) — optimizations for `do`, `while` and `for` loops
|
||||
when we can statically determine the condition.
|
||||
|
||||
- `merge_vars` (default: `true`) -- combine and reuse variables.
|
||||
- `merge_vars` (default: `true`) — combine and reuse variables.
|
||||
|
||||
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
|
||||
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
|
||||
where the return value is discarded, to avoid the parens that the
|
||||
code generator would insert.
|
||||
|
||||
- `objects` (default: `true`) -- compact duplicate keys in object literals.
|
||||
- `objects` (default: `true`) — compact duplicate keys in object literals.
|
||||
|
||||
- `passes` (default: `1`) -- The maximum number of times to run compress.
|
||||
- `passes` (default: `1`) — The maximum number of times to run compress.
|
||||
In some cases more than one pass leads to further compressed code. Keep in
|
||||
mind more passes will take more time.
|
||||
|
||||
- `properties` (default: `true`) -- rewrite property access using the dot notation, for
|
||||
- `properties` (default: `true`) — rewrite property access using the dot notation, for
|
||||
example `foo["bar"] → foo.bar`
|
||||
|
||||
- `pure_funcs` (default: `null`) -- You can pass an array of names and
|
||||
- `pure_funcs` (default: `null`) — You can pass an array of names and
|
||||
UglifyJS will assume that those functions do not produce side
|
||||
effects. DANGER: will not check if the name is redefined in scope.
|
||||
An example case here, for instance `var q = Math.floor(a/b)`. If
|
||||
@@ -736,24 +749,24 @@ to be `false` and all symbol names will be omitted.
|
||||
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||
are also under `mangle.reserved` to avoid mangling.
|
||||
|
||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
||||
- `pure_getters` (default: `"strict"`) — If you pass `true` for
|
||||
this, UglifyJS will assume that object property access
|
||||
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||
|
||||
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
|
||||
- `reduce_funcs` (default: `true`) — Allows single-use functions to be
|
||||
inlined as function expressions when permissible allowing further
|
||||
optimization. Enabled by default. Option depends on `reduce_vars`
|
||||
being enabled. Some code runs faster in the Chrome V8 engine if this
|
||||
option is disabled. Does not negatively impact other major browsers.
|
||||
|
||||
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
||||
- `reduce_vars` (default: `true`) — Improve optimization on variables assigned with and
|
||||
used as constant values.
|
||||
|
||||
- `rests` (default: `true`) -- apply optimizations to rest parameters
|
||||
- `rests` (default: `true`) — apply optimizations to rest parameters
|
||||
|
||||
- `sequences` (default: `true`) -- join consecutive simple statements using the
|
||||
- `sequences` (default: `true`) — join consecutive simple statements using the
|
||||
comma operator. May be set to a positive integer to specify the maximum number
|
||||
of consecutive comma sequences that will be generated. If this option is set to
|
||||
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
||||
@@ -762,70 +775,68 @@ to be `false` and all symbol names will be omitted.
|
||||
occasions the default sequences limit leads to very slow compress times in which
|
||||
case a value of `20` or less is recommended.
|
||||
|
||||
- `side_effects` (default: `true`) -- Pass `false` to disable potentially dropping
|
||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||
example: `/*@__PURE__*/foo();`
|
||||
- `side_effects` (default: `true`) — drop extraneous code which does not affect
|
||||
outcome of runtime execution.
|
||||
|
||||
- `spreads` (default: `true`) -- flatten spread expressions.
|
||||
- `spreads` (default: `true`) — flatten spread expressions.
|
||||
|
||||
- `strings` (default: `true`) -- compact string concatenations.
|
||||
- `strings` (default: `true`) — compact string concatenations.
|
||||
|
||||
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
||||
- `switches` (default: `true`) — de-duplicate and remove unreachable `switch` branches
|
||||
|
||||
- `templates` (default: `true`) -- compact template literals by embedding expressions
|
||||
- `templates` (default: `true`) — compact template literals by embedding expressions
|
||||
and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
|
||||
|
||||
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
|
||||
- `top_retain` (default: `null`) — prevent specific toplevel functions and
|
||||
variables from `unused` removal (can be array, comma-separated, RegExp or
|
||||
function. Implies `toplevel`)
|
||||
|
||||
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
|
||||
- `toplevel` (default: `false`) — drop unreferenced functions (`"funcs"`) and/or
|
||||
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
||||
both unreferenced functions and variables)
|
||||
|
||||
- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
|
||||
- `typeofs` (default: `true`) — Transforms `typeof foo == "undefined"` into
|
||||
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
||||
earlier versions due to known issues.
|
||||
|
||||
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
|
||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||
|
||||
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
|
||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
|
||||
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
|
||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||
- `unsafe_math` (default: `false`) — optimize numerical expressions like
|
||||
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||
|
||||
- `unsafe_proto` (default: `false`) -- optimize expressions like
|
||||
- `unsafe_proto` (default: `false`) — optimize expressions like
|
||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||
|
||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
||||
- `unsafe_regexp` (default: `false`) — enable substitutions of variables with
|
||||
`RegExp` values the same way as if they are constants.
|
||||
|
||||
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
||||
- `unsafe_undefined` (default: `false`) — substitute `void 0` if there is a
|
||||
variable named `undefined` in scope (variable name will be mangled, typically
|
||||
reduced to a single character)
|
||||
|
||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
||||
- `unused` (default: `true`) — drop unreferenced functions and variables (simple
|
||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||
|
||||
- `varify` (default: `true`) -- convert block-scoped declaractions into `var`
|
||||
- `varify` (default: `true`) — convert block-scoped declaractions into `var`
|
||||
whenever safe to do so
|
||||
|
||||
- `yields` (default: `true`) -- apply optimizations to `yield` expressions
|
||||
- `yields` (default: `true`) — apply optimizations to `yield` expressions
|
||||
|
||||
## Mangle options
|
||||
|
||||
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
|
||||
- `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
|
||||
where `eval` or `with` are used.
|
||||
|
||||
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
|
||||
- `reserved` (default: `[]`) — Pass an array of identifiers that should be
|
||||
excluded from mangling. Example: `["foo", "bar"]`.
|
||||
|
||||
- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
|
||||
- `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
|
||||
top level scope.
|
||||
|
||||
Examples:
|
||||
@@ -852,18 +863,18 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
||||
|
||||
### Mangle properties options
|
||||
|
||||
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
|
||||
- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
|
||||
DOM properties. Not recommended to override this setting.
|
||||
|
||||
- `debug` (default: `false`) -— Mangle names with the original name still present.
|
||||
- `debug` (default: `false`) — Mangle names with the original name still present.
|
||||
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
||||
|
||||
- `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
|
||||
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
|
||||
|
||||
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
|
||||
- `regex` (default: `null`) — Pass a RegExp literal to only mangle property
|
||||
names matching the regular expression.
|
||||
|
||||
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
|
||||
- `reserved` (default: `[]`) — Do not mangle property names listed in the
|
||||
`reserved` array.
|
||||
|
||||
## Output options
|
||||
@@ -872,19 +883,23 @@ The code generator tries to output shortest code possible by default. In
|
||||
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
||||
can pass additional arguments that control the code output:
|
||||
|
||||
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
||||
- `annotations` (default: `false`) — pass `true` to retain comment annotations
|
||||
`/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
|
||||
`comments` is set.
|
||||
|
||||
- `ascii_only` (default: `false`) — escape Unicode characters in strings and
|
||||
regexps (affects directives with non-ascii characters becoming invalid)
|
||||
|
||||
- `beautify` (default `true`) -- whether to actually beautify the output.
|
||||
- `beautify` (default: `true`) — whether to actually beautify the output.
|
||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||
when you want to generate minified code, in order to specify additional
|
||||
arguments, so you can use `-b beautify=false` to override it.
|
||||
|
||||
- `braces` (default `false`) -- always insert braces in `if`, `for`,
|
||||
- `braces` (default: `false`) — always insert braces in `if`, `for`,
|
||||
`do`, `while` or `with` statements, even if their body is a single
|
||||
statement.
|
||||
|
||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
||||
- `comments` (default: `false`) — pass `true` or `"all"` to preserve all
|
||||
comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
|
||||
`@license`, or `@preserve` (case-insensitive), a regular expression string
|
||||
(e.g. `/^!/`), or a function which returns `boolean`, e.g.
|
||||
@@ -894,53 +909,53 @@ can pass additional arguments that control the code output:
|
||||
}
|
||||
```
|
||||
|
||||
- `galio` (default `false`) -- enable workarounds for ANT Galio bugs
|
||||
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
|
||||
|
||||
- `indent_level` (default `4`)
|
||||
- `indent_level` (default: `4`)
|
||||
|
||||
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
||||
- `indent_start` (default: `0`) — prefix all lines by that many spaces
|
||||
|
||||
- `inline_script` (default `true`) -- escape HTML comments and the slash in
|
||||
- `inline_script` (default: `true`) — escape HTML comments and the slash in
|
||||
occurrences of `</script>` in strings
|
||||
|
||||
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
||||
- `keep_quoted_props` (default: `false`) — when turned on, prevents stripping
|
||||
quotes from property names in object literals.
|
||||
|
||||
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
|
||||
- `max_line_len` (default: `false`) — maximum line length (for uglified code)
|
||||
|
||||
- `preamble` (default `null`) -- when passed it must be a string and
|
||||
- `preamble` (default: `null`) — when passed it must be a string and
|
||||
it will be prepended to the output literally. The source map will
|
||||
adjust for this text. Can be used to insert a comment containing
|
||||
licensing information, for example.
|
||||
|
||||
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
|
||||
- `preserve_line` (default: `false`) — pass `true` to retain line numbering on
|
||||
a best effort basis.
|
||||
|
||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||
- `quote_keys` (default: `false`) — pass `true` to quote all keys in literal
|
||||
objects
|
||||
|
||||
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
||||
- `quote_style` (default: `0`) — preferred quote style for strings (affects
|
||||
quoted property names and directives as well):
|
||||
- `0` -- prefers double quotes, switches to single quotes when there are
|
||||
- `0` — prefers double quotes, switches to single quotes when there are
|
||||
more double quotes in the string itself. `0` is best for gzip size.
|
||||
- `1` -- always use single quotes
|
||||
- `2` -- always use double quotes
|
||||
- `3` -- always use the original quotes
|
||||
- `1` — always use single quotes
|
||||
- `2` — always use double quotes
|
||||
- `3` — always use the original quotes
|
||||
|
||||
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
||||
- `semicolons` (default: `true`) — separate statements with semicolons. If
|
||||
you pass `false` then whenever possible we will use a newline instead of a
|
||||
semicolon, leading to more readable output of uglified code (size before
|
||||
gzip could be smaller; size after gzip insignificantly larger).
|
||||
|
||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
||||
- `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts)
|
||||
|
||||
- `width` (default `80`) -- only takes effect when beautification is on, this
|
||||
- `width` (default: `80`) — only takes effect when beautification is on, this
|
||||
specifies an (orientative) line width that the beautifier will try to
|
||||
obey. It refers to the width of the line text (excluding indentation).
|
||||
It doesn't work very well currently, but it does make the code generated
|
||||
by UglifyJS more readable.
|
||||
|
||||
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
|
||||
- `wrap_iife` (default: `false`) — pass `true` to wrap immediately invoked
|
||||
function expressions. See
|
||||
[#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
|
||||
|
||||
@@ -1141,18 +1156,14 @@ in total it's a bit more than just using UglifyJS's own parser.
|
||||
It's not well known, but whitespace removal and symbol mangling accounts
|
||||
for 95% of the size reduction in minified code for most JavaScript - not
|
||||
elaborate code transforms. One can simply disable `compress` to speed up
|
||||
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
|
||||
comparable minify speeds and gzip sizes to
|
||||
[`butternut`](https://www.npmjs.com/package/butternut):
|
||||
Uglify builds by 3 to 5 times.
|
||||
|
||||
| d3.js | minify size | gzip size | minify time (seconds) |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| original | 451,131 | 108,733 | - |
|
||||
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
|
||||
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
|
||||
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
|
||||
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
|
||||
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
|
||||
| original | 511,371 | 119,932 | - |
|
||||
| uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 |
|
||||
| uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 |
|
||||
| uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 |
|
||||
|
||||
To enable fast minify mode from the CLI use:
|
||||
```
|
||||
@@ -1285,3 +1296,16 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// SyntaxError: Identifier 'e' has already been declared
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
console.log({
|
||||
...{
|
||||
set 42(v) {},
|
||||
42: "PASS",
|
||||
},
|
||||
});
|
||||
// Expected: { '42': 'PASS' }
|
||||
// Actual: { '42': undefined }
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
|
||||
22
bin/uglifyjs
22
bin/uglifyjs
@@ -95,6 +95,8 @@ function process_option(name, no_value) {
|
||||
" -b, --beautify [options] Beautify output/specify output options.",
|
||||
" -O, --output-opts <options> Output options (beautify disabled).",
|
||||
" -o, --output <file> Output file (default STDOUT).",
|
||||
" --annotations Process and preserve comment annotations.",
|
||||
" --no-annotations Ignore and discard comment annotations.",
|
||||
" --comments [filter] Preserve copyright comments in the output.",
|
||||
" --config-file <file> Read minify() options from JSON file.",
|
||||
" -d, --define <expr>[=value] Global definitions.",
|
||||
@@ -113,6 +115,9 @@ function process_option(name, no_value) {
|
||||
" --warn Print warning messages.",
|
||||
" --webkit Support non-standard Safari/Webkit.",
|
||||
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
|
||||
"",
|
||||
"(internal debug use only)",
|
||||
" --in-situ Warning: replaces original source files with minified output.",
|
||||
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
|
||||
].join("\n"));
|
||||
}
|
||||
@@ -139,6 +144,7 @@ function process_option(name, no_value) {
|
||||
case "enclose":
|
||||
options[name] = read_value();
|
||||
break;
|
||||
case "annotations":
|
||||
case "ie8":
|
||||
case "timings":
|
||||
case "toplevel":
|
||||
@@ -146,6 +152,9 @@ function process_option(name, no_value) {
|
||||
case "webkit":
|
||||
options[name] = true;
|
||||
break;
|
||||
case "no-annotations":
|
||||
options.annotations = false;
|
||||
break;
|
||||
case "keep-fnames":
|
||||
options.keep_fnames = true;
|
||||
break;
|
||||
@@ -194,6 +203,7 @@ function process_option(name, no_value) {
|
||||
case "no-rename":
|
||||
options.rename = false;
|
||||
break;
|
||||
case "in-situ":
|
||||
case "reduce-test":
|
||||
case "self":
|
||||
break;
|
||||
@@ -254,7 +264,17 @@ if (specified["self"]) {
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
paths = UglifyJS.FILES;
|
||||
}
|
||||
if (paths.length) {
|
||||
if (specified["in-situ"]) {
|
||||
if (output || specified["reduce-test"] || specified["self"]) fatal("incompatible options specified");
|
||||
paths.forEach(function(name) {
|
||||
print(name);
|
||||
if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified");
|
||||
files = {};
|
||||
files[convert_path(name)] = read_file(name);
|
||||
output = name;
|
||||
run();
|
||||
});
|
||||
} else if (paths.length) {
|
||||
simple_glob(paths).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
|
||||
20
lib/ast.js
20
lib/ast.js
@@ -55,9 +55,10 @@ function DEFNODE(type, props, methods, base) {
|
||||
props.forEach(function(prop) {
|
||||
code.push("this.", prop, "=props.", prop, ";");
|
||||
});
|
||||
code.push("}");
|
||||
var proto = base && new base;
|
||||
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
||||
code.push("}}");
|
||||
code.push("}");
|
||||
var ctor = new Function(code.join(""))();
|
||||
if (proto) {
|
||||
ctor.prototype = proto;
|
||||
@@ -139,7 +140,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
}, null);
|
||||
|
||||
(AST_Node.log_function = function(fn, verbose) {
|
||||
if (!fn) {
|
||||
if (typeof fn != "function") {
|
||||
AST_Node.info = AST_Node.warn = noop;
|
||||
return;
|
||||
}
|
||||
@@ -874,6 +875,7 @@ var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
||||
$documentation: "A `class` method",
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
|
||||
if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
|
||||
if (this.value.name != null) throw new Error("name of class method's lambda must be null");
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
@@ -1683,6 +1685,8 @@ var AST_ObjectMethod = DEFNODE("ObjectMethod", null, {
|
||||
$documentation: "A key(){} object property",
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
|
||||
if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
|
||||
if (this.value.name != null) throw new Error("name of class method's lambda must be null");
|
||||
},
|
||||
}, AST_ObjectKeyVal);
|
||||
|
||||
@@ -1809,10 +1813,20 @@ var AST_Super = DEFNODE("Super", null, {
|
||||
var AST_This = DEFNODE("This", null, {
|
||||
$documentation: "The `this` symbol",
|
||||
_validate: function() {
|
||||
if (this.name !== "this") throw new Error('name must be "this"');
|
||||
if (this.TYPE == "This" && this.name !== "this") throw new Error('name must be "this"');
|
||||
},
|
||||
}, AST_ObjectIdentity);
|
||||
|
||||
var AST_NewTarget = DEFNODE("NewTarget", null, {
|
||||
$documentation: "The `new.target` symbol",
|
||||
initialize: function() {
|
||||
this.name = "new.target";
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.name !== "new.target") throw new Error('name must be "new.target": ' + this.name);
|
||||
},
|
||||
}, AST_This);
|
||||
|
||||
var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
$documentation: "A template literal, i.e. tag`str1${expr1}...strN${exprN}strN+1`",
|
||||
$propdoc: {
|
||||
|
||||
699
lib/compress.js
699
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -47,14 +47,12 @@ function parse_source_map(content) {
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
if (options[name]) {
|
||||
keys.forEach(function(key) {
|
||||
if (options[key]) {
|
||||
if (typeof options[key] != "object") options[key] = {};
|
||||
if (!(name in options[key])) options[key][name] = options[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
keys.forEach(function(key) {
|
||||
if (options[key]) {
|
||||
if (typeof options[key] != "object") options[key] = {};
|
||||
if (!(name in options[key])) options[key][name] = options[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init_cache(cache) {
|
||||
@@ -75,6 +73,7 @@ function to_json(cache) {
|
||||
function minify(files, options) {
|
||||
try {
|
||||
options = defaults(options, {
|
||||
annotations: undefined,
|
||||
compress: {},
|
||||
enclose: false,
|
||||
ie8: false,
|
||||
@@ -94,17 +93,14 @@ function minify(files, options) {
|
||||
wrap: false,
|
||||
}, true);
|
||||
if (options.validate) AST_Node.enable_validation();
|
||||
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" ]);
|
||||
set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||
set_shorthand("webkit", options, [ "mangle", "output" ]);
|
||||
var timings = options.timings && { start: Date.now() };
|
||||
if (options.rename === undefined) options.rename = options.compress && options.mangle;
|
||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
||||
if (options.ie8) set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||
if (options.webkit) set_shorthand("webkit", options, [ "mangle", "output" ]);
|
||||
var quoted_props;
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
|
||||
138
lib/output.js
138
lib/output.js
@@ -52,6 +52,7 @@ function OutputStream(options) {
|
||||
|
||||
var readonly = !options;
|
||||
options = defaults(options, {
|
||||
annotations : false,
|
||||
ascii_only : false,
|
||||
beautify : false,
|
||||
braces : false,
|
||||
@@ -346,6 +347,7 @@ function OutputStream(options) {
|
||||
};
|
||||
|
||||
var indent = options.beautify ? function(half) {
|
||||
if (need_newline_indented) print("\n");
|
||||
print(repeat_string(" ", half ? indentation - (options.indent_level >> 1) : indentation));
|
||||
} : noop;
|
||||
|
||||
@@ -449,6 +451,27 @@ function OutputStream(options) {
|
||||
return /^ *$/.test(OUTPUT.slice(index + 1));
|
||||
}
|
||||
|
||||
function pad_comment(token, force) {
|
||||
if (need_newline_indented) return;
|
||||
if (token.nlb && (force || !has_nlb())) {
|
||||
need_newline_indented = true;
|
||||
} else if (force) {
|
||||
need_space = true;
|
||||
}
|
||||
}
|
||||
|
||||
function print_comment(comment) {
|
||||
var value = comment.value.replace(/[@#]__PURE__/g, " ");
|
||||
if (/^\s*$/.test(value) && !/^\s*$/.test(comment.value)) return false;
|
||||
if (/comment[134]/.test(comment.type)) {
|
||||
print("//" + value);
|
||||
need_newline_indented = true;
|
||||
} else if (comment.type == "comment2") {
|
||||
print("/*" + value + "*/");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepend_comments(node) {
|
||||
var self = this;
|
||||
var scan = node instanceof AST_Exit && node.value;
|
||||
@@ -488,35 +511,12 @@ function OutputStream(options) {
|
||||
}
|
||||
|
||||
comments = comments.filter(comment_filter, node);
|
||||
if (comments.length == 0) return;
|
||||
var last_nlb = has_nlb();
|
||||
comments.forEach(function(c, i) {
|
||||
if (!last_nlb) {
|
||||
if (c.nlb) {
|
||||
print("\n");
|
||||
indent();
|
||||
last_nlb = true;
|
||||
} else if (i > 0) {
|
||||
space();
|
||||
}
|
||||
}
|
||||
if (/comment[134]/.test(c.type)) {
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, " ") + "\n");
|
||||
indent();
|
||||
last_nlb = true;
|
||||
} else if (c.type == "comment2") {
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
|
||||
last_nlb = false;
|
||||
}
|
||||
var printed = false;
|
||||
comments.forEach(function(comment, index) {
|
||||
pad_comment(comment, index);
|
||||
if (print_comment(comment)) printed = true;
|
||||
});
|
||||
if (!last_nlb) {
|
||||
if (node.start.nlb) {
|
||||
print("\n");
|
||||
indent();
|
||||
} else {
|
||||
space();
|
||||
}
|
||||
}
|
||||
if (printed) pad_comment(node.start, true);
|
||||
|
||||
function dump(node) {
|
||||
var token = node.start;
|
||||
@@ -546,25 +546,9 @@ function OutputStream(options) {
|
||||
}))) return;
|
||||
comments._dumped = self;
|
||||
var insert = OUTPUT.length;
|
||||
comments.filter(comment_filter, node).forEach(function(c, i) {
|
||||
need_space = false;
|
||||
if (need_newline_indented) {
|
||||
print("\n");
|
||||
indent();
|
||||
need_newline_indented = false;
|
||||
} else if (c.nlb && (i > 0 || !has_nlb())) {
|
||||
print("\n");
|
||||
indent();
|
||||
} else if (i > 0 || !tail) {
|
||||
space();
|
||||
}
|
||||
if (/comment[134]/.test(c.type)) {
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, " "));
|
||||
need_newline_indented = true;
|
||||
} else if (c.type == "comment2") {
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
|
||||
need_space = true;
|
||||
}
|
||||
comments.filter(comment_filter, node).forEach(function(comment, index) {
|
||||
pad_comment(comment, index || !tail);
|
||||
print_comment(comment);
|
||||
});
|
||||
if (OUTPUT.length > insert) newline_insert = insert;
|
||||
}
|
||||
@@ -741,6 +725,8 @@ function OutputStream(options) {
|
||||
|| p instanceof AST_PropAccess && p.expression === this
|
||||
// ...(foo, bar, baz)
|
||||
|| p instanceof AST_Spread
|
||||
// (foo, bar)`baz`
|
||||
|| p instanceof AST_Template && p.tag === this
|
||||
// !(foo, bar, baz)
|
||||
|| p instanceof AST_Unary
|
||||
// var a = (1, 2), b = a + a; ---> b == 4
|
||||
@@ -1436,6 +1422,17 @@ function OutputStream(options) {
|
||||
});
|
||||
|
||||
/* -----[ other expressions ]----- */
|
||||
function print_annotation(self, output) {
|
||||
if (!output.option("annotations")) return;
|
||||
if (!self.pure) return;
|
||||
var level = 0, parent = self, node;
|
||||
do {
|
||||
node = parent;
|
||||
parent = output.parent(level++);
|
||||
if (parent instanceof AST_Call && parent.expression === node) return;
|
||||
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
||||
output.print("/*" + self.pure + "*/");
|
||||
}
|
||||
function print_call_args(self, output) {
|
||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||
output.add_mapping(self.start);
|
||||
@@ -1448,11 +1445,14 @@ function OutputStream(options) {
|
||||
});
|
||||
}
|
||||
DEFPRINT(AST_Call, function(output) {
|
||||
this.expression.print(output);
|
||||
print_call_args(this, output);
|
||||
var self = this;
|
||||
print_annotation(self, output);
|
||||
self.expression.print(output);
|
||||
print_call_args(self, output);
|
||||
});
|
||||
DEFPRINT(AST_New, function(output) {
|
||||
var self = this;
|
||||
print_annotation(self, output);
|
||||
output.print("new");
|
||||
output.space();
|
||||
self.expression.print(output);
|
||||
@@ -1588,7 +1588,14 @@ function OutputStream(options) {
|
||||
output.space();
|
||||
} : noop);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredKeyVal, print_key_value);
|
||||
DEFPRINT(AST_DestructuredKeyVal, function(output) {
|
||||
var self = this;
|
||||
var key = print_property_key(self, output);
|
||||
var value = self.value;
|
||||
if (key && value instanceof AST_SymbolDeclaration && key == get_symbol_name(value)) return;
|
||||
output.colon();
|
||||
value.print(output);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||
var props = this.properties, len = props.length, rest = this.rest;
|
||||
if (len || rest) output.with_block(function() {
|
||||
@@ -1651,20 +1658,19 @@ function OutputStream(options) {
|
||||
output.print_string(key, quote);
|
||||
} else {
|
||||
output.print_name(key);
|
||||
return key;
|
||||
}
|
||||
} else {
|
||||
output.print_string(key, quote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function print_key_value(output) {
|
||||
DEFPRINT(AST_ObjectKeyVal, function(output) {
|
||||
var self = this;
|
||||
print_property_key(self, output);
|
||||
output.colon();
|
||||
self.value.print(output);
|
||||
}
|
||||
DEFPRINT(AST_ObjectKeyVal, print_key_value);
|
||||
});
|
||||
DEFPRINT(AST_ObjectMethod, function(output) {
|
||||
print_method(this, output);
|
||||
});
|
||||
@@ -1683,32 +1689,36 @@ function OutputStream(options) {
|
||||
}
|
||||
DEFPRINT(AST_ObjectGetter, print_accessor("get"));
|
||||
DEFPRINT(AST_ObjectSetter, print_accessor("set"));
|
||||
function print_symbol(self, output) {
|
||||
var def = self.definition();
|
||||
output.print_name(def && def.mangled_name || self.name);
|
||||
function get_symbol_name(sym) {
|
||||
var def = sym.definition();
|
||||
return def && def.mangled_name || sym.name;
|
||||
}
|
||||
DEFPRINT(AST_Symbol, function(output) {
|
||||
print_symbol(this, output);
|
||||
output.print_name(get_symbol_name(this));
|
||||
});
|
||||
DEFPRINT(AST_SymbolExport, function(output) {
|
||||
var self = this;
|
||||
print_symbol(self, output);
|
||||
if (self.alias) {
|
||||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(self.alias);
|
||||
output.print_name(alias);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
if (self.key) {
|
||||
output.print_name(self.key);
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
}
|
||||
print_symbol(self, output);
|
||||
output.print_name(name);
|
||||
});
|
||||
DEFPRINT(AST_Hole, noop);
|
||||
DEFPRINT(AST_Template, function(output) {
|
||||
|
||||
157
lib/parse.js
157
lib/parse.js
@@ -100,6 +100,7 @@ var OPERATORS = makePredicate([
|
||||
"/=",
|
||||
"*=",
|
||||
"%=",
|
||||
"**=",
|
||||
">>=",
|
||||
"<<=",
|
||||
">>>=",
|
||||
@@ -160,10 +161,10 @@ function decode_escape_sequence(seq) {
|
||||
case "t": return "\t";
|
||||
case "u":
|
||||
var code;
|
||||
if (seq.length == 5) {
|
||||
code = seq.slice(1);
|
||||
} else if (seq[1] == "{" && seq.slice(-1) == "}") {
|
||||
if (seq[1] == "{" && seq.slice(-1) == "}") {
|
||||
code = seq.slice(2, -1);
|
||||
} else if (seq.length == 5) {
|
||||
code = seq.slice(1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -652,7 +653,7 @@ var UNARY_PREFIX = makePredicate("typeof void delete -- ++ ! ~ - +");
|
||||
|
||||
var UNARY_POSTFIX = makePredicate("-- ++");
|
||||
|
||||
var ASSIGNMENT = makePredicate("= += -= /= *= %= >>= <<= >>>= |= ^= &=");
|
||||
var ASSIGNMENT = makePredicate("= += -= /= *= %= **= >>= <<= >>>= |= ^= &=");
|
||||
|
||||
var PRECEDENCE = function(a, ret) {
|
||||
for (var i = 0; i < a.length;) {
|
||||
@@ -1053,6 +1054,16 @@ function parse($TEXT, options) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
function has_modifier(name) {
|
||||
if (!is("name", name)) return;
|
||||
var token = peek();
|
||||
if (!token) return;
|
||||
if (is_token(token, "operator", "=")) return;
|
||||
if (token.type == "punc" && /^[(;}]$/.test(token.value)) return;
|
||||
if (has_newline_before(token)) return;
|
||||
return next();
|
||||
}
|
||||
|
||||
function class_(ctor) {
|
||||
var was_async = S.in_async;
|
||||
var was_gen = S.in_generator;
|
||||
@@ -1078,16 +1089,8 @@ function parse($TEXT, options) {
|
||||
continue;
|
||||
}
|
||||
var start = S.token;
|
||||
var fixed = is("name", "static");
|
||||
if (fixed) next();
|
||||
var async = is("name", "async") && peek();
|
||||
if (async) {
|
||||
if (async.type == "punc" && /^[(=;}]$/.test(async.value) || has_newline_before(async)) {
|
||||
async = false;
|
||||
} else {
|
||||
async = next();
|
||||
}
|
||||
}
|
||||
var fixed = !!has_modifier("static");
|
||||
var async = has_modifier("async");
|
||||
if (is("operator", "*")) {
|
||||
next();
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
@@ -1502,14 +1505,14 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function export_default_decl() {
|
||||
switch (S.token.value) {
|
||||
case "async":
|
||||
if (is("name", "async")) {
|
||||
if (!is_token(peek(), "keyword", "function")) return;
|
||||
next();
|
||||
next();
|
||||
if (!is("operator", "*")) return maybe_named(AST_AsyncDefun, function_(AST_AsyncFunction));
|
||||
next();
|
||||
return maybe_named(AST_AsyncGeneratorDefun, function_(AST_AsyncGeneratorFunction));
|
||||
} else if (is("keyword")) switch (S.token.value) {
|
||||
case "class":
|
||||
next();
|
||||
return maybe_named(AST_DefClass, class_(AST_ClassExpression));
|
||||
@@ -1522,13 +1525,13 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
var export_decl = embed_tokens(function() {
|
||||
switch (S.token.value) {
|
||||
case "async":
|
||||
if (is("name", "async")) {
|
||||
next();
|
||||
expect_token("keyword", "function");
|
||||
if (!is("operator", "*")) return function_(AST_AsyncDefun);
|
||||
next();
|
||||
return function_(AST_AsyncGeneratorDefun);
|
||||
} else if (is("keyword")) switch (S.token.value) {
|
||||
case "class":
|
||||
next();
|
||||
return class_(AST_DefClass);
|
||||
@@ -1734,58 +1737,66 @@ function parse($TEXT, options) {
|
||||
var new_ = function(allow_calls) {
|
||||
var start = S.token;
|
||||
expect_token("operator", "new");
|
||||
var newexp = expr_atom(false), args;
|
||||
if (is("punc", "(")) {
|
||||
var call;
|
||||
if (is("punc", ".") && is_token(peek(), "name", "target")) {
|
||||
next();
|
||||
args = expr_list(")", !options.strict);
|
||||
next();
|
||||
call = new AST_NewTarget();
|
||||
} else {
|
||||
args = [];
|
||||
var exp = expr_atom(false), args;
|
||||
if (is("punc", "(")) {
|
||||
next();
|
||||
args = expr_list(")", !options.strict);
|
||||
} else {
|
||||
args = [];
|
||||
}
|
||||
call = new AST_New({ expression: exp, args: args });
|
||||
}
|
||||
var call = new AST_New({
|
||||
start : start,
|
||||
expression : newexp,
|
||||
args : args,
|
||||
end : prev()
|
||||
});
|
||||
mark_pure(call);
|
||||
call.start = start;
|
||||
call.end = prev();
|
||||
return subscripts(call, allow_calls);
|
||||
};
|
||||
|
||||
function as_atom_node() {
|
||||
var tok = S.token, ret;
|
||||
var ret, tok = S.token, value = tok.value;
|
||||
switch (tok.type) {
|
||||
case "num":
|
||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
case "bigint":
|
||||
ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({
|
||||
start : tok,
|
||||
end : tok,
|
||||
value : tok.value,
|
||||
quote : tok.quote
|
||||
});
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
case "atom":
|
||||
switch (tok.value) {
|
||||
case "false":
|
||||
ret = new AST_False({ start: tok, end: tok });
|
||||
break;
|
||||
case "true":
|
||||
ret = new AST_True({ start: tok, end: tok });
|
||||
break;
|
||||
case "null":
|
||||
ret = new AST_Null({ start: tok, end: tok });
|
||||
break;
|
||||
if (isFinite(value)) {
|
||||
ret = new AST_Number({ value: value });
|
||||
} else {
|
||||
ret = new AST_Infinity();
|
||||
if (value < 0) ret = new AST_UnaryPrefix({ operator: "-", expression: ret });
|
||||
}
|
||||
break;
|
||||
case "bigint":
|
||||
ret = new AST_BigInt({ value: value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({ value : value, quote : tok.quote });
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ value: value });
|
||||
break;
|
||||
case "atom":
|
||||
switch (value) {
|
||||
case "false":
|
||||
ret = new AST_False();
|
||||
break;
|
||||
case "true":
|
||||
ret = new AST_True();
|
||||
break;
|
||||
case "null":
|
||||
ret = new AST_Null();
|
||||
break;
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
next();
|
||||
ret.start = ret.end = tok;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1825,11 +1836,13 @@ function parse($TEXT, options) {
|
||||
expect(")");
|
||||
var end = prev();
|
||||
end.comments_before = ex.end.comments_before;
|
||||
[].push.apply(ex.end.comments_after, end.comments_after);
|
||||
end.comments_after.forEach(function(comment) {
|
||||
ex.end.comments_after.push(comment);
|
||||
if (comment.nlb) S.token.nlb = true;
|
||||
});
|
||||
end.comments_after.length = 0;
|
||||
end.comments_after = ex.end.comments_after;
|
||||
ex.end = end;
|
||||
if (ex instanceof AST_Call) mark_pure(ex);
|
||||
if (is("punc", "=>")) return arrow(ex instanceof AST_Sequence ? ex.expressions : [ ex ], start);
|
||||
return subscripts(ex, allow_calls);
|
||||
case "[":
|
||||
@@ -2206,19 +2219,6 @@ function parse($TEXT, options) {
|
||||
});
|
||||
}
|
||||
|
||||
function mark_pure(call) {
|
||||
var start = call.start;
|
||||
var comments = start.comments_before;
|
||||
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
|
||||
while (--i >= 0) {
|
||||
var comment = comments[i];
|
||||
if (/[@#]__PURE__/.test(comment.value)) {
|
||||
call.pure = comment;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function template(tag) {
|
||||
var read = S.input.context().read_template;
|
||||
var strings = [];
|
||||
@@ -2266,7 +2266,6 @@ function parse($TEXT, options) {
|
||||
args : expr_list(")", !options.strict),
|
||||
end : prev()
|
||||
});
|
||||
mark_pure(call);
|
||||
return subscripts(call, true);
|
||||
}
|
||||
if (is("punc", "`")) {
|
||||
@@ -2275,6 +2274,18 @@ function parse($TEXT, options) {
|
||||
tmpl.end = prev();
|
||||
return subscripts(tmpl, allow_calls);
|
||||
}
|
||||
if (expr instanceof AST_Call && !expr.pure) {
|
||||
var start = expr.start;
|
||||
var comments = start.comments_before;
|
||||
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
|
||||
while (--i >= 0) {
|
||||
var match = /[@#]__PURE__/.exec(comments[i].value);
|
||||
if (match) {
|
||||
expr.pure = match[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
};
|
||||
|
||||
|
||||
18
lib/scope.js
18
lib/scope.js
@@ -96,8 +96,10 @@ SymbolDef.prototype = {
|
||||
|| this.undeclared
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||
&& (this.orig[0] instanceof AST_SymbolClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefun
|
||||
|| this.orig[0] instanceof AST_SymbolLambda);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -198,9 +200,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
} else if (node instanceof AST_SymbolConst) {
|
||||
var def = scope.def_variable(node);
|
||||
def.defun = defun;
|
||||
def.exported = exported;
|
||||
if (exported) def.exported = true;
|
||||
} else if (node instanceof AST_SymbolDefun) {
|
||||
defun.def_function(node, tw.parent()).exported = exported;
|
||||
var def = defun.def_function(node, tw.parent());
|
||||
if (exported) def.exported = true;
|
||||
entangle(defun, scope);
|
||||
} else if (node instanceof AST_SymbolFunarg) {
|
||||
defun.def_variable(node);
|
||||
@@ -209,9 +212,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
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_SymbolLet) {
|
||||
scope.def_variable(node).exported = exported;
|
||||
var def = scope.def_variable(node);
|
||||
if (exported) def.exported = true;
|
||||
} else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null).exported = exported;
|
||||
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
|
||||
if (exported) def.exported = true;
|
||||
entangle(defun, scope);
|
||||
}
|
||||
|
||||
@@ -435,6 +440,7 @@ AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
});
|
||||
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
return this;
|
||||
});
|
||||
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.13.0",
|
||||
"version": "3.13.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -10,33 +10,38 @@ var sandbox = require("./sandbox");
|
||||
var semver = require("semver");
|
||||
var U = require("./node");
|
||||
|
||||
var file = process.argv[2];
|
||||
var batch = 50;
|
||||
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||
if (file) {
|
||||
if (process.argv.length > 3) {
|
||||
var file = process.argv[2];
|
||||
var start = process.argv[3] | 0;
|
||||
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) {
|
||||
process.exit(Object.keys(tests).slice(start, start + batch).filter(function(name) {
|
||||
return !test_case(tests[name]);
|
||||
}).length);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir).filter(function(name) {
|
||||
var files = process.argv.length == 3 ? [ process.argv[2] ] : 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 ], {
|
||||
(function next(file, start, length) {
|
||||
if (start < length) {
|
||||
child_process.spawn(process.argv[0], [ process.argv[1], file, start, batch ], {
|
||||
stdio: [ "ignore", 1, 2 ]
|
||||
}).on("exit", function(code) {
|
||||
if (code) {
|
||||
failures += code;
|
||||
failed_files[file] = code;
|
||||
failed_files[file] = true;
|
||||
}
|
||||
next();
|
||||
next(file, start + batch, length);
|
||||
});
|
||||
} else if (file = files.shift()) {
|
||||
log("--- {file}", { file: file });
|
||||
start = 0;
|
||||
length = Object.keys(parse_test(path.resolve(dir, file))).length;
|
||||
next(file, start, length);
|
||||
} else if (failures) {
|
||||
console.error();
|
||||
console.error("!!! Failed " + failures + " test case(s).");
|
||||
@@ -257,6 +262,7 @@ function test_case(test) {
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input_formatted = make_code(test.input, {
|
||||
annotations: true,
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
keep_quoted_props: true,
|
||||
|
||||
473
test/compress/annotations.js
Normal file
473
test/compress/annotations.js
Normal file
@@ -0,0 +1,473 @@
|
||||
issue_2629_1: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a();
|
||||
/*@__PURE__*/ (b());
|
||||
(/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ d());
|
||||
}
|
||||
expect_exact: "c();"
|
||||
}
|
||||
|
||||
issue_2629_2: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a(1)(2)(3);
|
||||
/*@__PURE__*/ (b(1))(2)(3);
|
||||
/*@__PURE__*/ (c(1)(2))(3);
|
||||
/*@__PURE__*/ (d(1)(2)(3));
|
||||
(/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ f(1))(2)(3);
|
||||
(/*@__PURE__*/ g(1)(2))(3);
|
||||
(/*@__PURE__*/ h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"e(1)(2)(3);",
|
||||
"f(1)(2)(3);",
|
||||
"g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_3: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
||||
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"h.x(1).y(2).z(3);",
|
||||
"i.x(1).y(2).z(3);",
|
||||
"j.x(1).y(2).z(3);",
|
||||
"k.x(1).y(2).z(3);",
|
||||
"l.x(1).y(2).z(3);",
|
||||
"m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_4: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ x(), y());
|
||||
(w(), /*@__PURE__*/ x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2629_5: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ x() ];
|
||||
[ /*@__PURE__*/ x(), y() ];
|
||||
[ w(), /*@__PURE__*/ x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2638: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(g() || h())(x(), y());
|
||||
(/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"x(),y();",
|
||||
"(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_1: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a();
|
||||
/*@__PURE__*/ (new b());
|
||||
new (/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ new d());
|
||||
}
|
||||
expect_exact: [
|
||||
"new c;",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_2: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a(1)(2)(3);
|
||||
/*@__PURE__*/ new (b(1))(2)(3);
|
||||
/*@__PURE__*/ new (c(1)(2))(3);
|
||||
/*@__PURE__*/ new (d(1)(2)(3));
|
||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ new f(1))(2)(3);
|
||||
(/*@__PURE__*/ new g(1)(2))(3);
|
||||
(/*@__PURE__*/ new h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new e(1)(2)(3);",
|
||||
"new f(1)(2)(3);",
|
||||
"new g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_3: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new h.x(1).y(2).z(3);",
|
||||
"/* */new i.x(1).y(2).z(3);",
|
||||
"new j.x(1).y(2).z(3);",
|
||||
"new k.x(1).y(2).z(3);",
|
||||
"new l.x(1).y(2).z(3);",
|
||||
"new m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_4: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ new x(), y());
|
||||
(w(), /*@__PURE__*/ new x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_5: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ new x() ];
|
||||
[ /*@__PURE__*/ new x(), y() ];
|
||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_6: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/new (g() || h())(x(), y());
|
||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"x(),y();",
|
||||
"/* */new(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3858: {
|
||||
options = {
|
||||
annotations: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
var f = function(a) {
|
||||
return function() {
|
||||
console.log(a);
|
||||
}();
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inline_pure_call_1: {
|
||||
options = {
|
||||
annotations: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
inline_pure_call_2: {
|
||||
options = {
|
||||
annotations: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
var a = f("PASS");
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
inline_pure_call_3: {
|
||||
options = {
|
||||
annotations: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
var a = f("PASS");
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
console.log("PASS");
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
inline_pure_call_4: {
|
||||
options = {
|
||||
annotations: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = /*@__PURE__*/ function() {
|
||||
return console.log("PASS"), 42;
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
return console.log("PASS"), 42;
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
compress_and_output_annotations_enabled: {
|
||||
options = {
|
||||
annotations: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
annotations: true,
|
||||
beautify: true,
|
||||
comments: false,
|
||||
}
|
||||
input: {
|
||||
var top = /*@__PURE__*/ foo();
|
||||
/*@__PURE__*/ a(1)(2)(3);
|
||||
/*@__PURE__*/ (b(1))(2)(3);
|
||||
/*@__PURE__*/ (c(1)(2))(3);
|
||||
/*@__PURE__*/ (d(1)(2)(3));
|
||||
(/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ f(1))(2)(3);
|
||||
(/*@__PURE__*/ g(1)(2))(3);
|
||||
(/*@__PURE__*/ h(1)(2)(3));
|
||||
/*@__PURE__*/ l(1).p(2);
|
||||
(/*@__PURE__*/ m(1)).p(2);
|
||||
(/*@__PURE__*/ n(1).p)(2);
|
||||
(/*@__PURE__*/ o(1).p(2));
|
||||
}
|
||||
expect_exact: [
|
||||
"var top = /*@__PURE__*/foo();",
|
||||
"",
|
||||
"e(1)(2)(3);",
|
||||
"",
|
||||
"f(1)(2)(3);",
|
||||
"",
|
||||
"g(1)(2)(3);",
|
||||
"",
|
||||
"m(1).p(2);",
|
||||
"",
|
||||
"n(1).p(2);",
|
||||
]
|
||||
}
|
||||
|
||||
compress_annotations_disabled_output_annotations_enabled: {
|
||||
options = {
|
||||
annotations: false,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
annotations: true,
|
||||
comments: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a(1+2);
|
||||
/*#__PURE__*/ (b(2+3));
|
||||
(/*@__PURE__*/ c)(side_effect);
|
||||
(/*#__PURE__*/ d(effect()));
|
||||
}
|
||||
expect_exact: [
|
||||
"/*@__PURE__*/a(3),",
|
||||
"/*#__PURE__*/b(5),",
|
||||
"c(side_effect),",
|
||||
"/*#__PURE__*/d(effect());",
|
||||
]
|
||||
}
|
||||
|
||||
compress_and_output_annotations_disabled: {
|
||||
options = {
|
||||
annotations: false,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
annotations: false,
|
||||
comments: true,
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a(1+2);
|
||||
/*@__PURE__*/ (b(2+3));
|
||||
(/*@__PURE__*/ c)(side_effect);
|
||||
(/*@__PURE__*/ d(effect()));
|
||||
}
|
||||
expect_exact: [
|
||||
"a(3),",
|
||||
"b(5),",
|
||||
"c(side_effect),",
|
||||
"d(effect());",
|
||||
]
|
||||
}
|
||||
@@ -84,6 +84,7 @@ replace_index_drop_fargs_1: {
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
@@ -119,7 +120,7 @@ replace_index_drop_fargs_1: {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
console.log("bar"[1], "bar"[1], "bar".foo);
|
||||
})("bar", 42);
|
||||
(function(argument_0, argument_1) {
|
||||
var arguments;
|
||||
@@ -649,6 +650,7 @@ issue_3420_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
@@ -671,6 +673,7 @@ issue_3420_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var foo = function() {
|
||||
@@ -691,6 +694,7 @@ issue_3420_3: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -713,6 +717,7 @@ issue_3420_4: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
@@ -738,6 +743,7 @@ issue_3420_5: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -765,6 +771,7 @@ issue_3420_6: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
@@ -783,6 +790,7 @@ issue_3420_7: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -827,6 +835,7 @@ issue_4291_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
@@ -847,6 +856,7 @@ issue_4291_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
@@ -857,8 +867,8 @@ issue_4291_2: {
|
||||
console.log(a[1], a[0], a.length);
|
||||
}
|
||||
expect: {
|
||||
var a = function(argument_0) {
|
||||
if (argument_0)
|
||||
var a = function() {
|
||||
if (arguments[0])
|
||||
arguments[1] = "PASS";
|
||||
return arguments;
|
||||
}(42);
|
||||
@@ -871,6 +881,7 @@ issue_4397: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
@@ -999,3 +1010,26 @@ issue_4696: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4809: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
A = 0;
|
||||
(function() {
|
||||
arguments[A] = "PASS";
|
||||
console.log(arguments[0]);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
A = 0;
|
||||
(function() {
|
||||
arguments[A] = "PASS";
|
||||
console.log(arguments[0]);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@ drop_arguments: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
@@ -803,3 +804,13 @@ issue_4687_2: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4772: {
|
||||
input: {
|
||||
var f = a => (a)
|
||||
/**/ console.log(f("PASS"));
|
||||
}
|
||||
expect_exact: 'var f=a=>a;console.log(f("PASS"));'
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -23,16 +23,34 @@ async_label: {
|
||||
}
|
||||
|
||||
await_await: {
|
||||
options = {
|
||||
awaits: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
console.log("PASS");
|
||||
await await 42;
|
||||
await await {
|
||||
then(resolve) {
|
||||
resolve({
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
console.log("PASS");
|
||||
await await 42;
|
||||
await {
|
||||
then(resolve) {
|
||||
resolve({
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -546,7 +564,7 @@ drop_return: {
|
||||
input: {
|
||||
(async function(a) {
|
||||
while (!console);
|
||||
return console.log(a);
|
||||
return !console.log(a);
|
||||
})(42);
|
||||
}
|
||||
expect: {
|
||||
@@ -596,14 +614,14 @@ functions: {
|
||||
async function b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = async function(c) {
|
||||
async function c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (await c(await b(await a()))) {
|
||||
async function d() {}
|
||||
async function e() {
|
||||
return typeof e;
|
||||
}
|
||||
var d = async function() {};
|
||||
var e = async function y() {
|
||||
return typeof y;
|
||||
};
|
||||
var f = async function(f) {
|
||||
return f;
|
||||
};
|
||||
@@ -654,9 +672,9 @@ functions_use_strict: {
|
||||
async function b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = async function(c) {
|
||||
async function c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (await c(await b(await a()))) {
|
||||
var d = async function() {};
|
||||
var e = async function y() {
|
||||
@@ -673,6 +691,54 @@ functions_use_strict: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
functions_anonymous: {
|
||||
options = {
|
||||
functions: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var await = async function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
await(await);
|
||||
}
|
||||
expect: {
|
||||
async function await() {
|
||||
console.log("PASS");
|
||||
}
|
||||
await();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
functions_inner_var: {
|
||||
options = {
|
||||
functions: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var await = function a() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
};
|
||||
await(await);
|
||||
}
|
||||
expect: {
|
||||
function await() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
}
|
||||
await();
|
||||
}
|
||||
expect_stdout: "undefined undefined"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4335_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1246,3 +1312,222 @@ issue_4618: {
|
||||
expect_stdout: "function"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4717: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
async function f() {
|
||||
var a = function() {
|
||||
await;
|
||||
}();
|
||||
return "FAIL";
|
||||
}
|
||||
return f();
|
||||
})().then(console.log).catch(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
return function() {
|
||||
await;
|
||||
}(), "FAIL";
|
||||
})().then(console.log).catch(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4738_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await {
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await {
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4738_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await {
|
||||
get then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await {
|
||||
get then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4738_3: {
|
||||
options = {
|
||||
awaits: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await {
|
||||
then: function() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await {
|
||||
then: function() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4747: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
async function f() {
|
||||
a = "PASS";
|
||||
null.p += "PASS";
|
||||
}
|
||||
f();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
(async function() {
|
||||
a = "PASS";
|
||||
null.p += "PASS";
|
||||
})();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4764_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
return {
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
return {
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4764_2: {
|
||||
options = {
|
||||
arrows: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async () => ({
|
||||
get then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
}))();
|
||||
}
|
||||
expect: {
|
||||
(async () => ({
|
||||
get then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
}))();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4764_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function(o) {
|
||||
return o;
|
||||
})({
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(async function(o) {
|
||||
return o;
|
||||
})({
|
||||
then() {
|
||||
console.log("PASS");
|
||||
},
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -60,3 +60,33 @@ issue_4590: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4801: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
(function(a) {
|
||||
A = 42;
|
||||
a || A;
|
||||
})(!(0 == 42 >> 0o644n));
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
0 != (A = 42) >> 0o644n || A;
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
@@ -82,6 +82,19 @@ fields: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
modifier_as_field_name: {
|
||||
input: {
|
||||
for (var k in new class { async; static = 42 })
|
||||
console.log(k);
|
||||
}
|
||||
expect_exact: "for(var k in new class{async;static=42})console.log(k);"
|
||||
expect_stdout: [
|
||||
"async",
|
||||
"static",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
methods: {
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -125,7 +138,7 @@ private_methods: {
|
||||
}
|
||||
expect_exact: "(new class A{static*#f(){yield 3*A.#p}async #g(){for(var a of A.#f())return a*await 2}static get #p(){return 7}get q(){return this.#g()}}).q.then(console.log);"
|
||||
expect_stdout: "42"
|
||||
node_version: ">=14"
|
||||
node_version: ">=14.6"
|
||||
}
|
||||
|
||||
await: {
|
||||
@@ -256,6 +269,43 @@ block_scoped: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_extends: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var f = () => {};
|
||||
class A extends f {
|
||||
get p() {}
|
||||
}
|
||||
A.q = 42;
|
||||
return class B extends A {};
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends (() => {}) {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_extends: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
@@ -357,7 +407,7 @@ static_side_effects: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
single_use: {
|
||||
single_use_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -376,6 +426,163 @@ single_use: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {
|
||||
f(a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
new A().f("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
new class {
|
||||
f(a) {
|
||||
console.log(a);
|
||||
}
|
||||
}().f("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {
|
||||
f() {
|
||||
return A;
|
||||
}
|
||||
}
|
||||
console.log(typeof new A().f());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof new class A {
|
||||
f() {
|
||||
return A;
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(new class A {
|
||||
f() {
|
||||
return typeof A;
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(new class A {
|
||||
f() {
|
||||
return typeof A;
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_5: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log("foo");
|
||||
}
|
||||
(function() {
|
||||
"use strict";
|
||||
class A extends f {
|
||||
f() {
|
||||
console.log("bar");
|
||||
}
|
||||
}
|
||||
console.log("baz");
|
||||
new A().f();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
console.log("foo");
|
||||
}
|
||||
(function() {
|
||||
"use strict";
|
||||
class A extends f {
|
||||
f() {
|
||||
console.log("bar");
|
||||
}
|
||||
}
|
||||
console.log("baz");
|
||||
new A().f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_6: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {
|
||||
[(console.log("foo"), "f")]() {
|
||||
console.log("bar");
|
||||
}
|
||||
}
|
||||
console.log("baz");
|
||||
new A().f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {
|
||||
[(console.log("foo"), "f")]() {
|
||||
console.log("bar");
|
||||
}
|
||||
}
|
||||
console.log("baz");
|
||||
new A().f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
collapse_non_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -413,11 +620,10 @@ collapse_rhs: {
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
a = "PASS";
|
||||
class A {
|
||||
p = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
console.log(a = "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
@@ -519,7 +725,7 @@ unused_await: {
|
||||
(() => console.log(await))();
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_stdout: true
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
@@ -573,6 +779,99 @@ computed_key_generator: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_fnames: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class Foo {}
|
||||
console.log(Foo.name, class Bar {}.name);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class Foo {}
|
||||
console.log(Foo.name, class Bar {}.name);
|
||||
}
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
var unused = class {};
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_805_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
class unused {}
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4681: {
|
||||
options = {
|
||||
unused: true,
|
||||
@@ -768,3 +1067,232 @@ issue_4705: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4720: {
|
||||
options = {
|
||||
ie8: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static p = function f() {};
|
||||
}
|
||||
console.log(typeof A.p, typeof f);
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static p = function f() {};
|
||||
}
|
||||
console.log(typeof A.p, typeof f);
|
||||
}
|
||||
expect_stdout: "function undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4721: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "foo";
|
||||
try {
|
||||
(class extends 42 {
|
||||
[a = "bar"]() {}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "foo";
|
||||
try {
|
||||
(class extends 42 {
|
||||
[a = "bar"]() {}
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4722_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends function*() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends function*() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4722_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends async function() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends async function() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4722_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends async function*() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(class extends async function*() {} {});
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4725_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof new class {
|
||||
f() {
|
||||
return function g() {
|
||||
return g;
|
||||
}();
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof new class {
|
||||
f() {
|
||||
return function g() {
|
||||
return g;
|
||||
}();
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4725_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
new class {
|
||||
f() {
|
||||
return function() {
|
||||
while (console.log("PASS"));
|
||||
}();
|
||||
}
|
||||
}().f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
new class {
|
||||
f() {
|
||||
while (console.log("PASS"));
|
||||
}
|
||||
}().f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
new_target: {
|
||||
input: {
|
||||
console.log(typeof new class {
|
||||
constructor() {
|
||||
this.f = () => new.target;
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof new class {
|
||||
constructor() {
|
||||
this.f = () => new.target;
|
||||
}
|
||||
}().f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4756: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
class A extends 42 {
|
||||
static [console.log("foo")] = console.log("bar");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("baz");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(class extends 42 {
|
||||
[console.log("foo")]() {}
|
||||
}),
|
||||
(() => console.log("bar"))();
|
||||
} catch (e) {
|
||||
console.log("baz");
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
@@ -958,8 +958,7 @@ collapse_vars_misc: {
|
||||
}
|
||||
expect: {
|
||||
function f0(o, a, h) {
|
||||
var b = 3 - a;
|
||||
return o.run(b)[7] = h;
|
||||
return o.run(3 - a)[7] = h;
|
||||
}
|
||||
function f1(x) { return 5 - x }
|
||||
function f2(x) { return foo() / (5 - x) }
|
||||
@@ -2276,8 +2275,8 @@ var_defs: {
|
||||
}
|
||||
expect: {
|
||||
var f1 = function(x, y) {
|
||||
var r = x + y, z = r * r - r, b = 7;
|
||||
console.log(z + b);
|
||||
var r = x + y;
|
||||
console.log(r * r - r + 7);
|
||||
};
|
||||
f1("1", 0);
|
||||
}
|
||||
@@ -2907,8 +2906,7 @@ issue_2187_1: {
|
||||
var a = 1;
|
||||
!function(foo) {
|
||||
foo();
|
||||
var a = 2;
|
||||
console.log(a);
|
||||
console.log(2);
|
||||
}(function() {
|
||||
console.log(a);
|
||||
});
|
||||
@@ -6961,8 +6959,7 @@ sequence_in_iife_2: {
|
||||
}
|
||||
expect: {
|
||||
var a = "foo", b = 42;
|
||||
b = a;
|
||||
console.log(a, b);
|
||||
console.log(a, b = a);
|
||||
}
|
||||
expect_stdout: "foo foo"
|
||||
}
|
||||
@@ -8756,3 +8753,130 @@ issue_4586_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4732_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function(b) {
|
||||
var b = a++;
|
||||
var c = b ? b && console.log("PASS") : 0;
|
||||
})(a++);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(function(b) {
|
||||
(b = a++) && (b && console.log("PASS"));
|
||||
})(a++);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4732_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function(b) {
|
||||
var b = a++;
|
||||
var c = b ? b && console.log("PASS") : 0;
|
||||
})(a++);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(function(b) {
|
||||
(b = a++) && b && console.log("PASS");
|
||||
})(a++);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
dot_in_try: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o, a = 6, b = 7, c;
|
||||
try {
|
||||
c = a * b;
|
||||
o.p(c);
|
||||
} catch (e) {
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o, a = 6, b = 7, c;
|
||||
try {
|
||||
c = a * b;
|
||||
o.p(c);
|
||||
} catch (e) {
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
dot_non_local: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o, a = 6, b = 7, c;
|
||||
function f() {
|
||||
c = a * b;
|
||||
o.p(c);
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o, a = 6, b = 7, c;
|
||||
function f() {
|
||||
c = a * b;
|
||||
o.p(c);
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_4806: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a, o = {
|
||||
f: function() {
|
||||
console.log(this === o ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(a = 42, o.f)(42);
|
||||
}
|
||||
expect: {
|
||||
var a, o = {
|
||||
f: function() {
|
||||
console.log(this === o ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(0, o.f)(a = 42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -3274,3 +3274,86 @@ issue_4662: {
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
issue_4806_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
var a;
|
||||
(a = 42, O.f)();
|
||||
a;
|
||||
}
|
||||
expect: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(0, O.f)();
|
||||
42;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4806_2: {
|
||||
options = {
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
var a;
|
||||
(a = 42, O.f)();
|
||||
a;
|
||||
}
|
||||
expect: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
},
|
||||
(0, O.f)();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4806_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
var a;
|
||||
(a = 42, O.f)();
|
||||
a;
|
||||
}
|
||||
expect: {
|
||||
O = {
|
||||
f: function() {
|
||||
console.log(this === O ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(0, O.f)();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -847,6 +847,8 @@ unsafe_charAt_noop: {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
s = "foo";
|
||||
x = 42;
|
||||
console.log(
|
||||
s.charAt(0),
|
||||
"string".charAt(x),
|
||||
@@ -854,12 +856,15 @@ unsafe_charAt_noop: {
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
s = "foo";
|
||||
x = 42;
|
||||
console.log(
|
||||
s[0],
|
||||
"string"[0 | x],
|
||||
(typeof x)[0]
|
||||
s[0] || "",
|
||||
"string"[0 | x] || "",
|
||||
(typeof x)[0] || ""
|
||||
);
|
||||
}
|
||||
expect_stdout: "f n"
|
||||
}
|
||||
|
||||
issue_1649: {
|
||||
|
||||
@@ -43,6 +43,28 @@ await: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
assignment_1: {
|
||||
input: {
|
||||
var a = 2;
|
||||
a **= 5;
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: "var a=2;a**=5;console.log(a);"
|
||||
expect_stdout: "32"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
assignment_2: {
|
||||
input: {
|
||||
var a = 8n;
|
||||
a **= a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: "var a=8n;a**=a;console.log(a);"
|
||||
expect_stdout: "16777216n"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -84,3 +106,42 @@ issue_4664: {
|
||||
expect_stdout: "function 1073741824 object"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4715: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
A = 1;
|
||||
console.log((-0) ** A + 0);
|
||||
console.log((-0) ** A - 0);
|
||||
console.log((-0) ** A * 1);
|
||||
console.log((-0) ** A / 1);
|
||||
console.log(Math.pow(-0, A) + 0);
|
||||
console.log(Math.pow(-0, A) - 0);
|
||||
console.log(Math.pow(-0, A) * 1);
|
||||
console.log(Math.pow(-0, A) / 1);
|
||||
}
|
||||
expect: {
|
||||
A = 1;
|
||||
console.log((-0) ** A + 0);
|
||||
console.log((-0) ** A);
|
||||
console.log((-0) ** A * 1);
|
||||
console.log((-0) ** A);
|
||||
console.log(Math.pow(-0, A) + 0);
|
||||
console.log(+Math.pow(-0, A));
|
||||
console.log(+Math.pow(-0, A));
|
||||
console.log(+Math.pow(-0, A));
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
"-0",
|
||||
"-0",
|
||||
"-0",
|
||||
"0",
|
||||
"-0",
|
||||
"-0",
|
||||
"-0",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ refs: {
|
||||
export {};
|
||||
export { a, b as B, c as case, d as default };
|
||||
}
|
||||
expect_exact: "export{};export{a as a,b as B,c as case,d as default};"
|
||||
expect_exact: "export{};export{a,b as B,c as case,d as default};"
|
||||
}
|
||||
|
||||
var_defs: {
|
||||
@@ -12,7 +12,7 @@ var_defs: {
|
||||
export let b = 2, c = 3;
|
||||
export var { d, e: [] } = f;
|
||||
}
|
||||
expect_exact: "export const a=1;export let b=2,c=3;export var{d:d,e:[]}=f;"
|
||||
expect_exact: "export const a=1;export let b=2,c=3;export var{d,e:[]}=f;"
|
||||
}
|
||||
|
||||
defuns: {
|
||||
@@ -35,7 +35,7 @@ defaults: {
|
||||
export default function*(a, b) {};
|
||||
export default async function f({ c }, ...[ d ]) {};
|
||||
}
|
||||
expect_exact: "export default 42;export default async;export default(x,y)=>x*x;export default class{}export default function*(a,b){}export default async function f({c:c},...[d]){}"
|
||||
expect_exact: "export default 42;export default async;export default(x,y)=>x*x;export default class{}export default function*(a,b){}export default async function f({c},...[d]){}"
|
||||
}
|
||||
|
||||
defaults_parentheses_1: {
|
||||
@@ -203,7 +203,23 @@ mangle_rename: {
|
||||
}
|
||||
}
|
||||
|
||||
hoist_exports: {
|
||||
hoist_exports_1: {
|
||||
options = {
|
||||
hoist_exports: true,
|
||||
}
|
||||
input: {
|
||||
export { a };
|
||||
export var b;
|
||||
export function f() {}
|
||||
}
|
||||
expect: {
|
||||
var b;
|
||||
function f() {}
|
||||
export { a, b, f };
|
||||
}
|
||||
}
|
||||
|
||||
hoist_exports_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_exports: true,
|
||||
@@ -226,15 +242,15 @@ hoist_exports: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
let f, { foo: o } = 42;
|
||||
function c(t, { [f]: a }) {
|
||||
t(a, c);
|
||||
let e, { foo: a } = 42;
|
||||
function f(t, { [e]: o }) {
|
||||
t(o, f);
|
||||
}
|
||||
export default 42;
|
||||
export default async function e(t, ...{ [o]: a }) {
|
||||
(await t)(e, a);
|
||||
export default async function n(t, ...{ [a]: o }) {
|
||||
(await t)(n, o);
|
||||
};
|
||||
export { f as bbb, o as ccc, c as fff };
|
||||
export { e as bbb, a as ccc, f as fff };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,3 +398,94 @@ single_use_class_default: {
|
||||
A.prototype.p = "PASS";
|
||||
}
|
||||
}
|
||||
|
||||
hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
}
|
||||
input: {
|
||||
export function f() {}
|
||||
export default async function* g() {}
|
||||
}
|
||||
expect_exact: "export function f(){}export default async function*g(){}"
|
||||
}
|
||||
|
||||
issue_4742_join_vars_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
export var a;
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
export var a;
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_join_vars_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
export var a = "foo";
|
||||
var b;
|
||||
b = "bar";
|
||||
}
|
||||
expect: {
|
||||
export var a = "foo";
|
||||
var b, b = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_unused_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
export var a;
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
export var a;
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_unused_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export var a = "foo";
|
||||
var a = "bar";
|
||||
}
|
||||
expect: {
|
||||
export var a = "foo";
|
||||
a = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
issue_4761: {
|
||||
input: {
|
||||
export default "function" == 42;
|
||||
}
|
||||
expect_exact: 'export default"function"==42;'
|
||||
}
|
||||
|
||||
issue_4766: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
export var a = "bar";
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
export var a = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2492,14 +2492,14 @@ issue_3297_3: {
|
||||
input: {
|
||||
function function1(session) {
|
||||
var public = {
|
||||
processBulk: processBulk
|
||||
processBulk: processBulk,
|
||||
};
|
||||
return public;
|
||||
function processBulk(bulk) {
|
||||
var subparam1 = session();
|
||||
function processOne(param1) {
|
||||
var param2 = {
|
||||
subparam1: subparam1
|
||||
subparam1: subparam1,
|
||||
};
|
||||
doProcessOne({
|
||||
param1: param1,
|
||||
@@ -2525,18 +2525,18 @@ issue_3297_3: {
|
||||
return {
|
||||
processBulk: function n(o) {
|
||||
var r, t, u = c();
|
||||
o && 0 < o.length && (r = {
|
||||
param1: o.shift(),
|
||||
param2: {
|
||||
subparam1: u
|
||||
}
|
||||
},
|
||||
o && 0 < o.length && (r = o.shift(),
|
||||
t = function() {
|
||||
n(o);
|
||||
},
|
||||
console.log(JSON.stringify(r)),
|
||||
console.log(JSON.stringify({
|
||||
param1: r,
|
||||
param2: {
|
||||
subparam1: u,
|
||||
},
|
||||
})),
|
||||
t());
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
function1(function() {
|
||||
@@ -2751,17 +2751,17 @@ functions: {
|
||||
function b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = function(c) {
|
||||
function c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (c(b(a()))) {
|
||||
function d() {}
|
||||
function e() {
|
||||
return typeof e;
|
||||
}
|
||||
var f = function(f) {
|
||||
function f(f) {
|
||||
return f;
|
||||
};
|
||||
}
|
||||
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||
}
|
||||
}();
|
||||
@@ -2808,9 +2808,9 @@ functions_use_strict: {
|
||||
function b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = function(c) {
|
||||
function c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (c(b(a()))) {
|
||||
var d = function() {};
|
||||
var e = function y() {
|
||||
@@ -2826,6 +2826,30 @@ functions_use_strict: {
|
||||
expect_stdout: "a true 42 function function function"
|
||||
}
|
||||
|
||||
functions_inner_var: {
|
||||
options = {
|
||||
functions: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
};
|
||||
a(a);
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
}
|
||||
a();
|
||||
}
|
||||
expect_stdout: "undefined undefined"
|
||||
}
|
||||
|
||||
issue_2437: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -5698,3 +5722,272 @@ block_scope_4_compress: {
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_4725_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f() {
|
||||
return function g() {
|
||||
return g;
|
||||
}();
|
||||
}
|
||||
};
|
||||
console.log(typeof o.f());
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f() {
|
||||
return function g() {
|
||||
return g;
|
||||
}();
|
||||
}
|
||||
};
|
||||
console.log(typeof o.f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4725_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f() {
|
||||
return function() {
|
||||
while (console.log("PASS"));
|
||||
}();
|
||||
}
|
||||
};
|
||||
o.f();
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f() {
|
||||
while (console.log("PASS"));
|
||||
}
|
||||
};
|
||||
o.f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
new_target_1: {
|
||||
input: {
|
||||
new function f() {
|
||||
console.log(new.target === f);
|
||||
}();
|
||||
console.log(function() {
|
||||
return new.target;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
new function f() {
|
||||
console.log(new.target === f);
|
||||
}();
|
||||
console.log(function() {
|
||||
return new.target;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
new_target_2: {
|
||||
input: {
|
||||
new function(a) {
|
||||
if (!new.target)
|
||||
console.log("FAIL");
|
||||
else if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
new function(a) {
|
||||
if (!new.target)
|
||||
console.log("FAIL");
|
||||
else if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
new_target_collapse_vars: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
new function(a) {
|
||||
if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}(0);
|
||||
}
|
||||
expect: {
|
||||
new function(a) {
|
||||
if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}(0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
new_target_delete: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
new function() {
|
||||
console.log(delete new.target);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
new function() {
|
||||
console.log(delete new.target);
|
||||
}();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
new_target_reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
new function(a) {
|
||||
if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}(0);
|
||||
}
|
||||
expect: {
|
||||
new function(a) {
|
||||
if (a)
|
||||
console.log("PASS");
|
||||
else
|
||||
new new.target(new.target.length);
|
||||
}(0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4753_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
for (var i in [ 1, 2 ])
|
||||
(function() {
|
||||
function f() {}
|
||||
f && console.log(f.p ^= 42);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
for (var i in [ 1, 2 ])
|
||||
f = function() {},
|
||||
void (f && console.log(f.p ^= 42));
|
||||
var f;
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4753_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
(function() {
|
||||
var a = f();
|
||||
function f() {
|
||||
return "PASS";
|
||||
}
|
||||
f;
|
||||
function g() {
|
||||
console.log(a);
|
||||
}
|
||||
g();
|
||||
})();
|
||||
} while (0);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
f = function() {
|
||||
return "PASS";
|
||||
},
|
||||
a = void 0,
|
||||
a = f(),
|
||||
console.log(a);
|
||||
} while (0);
|
||||
var f, a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4788: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
functions: true,
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = function g() {
|
||||
if (0) {
|
||||
var g = 42;
|
||||
f();
|
||||
}
|
||||
g || console.log("PASS");
|
||||
};
|
||||
a(a);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function f() {
|
||||
function a() {
|
||||
if (0) {
|
||||
var g = 42;
|
||||
f();
|
||||
}
|
||||
g || console.log("PASS");
|
||||
}
|
||||
a();
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ issue_4487: {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -152,7 +153,7 @@ issue_4487: {
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var a = console.log(typeof a);
|
||||
var f = console.log(typeof f);
|
||||
}
|
||||
a();
|
||||
}
|
||||
@@ -207,3 +208,35 @@ issue_4517: {
|
||||
}
|
||||
expect_stdout: "2boolean"
|
||||
}
|
||||
|
||||
issue_4736: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f() {
|
||||
(function g() {
|
||||
var b = (a = 0, 1 << 30);
|
||||
var c = (a = 0, console.log(b));
|
||||
var d = c;
|
||||
})(f);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
0,
|
||||
console.log(1073741824);
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1073741824"
|
||||
}
|
||||
|
||||
@@ -2919,3 +2919,29 @@ issue_4568: {
|
||||
}
|
||||
expect_stdout: "undefined 1"
|
||||
}
|
||||
|
||||
issue_4729: {
|
||||
options = {
|
||||
ie8: true,
|
||||
pure_getters: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
f;
|
||||
} catch (e) {
|
||||
var a = a && a[function f() {}];
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
f;
|
||||
} catch (e) {
|
||||
(function f() {});
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ keys_only: {
|
||||
input: {
|
||||
import { as as foo, bar, delete as baz } from "moo";
|
||||
}
|
||||
expect_exact: 'import{as as foo,bar as bar,delete as baz}from"moo";'
|
||||
expect_exact: 'import{as as foo,bar,delete as baz}from"moo";'
|
||||
}
|
||||
|
||||
default_all: {
|
||||
@@ -37,7 +37,7 @@ default_keys: {
|
||||
input: {
|
||||
import foo, { bar } from "baz";
|
||||
}
|
||||
expect_exact: 'import foo,{bar as bar}from"baz";'
|
||||
expect_exact: 'import foo,{bar}from"baz";'
|
||||
}
|
||||
|
||||
dynamic: {
|
||||
|
||||
@@ -4,7 +4,7 @@ mangle_keep_fnames_false: {
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
keep_fnames: false,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -30,7 +30,7 @@ mangle_keep_fnames_true: {
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
keep_fnames: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pure_function_calls: {
|
||||
options = {
|
||||
annotations: true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
@@ -60,6 +61,7 @@ pure_function_calls: {
|
||||
|
||||
pure_function_calls_toplevel: {
|
||||
options = {
|
||||
annotations: true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
@@ -126,6 +128,7 @@ pure_function_calls_toplevel: {
|
||||
|
||||
should_warn: {
|
||||
options = {
|
||||
annotations: true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
|
||||
@@ -426,6 +426,7 @@ wrap_iife_in_return_call: {
|
||||
|
||||
pure_annotation_1: {
|
||||
options = {
|
||||
annotations: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
@@ -439,6 +440,7 @@ pure_annotation_1: {
|
||||
|
||||
pure_annotation_2: {
|
||||
options = {
|
||||
annotations: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
@@ -463,15 +465,19 @@ drop_fargs: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
}(a++ + (a && console.log(a)));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
++a && console.log(a),
|
||||
a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_stdout: [
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
keep_fargs: {
|
||||
@@ -486,13 +492,17 @@ keep_fargs: {
|
||||
var a = 1;
|
||||
!function(a_1) {
|
||||
a++;
|
||||
}(a++ + (a && a.var));
|
||||
}(a++ + (a && console.log(a)));
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
++a && a.var, a++;
|
||||
++a && console.log(a),
|
||||
a++;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_stdout: [
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ reduce_block_2_toplevel: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
reduce_vars_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
@@ -381,6 +381,86 @@ reduce_vars: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
reduce_vars_2: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(typeof a);
|
||||
}
|
||||
for (let a in [ 42 ])
|
||||
f();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(typeof a);
|
||||
}
|
||||
for (let a in [ 42 ])
|
||||
f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
reduce_vars_3: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
let i = 1;
|
||||
function f() {
|
||||
i = 0;
|
||||
}
|
||||
for (let i = 0, x = 0; i < a.length; i++, x++) {
|
||||
if (x != i) {
|
||||
console.log("FAIL");
|
||||
break;
|
||||
}
|
||||
f();
|
||||
console.log(a[i]);
|
||||
}
|
||||
console.log(i);
|
||||
})([ 4, 2 ]);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
let i = 1;
|
||||
function f() {
|
||||
i = 0;
|
||||
}
|
||||
for (let i = 0, x = 0; i < a.length; i++, x++) {
|
||||
if (x != i) {
|
||||
console.log("FAIL");
|
||||
break;
|
||||
}
|
||||
f();
|
||||
console.log(a[i]);
|
||||
}
|
||||
console.log(i);
|
||||
})([ 4, 2 ]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"4",
|
||||
"2",
|
||||
"0",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
hoist_props: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
@@ -610,6 +690,28 @@ drop_unused: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
default_init: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let a;
|
||||
a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4191: {
|
||||
options = {
|
||||
functions: true,
|
||||
|
||||
@@ -836,10 +836,7 @@ for_of: {
|
||||
console.log(async);
|
||||
}
|
||||
expect_exact: 'var async=["PASS",42];async.p="FAIL";for(async of(null,async))console.log(async);'
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"42",
|
||||
]
|
||||
expect_stdout: true
|
||||
node_version: ">=0.12"
|
||||
}
|
||||
|
||||
|
||||
@@ -2620,9 +2620,9 @@ issue_4126_1: {
|
||||
try {
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
var b = a;
|
||||
var c = a;
|
||||
} finally {
|
||||
var c = b;
|
||||
var c = c;
|
||||
}
|
||||
console.log(c);
|
||||
}
|
||||
@@ -3239,3 +3239,65 @@ issue_4653: {
|
||||
"0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4759: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var i = 2, a = 1, b, c, d;
|
||||
while (i--) {
|
||||
try {
|
||||
if (1 != b) {
|
||||
d = [];
|
||||
null.p;
|
||||
c = d;
|
||||
} else {
|
||||
b = 0;
|
||||
a = c;
|
||||
}
|
||||
} catch (e) {}
|
||||
b = a;
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var i = 2, a = 1, b, c, d;
|
||||
while (i--) {
|
||||
try {
|
||||
if (1 != b) {
|
||||
d = [];
|
||||
null.p;
|
||||
c = d;
|
||||
} else {
|
||||
b = 0;
|
||||
a = c;
|
||||
}
|
||||
} catch (e) {}
|
||||
b = a;
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4761: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL", b;
|
||||
try {
|
||||
!a && --a && (b = 0)[console] || console.log(b);
|
||||
} catch (e) {}
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL", b;
|
||||
try {
|
||||
!a && --a && (b = 0)[console] || console.log(b);
|
||||
} catch (e) {}
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
literal_infinity: {
|
||||
input: {
|
||||
console.log(2e308, -1e2345);
|
||||
}
|
||||
expect_exact: "console.log(1/0,-(1/0));"
|
||||
}
|
||||
|
||||
parentheses_for_prototype_functions: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
|
||||
@@ -294,248 +294,6 @@ unary: {
|
||||
}
|
||||
}
|
||||
|
||||
issue_2629_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a();
|
||||
/*@__PURE__*/ (b());
|
||||
(/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */c();",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a(1)(2)(3);
|
||||
/*@__PURE__*/ (b(1))(2)(3);
|
||||
/*@__PURE__*/ (c(1)(2))(3);
|
||||
/*@__PURE__*/ (d(1)(2)(3));
|
||||
(/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ f(1))(2)(3);
|
||||
(/*@__PURE__*/ g(1)(2))(3);
|
||||
(/*@__PURE__*/ h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */e(1)(2)(3);",
|
||||
"/* */f(1)(2)(3);",
|
||||
"/* */g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
||||
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */h.x(1).y(2).z(3);",
|
||||
"/* */i.x(1).y(2).z(3);",
|
||||
"/* */j.x(1).y(2).z(3);",
|
||||
"/* */k.x(1).y(2).z(3);",
|
||||
"/* */l.x(1).y(2).z(3);",
|
||||
"/* */m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ x(), y());
|
||||
(w(), /*@__PURE__*/ x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2629_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ x() ];
|
||||
[ /*@__PURE__*/ x(), y() ];
|
||||
[ w(), /*@__PURE__*/ x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2638: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(g() || h())(x(), y());
|
||||
(/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a();
|
||||
/*@__PURE__*/ (new b());
|
||||
new (/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ new d());
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */c;",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a(1)(2)(3);
|
||||
/*@__PURE__*/ new (b(1))(2)(3);
|
||||
/*@__PURE__*/ new (c(1)(2))(3);
|
||||
/*@__PURE__*/ new (d(1)(2)(3));
|
||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ new f(1))(2)(3);
|
||||
(/*@__PURE__*/ new g(1)(2))(3);
|
||||
(/*@__PURE__*/ new h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */e(1)(2)(3);",
|
||||
"/* */new f(1)(2)(3);",
|
||||
"/* */new g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */h.x(1).y(2).z(3);",
|
||||
"/* */new/* */i.x(1).y(2).z(3);",
|
||||
"/* */new j.x(1).y(2).z(3);",
|
||||
"/* */new k.x(1).y(2).z(3);",
|
||||
"/* */new l.x(1).y(2).z(3);",
|
||||
"/* */new m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ new x(), y());
|
||||
(w(), /*@__PURE__*/ new x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ new x() ];
|
||||
[ /*@__PURE__*/ new x(), y() ];
|
||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_6: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/new (g() || h())(x(), y());
|
||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */new(/* */a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3065_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -680,130 +438,3 @@ issue_3325_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3858: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
var f = function(a) {
|
||||
return function() {
|
||||
console.log(a);
|
||||
}();
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inline_pure_call_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
f("PASS");
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
inline_pure_call_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
var a = f("PASS");
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
inline_pure_call_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function(a) {
|
||||
return /*@__PURE__*/ function(b) {
|
||||
console.log(b);
|
||||
}(a);
|
||||
};
|
||||
var a = f("PASS");
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
console.log("PASS");
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
inline_pure_call_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = /*@__PURE__*/ function() {
|
||||
return console.log("PASS"), 42;
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
return console.log("PASS"), 42;
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1220,13 +1220,110 @@ drop_arguments: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
lvalues_def: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
var a = b++, b = +function() {}();
|
||||
a && a[a++];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
a = b++, b = +void 0;
|
||||
a && a++;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
side_effects_assign: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
pure_getters: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = typeof void (a && a.in == 1, 0);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "undefined";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2062: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a || (a++, a--), a++, a--;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2878: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
function f2() {
|
||||
if (a) c++;
|
||||
}
|
||||
b = f2();
|
||||
a = 1;
|
||||
b && b.b;
|
||||
f2();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
function f2() {
|
||||
if (a) c++;
|
||||
}
|
||||
b = f2(),
|
||||
a = 1,
|
||||
f2();
|
||||
})(),
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3427: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
@@ -1242,6 +1339,74 @@ issue_3427: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3490_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
inline: true,
|
||||
pure_getters: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var b = 42, c = "FAIL";
|
||||
if ({
|
||||
3: function() {
|
||||
var a;
|
||||
return (a && a.p) < this;
|
||||
}(),
|
||||
}) c = "PASS";
|
||||
if (b) while ("" == typeof d);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect: {
|
||||
var b = 42, c = "FAIL";
|
||||
if (function() {
|
||||
var a;
|
||||
}(), c = "PASS", b) while ("" == typeof d);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
}
|
||||
|
||||
issue_4135: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 0;
|
||||
--b;
|
||||
a++;
|
||||
if (!a)
|
||||
var c = function() {
|
||||
var d = 0;
|
||||
function f() {
|
||||
d && d.p;
|
||||
}
|
||||
f();
|
||||
this;
|
||||
}(a++);
|
||||
console.log(a, b, c);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
0;
|
||||
a++;
|
||||
if (!a)
|
||||
var c = void a++;
|
||||
console.log(a, -1, c);
|
||||
}
|
||||
expect_stdout: "1 -1 undefined"
|
||||
}
|
||||
|
||||
issue_4440: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
@@ -1270,3 +1435,132 @@ issue_4440: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4730_1: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log("PASS") + (a && a[a.p]);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4730_2: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
!console.log("PASS") || a && a[a.p];
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4751: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
o && o.p;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
super_toString: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log({
|
||||
f() {
|
||||
return super.toString();
|
||||
},
|
||||
}.f());
|
||||
}
|
||||
expect: {
|
||||
console.log({
|
||||
f() {
|
||||
return super.toString();
|
||||
},
|
||||
}.f());
|
||||
}
|
||||
expect_stdout: "[object Object]"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
this_toString: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log({
|
||||
f() {
|
||||
return this.toString();
|
||||
},
|
||||
}.f());
|
||||
}
|
||||
expect: {
|
||||
console.log({
|
||||
f() {
|
||||
return "" + this;
|
||||
},
|
||||
}.f());
|
||||
}
|
||||
expect_stdout: "[object Object]"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4803: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get f() {
|
||||
console.log("PASS");
|
||||
},
|
||||
} || 42;
|
||||
for (var k in o)
|
||||
o[k];
|
||||
}
|
||||
expect: {
|
||||
var k, o = {
|
||||
get f() {
|
||||
console.log("PASS");
|
||||
},
|
||||
} || 42;
|
||||
for (k in o)
|
||||
o[k];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -564,6 +564,34 @@ delete_seq_3: {
|
||||
}
|
||||
|
||||
delete_seq_4: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: false,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log(delete (f(), undefined));
|
||||
console.log(delete (f(), void 0));
|
||||
console.log(delete (f(), Infinity));
|
||||
console.log(delete (f(), 1 / 0));
|
||||
console.log(delete (f(), NaN));
|
||||
console.log(delete (f(), 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log(delete void f()),
|
||||
console.log(delete void f()),
|
||||
console.log((f(), delete (1 / 0))),
|
||||
console.log((f(), delete (1 / 0))),
|
||||
console.log(delete (f(), NaN)),
|
||||
console.log((f(), delete(0 / 0)));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_4_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
@@ -592,6 +620,35 @@ delete_seq_4: {
|
||||
}
|
||||
|
||||
delete_seq_5: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: false,
|
||||
keep_infinity: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log(delete (f(), undefined));
|
||||
console.log(delete (f(), void 0));
|
||||
console.log(delete (f(), Infinity));
|
||||
console.log(delete (f(), 1 / 0));
|
||||
console.log(delete (f(), NaN));
|
||||
console.log(delete (f(), 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log(delete void f()),
|
||||
console.log(delete void f()),
|
||||
console.log(delete (f(), Infinity)),
|
||||
console.log((f(), delete (1 / 0))),
|
||||
console.log(delete (f(), NaN)),
|
||||
console.log((f(), delete (0 / 0)));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_5_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
@@ -663,12 +720,21 @@ side_effects_cascade_1: {
|
||||
if (a < 0) a = 0;
|
||||
b.a = a;
|
||||
}
|
||||
var m = {}, n = {};
|
||||
f(13, m);
|
||||
f("foo", n);
|
||||
console.log(m.a, n.a);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(a -= 42) < 0 && (a = 0), b.a = a;
|
||||
b.a = a = (a -= 42) < 0 ? 0 : a;
|
||||
}
|
||||
var m = {}, n = {};
|
||||
f(13, m),
|
||||
f("foo", n),
|
||||
console.log(m.a, n.a);
|
||||
}
|
||||
expect_stdout: "0 NaN"
|
||||
}
|
||||
|
||||
side_effects_cascade_2: {
|
||||
|
||||
@@ -558,3 +558,60 @@ drop_side_effect_free_call: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4730_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log("PASS") + (a && a[a.p]);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS"),
|
||||
a && a[a.p];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4730_2: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
!console.log("PASS") || a && a[a.p];
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
!console.log("PASS") || a && a[a.p];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4751: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
o && o.p;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
};
|
||||
o && o.p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ collapse_vars_4: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
conditionals_farg: {
|
||||
conditionals_farg_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
@@ -107,6 +107,28 @@ conditionals_farg: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
conditionals_farg_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
(function(a) {
|
||||
return a.length ? log(...a) : log("FAIL");
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
(function(a) {
|
||||
return a.length ? log(...a) : log("FAIL");
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
dont_inline: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -272,6 +294,31 @@ reduce_vars_2: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
reduce_vars_3: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
function g() {
|
||||
return (a => a)(...[ f ]);
|
||||
}
|
||||
console.log(g() === g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
function g() {
|
||||
return (a => a)(...[ f ]);
|
||||
}
|
||||
console.log(g() === g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
convert_setter: {
|
||||
options = {
|
||||
objects: true,
|
||||
@@ -667,6 +714,57 @@ unused_var_side_effects: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
unsafe_join_1: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log([ ..."foo" ].join());
|
||||
}
|
||||
expect: {
|
||||
console.log([ ..."foo" ].join());
|
||||
}
|
||||
expect_stdout: "f,o,o"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unsafe_join_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log([ "foo", ..."bar" ].join(""));
|
||||
}
|
||||
expect: {
|
||||
console.log([ "foo", ..."bar" ].join(""));
|
||||
}
|
||||
expect_stdout: "foobar"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unsafe_join_3: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
[].join(...console);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
[].join(...console);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4329: {
|
||||
options = {
|
||||
objects: true,
|
||||
|
||||
@@ -73,6 +73,20 @@ tag_parentheses_new: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
tag_parentheses_sequence: {
|
||||
input: {
|
||||
var o = {
|
||||
f() {
|
||||
console.log(this === o ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(42, o.f)``;
|
||||
}
|
||||
expect_exact: 'var o={f(){console.log(this===o?"FAIL":"PASS")}};(42,o.f)``;'
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
malformed_escape: {
|
||||
input: {
|
||||
(function(s) {
|
||||
@@ -211,7 +225,7 @@ unsafe_evaluate: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
side_effects: {
|
||||
side_effects_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
@@ -228,6 +242,30 @@ side_effects: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
side_effects_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f() {
|
||||
console.log(this === o ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(42, o.f)``;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f() {
|
||||
console.log(this === o ? "FAIL" : "PASS");
|
||||
},
|
||||
};
|
||||
(0, o.f)``;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
unsafe_side_effects: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
|
||||
@@ -50,7 +50,7 @@ unicode_parse_variables: {
|
||||
}
|
||||
}
|
||||
|
||||
unicode_escaped_identifier: {
|
||||
unicode_escaped_identifier_1: {
|
||||
input: {
|
||||
var \u0061 = "\ud800\udc00";
|
||||
console.log(a);
|
||||
@@ -59,6 +59,17 @@ unicode_escaped_identifier: {
|
||||
expect_stdout: "\ud800\udc00"
|
||||
}
|
||||
|
||||
unicode_escaped_identifier_2: {
|
||||
input: {
|
||||
var \u{61} = "foo";
|
||||
var \u{10000} = "bar";
|
||||
console.log(a, \u{10000});
|
||||
}
|
||||
expect_exact: 'var a="foo";var \u{10000}="bar";console.log(a,\u{10000});'
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
unicode_identifier_ascii_only: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
|
||||
@@ -354,6 +354,92 @@ forin_let_2: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
loop_scope_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var o = { foo: 1, bar: 2 };
|
||||
for (let i in o) {
|
||||
console.log(i);
|
||||
}
|
||||
for (const j in o)
|
||||
setTimeout(() => console.log(j), 0);
|
||||
for (let k in o)
|
||||
setTimeout(function() {
|
||||
console.log(k);
|
||||
}, 0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var o = { foo: 1, bar: 2 };
|
||||
for (var i in o)
|
||||
console.log(i);
|
||||
for (const j in o)
|
||||
setTimeout(() => console.log(j), 0);
|
||||
for (let k in o)
|
||||
setTimeout(function() {
|
||||
console.log(k);
|
||||
}, 0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
loop_scope_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = [ "foo", "bar" ];
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
const x = a[i];
|
||||
console.log(x);
|
||||
let y = a[i];
|
||||
setTimeout(() => console.log(y), 0);
|
||||
const z = a[i];
|
||||
setTimeout(function() {
|
||||
console.log(z);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = [ "foo", "bar" ];
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var x = a[i];
|
||||
console.log(x);
|
||||
let y = a[i];
|
||||
setTimeout(() => console.log(y), 0);
|
||||
const z = a[i];
|
||||
setTimeout(function() {
|
||||
console.log(z);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
"foo",
|
||||
"bar",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4290_1_const: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -409,3 +495,31 @@ drop_forin_let: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
default_init: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
(function() {
|
||||
"use strict";
|
||||
let a;
|
||||
a = A;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
A = "PASS";
|
||||
(function() {
|
||||
"use strict";
|
||||
var a = A;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -247,6 +247,30 @@ collapse_vars_4: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
collapse_vars_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = function* f(b, c) {
|
||||
b = yield c = b;
|
||||
console.log(c);
|
||||
}("PASS");
|
||||
a.next();
|
||||
a.next("FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = function* f(b, c) {
|
||||
b = yield c = b;
|
||||
console.log(c);
|
||||
}("PASS");
|
||||
a.next();
|
||||
a.next("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
collapse_property_lambda: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -388,14 +412,14 @@ functions: {
|
||||
function* b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = function*(c) {
|
||||
function* c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (yield* c(yield* b(yield* a()))) {
|
||||
function* d() {}
|
||||
function* e() {
|
||||
return typeof e;
|
||||
}
|
||||
var d = function*() {};
|
||||
var e = function* y() {
|
||||
return typeof y;
|
||||
};
|
||||
var f = function*(f) {
|
||||
return f;
|
||||
};
|
||||
@@ -446,9 +470,9 @@ functions_use_strict: {
|
||||
function* b() {
|
||||
return !!b;
|
||||
}
|
||||
var c = function*(c) {
|
||||
function* c(c) {
|
||||
return c;
|
||||
};
|
||||
}
|
||||
if (yield* c(yield* b(yield* a()))) {
|
||||
var d = function*() {};
|
||||
var e = function* y() {
|
||||
@@ -465,6 +489,54 @@ functions_use_strict: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
functions_anonymous: {
|
||||
options = {
|
||||
functions: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var yield = function*() {
|
||||
return "PASS";
|
||||
};
|
||||
console.log(yield().next(yield).value);
|
||||
}
|
||||
expect: {
|
||||
function* yield() {
|
||||
return "PASS";
|
||||
}
|
||||
console.log(yield().next(yield).value);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
functions_inner_var: {
|
||||
options = {
|
||||
functions: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var yield = function* a() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
};
|
||||
yield().next(yield);
|
||||
}
|
||||
expect: {
|
||||
function* yield() {
|
||||
var a;
|
||||
console.log(a, a);
|
||||
}
|
||||
yield().next(yield);
|
||||
}
|
||||
expect_stdout: "undefined undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
negate_iife: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
@@ -950,3 +1022,43 @@ issue_4641_2: {
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4769_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function*() {
|
||||
(function({} = yield => {}) {})();
|
||||
}().next().done);
|
||||
}
|
||||
expect: {
|
||||
console.log(function*() {
|
||||
(function({} = yield => {}) {})();
|
||||
}().next().done);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4769_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function*() {
|
||||
return function({} = yield => {}) {
|
||||
return "PASS";
|
||||
}();
|
||||
}().next().value);
|
||||
}
|
||||
expect: {
|
||||
console.log(function*() {
|
||||
return function({} = yield => {}) {
|
||||
return "PASS";
|
||||
}();
|
||||
}().next().value);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [
|
||||
"input.js"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;;;;;;;;;eAAc,OAAO,CAAC,KAAD,C;IAAd,G,YAAA,G;;gBACS,OAAO,CAAC,OAAD,C;IAAhB,K,aAAA,K;;AAEP,GAAG,CAAC,CAAJ,OAAA,GAAG,qBAAM,GAAG,CAAC,CAAJ,CAAM,KAAK,CAAC,CAAZ,CAAN,EAAH",
|
||||
"sourcesContent": [
|
||||
"const {foo} = require(\"bar\");\nconst {hello} = require(\"world\");\n\nfoo.x(...foo.y(hello.z));\n"
|
||||
]
|
||||
}
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [
|
||||
"input.js"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;;;;;;;;;eAAc,OAAO,CAAC,KAAD,C;IAAd,G,YAAA,G;;gBACS,OAAO,CAAC,OAAD,C;IAAhB,K,aAAA,K;;AAEP,GAAG,CAAC,CAAJ,OAAA,GAAG,qBAAM,GAAG,CAAC,CAAJ,CAAM,KAAK,CAAC,CAAZ,CAAN,EAAH",
|
||||
"sourcesContent": [
|
||||
"const {foo} = require(\"bar\");\nconst {hello} = require(\"world\");\n\nfoo.x(...foo.y(hello.z));\n"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"compress": false,
|
||||
"mangle": {
|
||||
"properties": {
|
||||
"regex": "/^_/"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"compress": false,
|
||||
"mangle": {
|
||||
"properties": {
|
||||
"regex": "/^_/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ describe("bin/uglifyjs", function() {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
|
||||
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -37,7 +37,7 @@ describe("bin/uglifyjs", function() {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -45,7 +45,7 @@ describe("bin/uglifyjs", function() {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n\n");
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -392,12 +392,12 @@ describe("comments", function() {
|
||||
describe("comment filters", function() {
|
||||
it("Should be able to filter comments by passing regexp", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments with the 'all' option", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
|
||||
});
|
||||
|
||||
it("Should be able to filter commments with the 'some' option", function() {
|
||||
@@ -410,13 +410,12 @@ describe("comments", function() {
|
||||
var f = function(node, comment) {
|
||||
return comment.value.length === 8;
|
||||
};
|
||||
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments by passing regex in string format", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
|
||||
});
|
||||
|
||||
it("Should be able to get the comment and comment type when using a function", function() {
|
||||
@@ -424,14 +423,12 @@ describe("comments", function() {
|
||||
var f = function(node, comment) {
|
||||
return comment.type == "comment1" || comment.type == "comment3";
|
||||
};
|
||||
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments by passing a boolean", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
|
||||
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
||||
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: false}), "");
|
||||
});
|
||||
|
||||
@@ -439,10 +436,8 @@ describe("comments", function() {
|
||||
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
|
||||
var f = function(node, comment) {
|
||||
assert.strictEqual(comment.type === "comment5", false);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
|
||||
});
|
||||
|
||||
@@ -453,9 +448,8 @@ describe("comments", function() {
|
||||
|
||||
it("Should have no problem on multiple calls", function() {
|
||||
const options = {
|
||||
comments: /ok/
|
||||
comments: /ok/,
|
||||
};
|
||||
|
||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||
@@ -463,14 +457,14 @@ describe("comments", function() {
|
||||
|
||||
it("Should handle shebang and preamble correctly", function() {
|
||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||
output: { preamble: "/* Build */" }
|
||||
output: { preamble: "/* Build */" },
|
||||
}).code;
|
||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||
});
|
||||
|
||||
it("Should handle preamble without shebang correctly", function() {
|
||||
var code = UglifyJS.minify("var x = 10;", {
|
||||
output: { preamble: "/* Build */" }
|
||||
output: { preamble: "/* Build */" },
|
||||
}).code;
|
||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||
});
|
||||
|
||||
@@ -235,8 +235,8 @@ describe("minify", function() {
|
||||
}
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=/* */function(){foo()}();");
|
||||
})
|
||||
assert.strictEqual(code, "var a=function(){foo()}();");
|
||||
});
|
||||
});
|
||||
|
||||
describe("JS_Parse_Error", function() {
|
||||
|
||||
@@ -137,6 +137,12 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
if (parent instanceof U.AST_ExportDefault) return;
|
||||
if (parent instanceof U.AST_ExportForeign) return;
|
||||
if (parent instanceof U.AST_ExportReferences) return;
|
||||
// preserve sole definition of an export statement
|
||||
if (node instanceof U.AST_VarDef
|
||||
&& parent.definitions.length == 1
|
||||
&& tt.parent(1) instanceof U.AST_ExportDeclaration) {
|
||||
return;
|
||||
}
|
||||
// preserve for (var xxx; ...)
|
||||
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node;
|
||||
// preserve for (xxx in/of ...)
|
||||
@@ -202,12 +208,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
if (node.expression instanceof U.AST_Function) {
|
||||
// hoist and return expressions from the IIFE function expression
|
||||
var body = node.expression.body;
|
||||
node.expression.body = [];
|
||||
var seq = [];
|
||||
body.forEach(function(node) {
|
||||
node.expression.body.forEach(function(node) {
|
||||
var expr = expr instanceof U.AST_Exit ? node.value : node.body;
|
||||
if (expr instanceof U.AST_Node && !U.is_statement(expr)) {
|
||||
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
|
||||
// collect expressions from each statements' body
|
||||
seq.push(expr);
|
||||
}
|
||||
@@ -258,7 +262,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
CHANGED = true;
|
||||
return List.skip;
|
||||
default:
|
||||
if (!has_exit(node)) {
|
||||
if (!has_exit(node) && can_hoist(node)) {
|
||||
// hoist function declaration body
|
||||
var body = node.body;
|
||||
node.body = [];
|
||||
@@ -375,11 +379,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
if (node.body instanceof U.AST_Call && node.body.expression instanceof U.AST_Function) {
|
||||
// hoist simple statement IIFE function expression body
|
||||
node.start._permute++;
|
||||
if (!has_exit(node.body.expression)) {
|
||||
var body = node.body.expression.body;
|
||||
node.body.expression.body = [];
|
||||
if (!has_exit(node.body.expression) && can_hoist(node.body.expression)) {
|
||||
CHANGED = true;
|
||||
return List.splice(body);
|
||||
return List.splice(node.body.expression.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,13 +462,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return List.skip;
|
||||
}
|
||||
|
||||
// preserve sole definition of an export statement
|
||||
if (node instanceof U.AST_VarDef
|
||||
&& parent.definitions.length == 1
|
||||
&& tt.parent(1) instanceof U.AST_ExportDeclaration) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// remove this node unless its the sole element of a (transient) sequence
|
||||
if (!(parent instanceof U.AST_Sequence) || parent.expressions.length > 1) {
|
||||
node.start._permute++;
|
||||
@@ -674,6 +669,20 @@ function has_loopcontrol(body, loop, label) {
|
||||
return found;
|
||||
}
|
||||
|
||||
function can_hoist(body) {
|
||||
var found = false;
|
||||
body.walk(new U.TreeWalker(function(node) {
|
||||
if (found) return true;
|
||||
if (node instanceof U.AST_NewTarget) return found = true;
|
||||
if (node instanceof U.AST_Scope) {
|
||||
if (node === body) return;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U.AST_Super) return found = true;
|
||||
}));
|
||||
return !found;
|
||||
}
|
||||
|
||||
function is_timed_out(result) {
|
||||
return sandbox.is_error(result) && /timed out/.test(result.message);
|
||||
}
|
||||
|
||||
98
test/release/acorn.sh
Executable file
98
test/release/acorn.sh
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/acorn \
|
||||
&& git clone https://github.com/acornjs/acorn.git tmp/acorn \
|
||||
&& cd tmp/acorn \
|
||||
&& rm -rf .git/hooks \
|
||||
&& git checkout 74b59384320ced82e09da2e8fdbed16810f7379a \
|
||||
&& patch -l -p1 <<EOF
|
||||
diff --git a/acorn-loose/rollup.config.js b/acorn-loose/rollup.config.js
|
||||
index d2389b2..c37882b 100644
|
||||
--- a/acorn-loose/rollup.config.js
|
||||
+++ b/acorn-loose/rollup.config.js
|
||||
@@ -1,2 +0,0 @@
|
||||
-import buble from "rollup-plugin-buble"
|
||||
-
|
||||
@@ -23 +20,0 @@ export default {
|
||||
- buble({transforms: {dangerousForOf: true}})
|
||||
diff --git a/acorn-walk/rollup.config.js b/acorn-walk/rollup.config.js
|
||||
index 67dd613..8c28807 100644
|
||||
--- a/acorn-walk/rollup.config.js
|
||||
+++ b/acorn-walk/rollup.config.js
|
||||
@@ -1,2 +0,0 @@
|
||||
-import buble from "rollup-plugin-buble"
|
||||
-
|
||||
@@ -19 +16,0 @@ export default {
|
||||
- buble({transforms: {dangerousForOf: true}})
|
||||
diff --git a/acorn/rollup.config.bin.js b/acorn/rollup.config.bin.js
|
||||
index 8a082b0..b3eda60 100644
|
||||
--- a/acorn/rollup.config.bin.js
|
||||
+++ b/acorn/rollup.config.bin.js
|
||||
@@ -1,2 +0,0 @@
|
||||
-import buble from "rollup-plugin-buble"
|
||||
-
|
||||
@@ -11 +9 @@ export default {
|
||||
- plugins: [buble()]
|
||||
+ plugins: []
|
||||
diff --git a/acorn/rollup.config.js b/acorn/rollup.config.js
|
||||
index c775a0c..cfd4c68 100644
|
||||
--- a/acorn/rollup.config.js
|
||||
+++ b/acorn/rollup.config.js
|
||||
@@ -1,2 +0,0 @@
|
||||
-import buble from "rollup-plugin-buble"
|
||||
-
|
||||
@@ -19 +16,0 @@ export default {
|
||||
- buble({transforms: {dangerousForOf: true}})
|
||||
diff --git a/package.json b/package.json
|
||||
index 382f59e..4612a75 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -24,4 +24 @@
|
||||
- "prepare": "npm run test",
|
||||
- "test": "node test/run.js && node test/lint.js",
|
||||
- "pretest": "npm run build:main && npm run build:loose",
|
||||
- "test:test262": "node bin/run_test262.js",
|
||||
+ "test": "node test/run.js",
|
||||
@@ -32,2 +29 @@
|
||||
- "build:bin": "rollup -c acorn/rollup.config.bin.js",
|
||||
- "lint": "eslint acorn/src/ acorn-walk/src/ acorn-loose/src/"
|
||||
+ "build:bin": "rollup -c acorn/rollup.config.bin.js"
|
||||
@@ -36,6 +31,0 @@
|
||||
- "eslint": "^4.10.0",
|
||||
- "eslint-config-standard": "^10.2.1",
|
||||
- "eslint-plugin-import": "^2.2.0",
|
||||
- "eslint-plugin-node": "^5.2.1",
|
||||
- "eslint-plugin-promise": "^3.5.0",
|
||||
- "eslint-plugin-standard": "^3.0.1",
|
||||
@@ -43,4 +32,0 @@
|
||||
- "rollup-plugin-buble": "^0.19.0",
|
||||
- "test262": "git+https://github.com/tc39/test262.git#a6c819ad0f049f23f1a37af6b89dbb79fe3b9216",
|
||||
- "test262-parser-runner": "^0.5.0",
|
||||
- "test262-stream": "^1.2.1",
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "acorn/src" \
|
||||
&& minify_in_situ "acorn-loose/src" \
|
||||
&& minify_in_situ "acorn-walk/src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm install \
|
||||
&& rm -rf acorn/dist acorn-loose/dist acorn-walk/dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "acorn/dist" \
|
||||
&& minify_in_situ "acorn-loose/dist" \
|
||||
&& minify_in_situ "acorn-walk/dist" \
|
||||
&& npm test
|
||||
182
test/release/bootstrap.sh
Executable file
182
test/release/bootstrap.sh
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/bootstrap \
|
||||
&& git clone --depth 1 --branch v5.0.0-beta2 https://github.com/twbs/bootstrap.git tmp/bootstrap \
|
||||
&& cd tmp/bootstrap \
|
||||
&& rm -rf .git/hooks \
|
||||
&& patch -p1 <<EOF
|
||||
--- a/.babelrc.js
|
||||
+++ /dev/null
|
||||
@@ -1,12 +0,0 @@
|
||||
-module.exports = {
|
||||
- presets: [
|
||||
- [
|
||||
- '@babel/preset-env',
|
||||
- {
|
||||
- loose: true,
|
||||
- bugfixes: true,
|
||||
- modules: false
|
||||
- }
|
||||
- ]
|
||||
- ]
|
||||
-};
|
||||
--- a/.gitattributes
|
||||
+++ b/.gitattributes
|
||||
@@ -5,0 +6 @@
|
||||
+*.png binary
|
||||
--- a/build/build-plugins.js
|
||||
+++ b/build/build-plugins.js
|
||||
@@ -14 +13,0 @@ const rollup = require('rollup')
|
||||
-const { babel } = require('@rollup/plugin-babel')
|
||||
@@ -19,6 +17,0 @@ const plugins = [
|
||||
- babel({
|
||||
- // Only transpile our source code
|
||||
- exclude: 'node_modules/**',
|
||||
- // Include the helpers in each file, at most one copy of each
|
||||
- babelHelpers: 'bundled'
|
||||
- })
|
||||
--- a/build/rollup.config.js
|
||||
+++ b/build/rollup.config.js
|
||||
@@ -4 +3,0 @@ const path = require('path')
|
||||
-const { babel } = require('@rollup/plugin-babel')
|
||||
@@ -15,6 +13,0 @@ const plugins = [
|
||||
- babel({
|
||||
- // Only transpile our source code
|
||||
- exclude: 'node_modules/**',
|
||||
- // Include the helpers in the bundle, at most one copy of each
|
||||
- babelHelpers: 'bundled'
|
||||
- })
|
||||
--- a/js/tests/integration/rollup.bundle.js
|
||||
+++ b/js/tests/integration/rollup.bundle.js
|
||||
@@ -3 +2,0 @@
|
||||
-const { babel } = require('@rollup/plugin-babel')
|
||||
@@ -18,4 +16,0 @@ module.exports = {
|
||||
- babel({
|
||||
- exclude: 'node_modules/**',
|
||||
- babelHelpers: 'bundled'
|
||||
- })
|
||||
--- a/js/tests/karma.conf.js
|
||||
+++ b/js/tests/karma.conf.js
|
||||
@@ -7,2 +6,0 @@ const ip = require('ip')
|
||||
-const { babel } = require('@rollup/plugin-babel')
|
||||
-const istanbul = require('rollup-plugin-istanbul')
|
||||
@@ -84,13 +81,0 @@ const conf = {
|
||||
- istanbul({
|
||||
- exclude: [
|
||||
- 'node_modules/**',
|
||||
- 'js/tests/unit/**/*.spec.js',
|
||||
- 'js/tests/helpers/**/*.js'
|
||||
- ]
|
||||
- }),
|
||||
- babel({
|
||||
- // Only transpile our source code
|
||||
- exclude: 'node_modules/**',
|
||||
- // Inline the required helpers in each file
|
||||
- babelHelpers: 'inline'
|
||||
- }),
|
||||
@@ -142 +126,0 @@ if (BROWSERSTACK) {
|
||||
- 'karma-coverage-istanbul-reporter'
|
||||
@@ -144 +127,0 @@ if (BROWSERSTACK) {
|
||||
- reporters.push('coverage-istanbul')
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -23 +23 @@
|
||||
- "start": "npm-run-all --parallel watch docs-serve",
|
||||
+ "start": "npm-run-all --parallel watch",
|
||||
@@ -28,3 +27,0 @@
|
||||
- "css-lint": "npm-run-all --continue-on-error --parallel css-lint-*",
|
||||
- "css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache --rd",
|
||||
- "css-lint-vars": "fusv scss/ site/assets/scss/",
|
||||
@@ -44 +40,0 @@
|
||||
- "js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives .",
|
||||
@@ -46,3 +42,3 @@
|
||||
- "js-minify-standalone": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
|
||||
- "js-minify-standalone-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
|
||||
- "js-minify-bundle": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
|
||||
+ "js-minify-standalone": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
|
||||
+ "js-minify-standalone-esm": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
|
||||
+ "js-minify-bundle": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
|
||||
@@ -56,25 +52 @@
|
||||
- "lint": "npm-run-all --parallel js-lint css-lint lockfile-lint",
|
||||
- "docs": "npm-run-all docs-build docs-lint",
|
||||
- "docs-build": "hugo --cleanDestinationDir",
|
||||
- "docs-compile": "npm run docs-build",
|
||||
- "docs-linkinator": "linkinator _gh_pages --recurse --silent --skip \"^(?!http://localhost)\"",
|
||||
- "docs-vnu": "node build/vnu-jar.js",
|
||||
- "docs-lint": "npm-run-all --parallel docs-vnu docs-linkinator",
|
||||
- "docs-serve": "hugo server --port 9001 --disableFastRender",
|
||||
- "docs-serve-only": "npx sirv-cli _gh_pages --port 9001",
|
||||
- "lockfile-lint": "lockfile-lint --allowed-hosts npm --allowed-schemes https: --empty-hostname false --type npm --path package-lock.json",
|
||||
- "update-deps": "ncu -u -x karma-browserstack-launcher,terser && npm update && echo Manually update site/assets/js/vendor",
|
||||
- "release": "npm-run-all dist release-sri docs-build release-zip*",
|
||||
- "release-sri": "node build/generate-sri.js",
|
||||
- "release-version": "node build/change-version.js",
|
||||
- "release-zip": "cross-env-shell \"rm -rf bootstrap-\$npm_package_version-dist && cp -r dist/ bootstrap-\$npm_package_version-dist && zip -r9 bootstrap-\$npm_package_version-dist.zip bootstrap-\$npm_package_version-dist && rm -rf bootstrap-\$npm_package_version-dist\"",
|
||||
- "release-zip-examples": "node build/zip-examples.js",
|
||||
- "dist": "npm-run-all --parallel css js",
|
||||
- "test": "npm-run-all lint dist js-test docs-build docs-lint",
|
||||
- "netlify": "cross-env-shell HUGO_BASEURL=\$DEPLOY_PRIME_URL npm-run-all dist release-sri docs-build",
|
||||
- "watch": "npm-run-all --parallel watch-*",
|
||||
- "watch-css-main": "nodemon --watch scss/ --ext scss --exec \"npm-run-all css-lint css-compile css-prefix\"",
|
||||
- "watch-css-dist": "nodemon --watch dist/css/ --ext css --ignore \"dist/css/*.rtl.*\" --exec \"npm run css-rtl\"",
|
||||
- "watch-css-docs": "nodemon --watch site/assets/scss/ --ext scss --exec \"npm run css-lint\"",
|
||||
- "watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm-run-all js-lint js-compile\"",
|
||||
- "watch-js-docs": "nodemon --watch site/assets/js/ --ext js --exec \"npm run js-lint\""
|
||||
+ "dist": "npm run css && npm run js"
|
||||
@@ -103,3 +74,0 @@
|
||||
- "@babel/cli": "^7.12.13",
|
||||
- "@babel/core": "^7.12.13",
|
||||
- "@babel/preset-env": "^7.12.13",
|
||||
@@ -107 +75,0 @@
|
||||
- "@rollup/plugin-babel": "^5.2.3",
|
||||
@@ -115,4 +82,0 @@
|
||||
- "eslint": "^7.19.0",
|
||||
- "eslint-config-xo": "^0.34.0",
|
||||
- "eslint-plugin-import": "^2.22.1",
|
||||
- "eslint-plugin-unicorn": "^27.0.0",
|
||||
@@ -122 +85,0 @@
|
||||
- "hugo-bin": "^0.68.0",
|
||||
@@ -128 +90,0 @@
|
||||
- "karma-coverage-istanbul-reporter": "^3.0.3",
|
||||
@@ -134,2 +95,0 @@
|
||||
- "linkinator": "^2.13.4",
|
||||
- "lockfile-lint": "^4.3.7",
|
||||
@@ -141 +100,0 @@
|
||||
- "rollup-plugin-istanbul": "^3.0.0",
|
||||
@@ -144,5 +103 @@
|
||||
- "shelljs": "^0.8.4",
|
||||
- "stylelint": "^13.9.0",
|
||||
- "stylelint-config-twbs-bootstrap": "^2.1.0",
|
||||
- "terser": "5.1.0",
|
||||
- "vnu-jar": "21.2.5"
|
||||
+ "shelljs": "^0.8.4"
|
||||
@@ -155,3 +109,0 @@
|
||||
- "hugo-bin": {
|
||||
- "buildTags": "extended"
|
||||
- },
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& minify_in_situ "node_modules/@popperjs/core" \
|
||||
&& rm -rf dist/js/* \
|
||||
&& minify_in_situ "build" \
|
||||
&& minify_in_situ "js" \
|
||||
&& minify_in_situ "site" \
|
||||
&& npm run dist \
|
||||
&& minify_in_situ "dist" \
|
||||
&& npm run js-test
|
||||
45
test/release/buble.sh
Executable file
45
test/release/buble.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/buble \
|
||||
&& git clone https://github.com/bublejs/buble.git tmp/buble \
|
||||
&& cd tmp/buble \
|
||||
&& rm -rf .git/hooks \
|
||||
&& git checkout dcc5ab02c9af6ddaad94e587c4911677340ec100 \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -29 +28,0 @@
|
||||
- "prepublish": "npm test",
|
||||
@@ -67,3 +66 @@
|
||||
- "source-map-support": "^0.5.16",
|
||||
- "test262": "git+https://github.com/tc39/test262.git#4f1155c566a222238fd86f179c6635ecb4c289bb",
|
||||
- "test262-stream": "^1.3.0"
|
||||
+ "source-map-support": "^0.5.16"
|
||||
--- a/src/program/BlockStatement.js
|
||||
+++ b/src/program/BlockStatement.js
|
||||
@@ -309 +309 @@ export default class BlockStatement extends Node {
|
||||
- let cont = false; // TODO implement proper continue...
|
||||
+ let cont = !declarations; // TODO implement proper continue...
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& rm -rf dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& node_modules/.bin/mocha
|
||||
45
test/release/butternut.sh
Executable file
45
test/release/butternut.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/butternut \
|
||||
&& git clone https://github.com/Rich-Harris/butternut.git tmp/butternut \
|
||||
&& cd tmp/butternut \
|
||||
&& rm -rf .git/hooks \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -25 +24,0 @@
|
||||
- "prepublish": "npm run test:min",
|
||||
--- a/rollup.config.js
|
||||
+++ b/rollup.config.js
|
||||
@@ -1 +0,0 @@
|
||||
-import buble from 'rollup-plugin-buble';
|
||||
@@ -28,6 +26,0 @@ const config = {
|
||||
- buble({
|
||||
- include: ['src/**', 'node_modules/acorn/**'],
|
||||
- transforms: {
|
||||
- dangerousForOf: true
|
||||
- }
|
||||
- }),
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm install \
|
||||
&& rm -rf dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& node_modules/.bin/mocha test/test.js
|
||||
33
test/release/install.sh
Executable file
33
test/release/install.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
if command -v timeout &> /dev/null; then NATIVE=1; fi
|
||||
timeout() {
|
||||
T=$1
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
expect <<EOF
|
||||
set timeout $T
|
||||
spawn -noecho sh -c "$@"
|
||||
expect timeout { exit 124 } eof
|
||||
catch wait ret
|
||||
exit [lindex \$ret 3]
|
||||
EOF
|
||||
return $?
|
||||
}
|
||||
if [ $NATIVE ]; then unset -f timeout; fi
|
||||
|
||||
git clone --branch v1.6.0 --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
|
||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||
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
|
||||
198
test/release/mathjs.sh
Executable file
198
test/release/mathjs.sh
Executable file
@@ -0,0 +1,198 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS="--annotations $@"
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
for i in `find $DIRS -type f -name '*.mjs'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/mathjs \
|
||||
&& git clone --depth 1 --branch v9.2.0 https://github.com/josdejong/mathjs.git tmp/mathjs \
|
||||
&& cd tmp/mathjs \
|
||||
&& rm -rf .git/hooks \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/gulpfile.cjs
|
||||
+++ b/gulpfile.cjs
|
||||
@@ -74 +74 @@ const webpackConfig = {
|
||||
- mode: 'production',
|
||||
+ mode: 'development',
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -132,2 +131,0 @@
|
||||
- "prepublishOnly": "npm run test:all && npm run lint",
|
||||
- "prepare": "npm run build",
|
||||
--- a/src/utils/string.js
|
||||
+++ b/src/utils/string.js
|
||||
@@ -15,0 +16,7 @@ export function endsWith (text, search) {
|
||||
+export function HACK (value) {
|
||||
+ if (typeof value == "object") {
|
||||
+ (value = Object.create(value)).valueOf = function() { return this }
|
||||
+ }
|
||||
+ return value
|
||||
+}
|
||||
+
|
||||
@@ -68 +75 @@ export function format (value, options) {
|
||||
- return value.toString()
|
||||
+ return HACK(value).toString()
|
||||
--- a/test/node-tests/cli/cli.test.js
|
||||
+++ b/test/node-tests/cli/cli.test.js
|
||||
@@ -36 +35,0 @@ describe('command line interface', function () {
|
||||
- const path2 = path.join(__dirname, 'script2')
|
||||
@@ -38,2 +37,2 @@ describe('command line interface', function () {
|
||||
- run('"' + path1 + '" "' + path2 + '"', function (e, result) {
|
||||
- assert.strictEqual(result, '2\n8\n')
|
||||
+ run('"' + path1 + '"', function (e, result) {
|
||||
+ assert.strictEqual(result, '2\n')
|
||||
--- a/test/unit-tests/expression/node/Node.test.js
|
||||
+++ b/test/unit-tests/expression/node/Node.test.js
|
||||
@@ -157 +157 @@ describe('Node', function () {
|
||||
- assert.throws(function () {
|
||||
+ if (0) assert.throws(function () {
|
||||
--- a/test/unit-tests/expression/parse.test.js
|
||||
+++ b/test/unit-tests/expression/parse.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../src/utils/string.js'
|
||||
@@ -333 +334 @@ describe('parse', function () {
|
||||
- assert.strictEqual(fmath.parse('1/3').compile().evaluate().toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(fmath.parse('1/3').compile().evaluate()).toString(), '0.(3)')
|
||||
--- a/test/unit-tests/function/arithmetic/abs.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/abs.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -35,3 +36,3 @@ describe('abs', function () {
|
||||
- assert.strictEqual(abs(a).toString(), '0.(3)')
|
||||
- assert.strictEqual(a.toString(), '-0.(3)')
|
||||
- assert.strictEqual(abs(fraction('1/3')).toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(abs(a)).toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '-0.(3)')
|
||||
+ assert.strictEqual(HACK(abs(fraction('1/3'))).toString(), '0.(3)')
|
||||
--- a/test/unit-tests/function/arithmetic/addScalar.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/addScalar.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -71 +72 @@ describe('addScalar', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||
@@ -73 +74 @@ describe('addScalar', function () {
|
||||
- assert.strictEqual(add(math.fraction(1), math.fraction(1, 3)).toString(), '1.(3)')
|
||||
+ assert.strictEqual(HACK(add(math.fraction(1), math.fraction(1, 3))).toString(), '1.(3)')
|
||||
--- a/test/unit-tests/function/arithmetic/ceil.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/ceil.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -88 +89 @@ describe('ceil', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
@@ -105 +106 @@ describe('ceil', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
@@ -107 +108 @@ describe('ceil', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/fix.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/fix.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -107 +108 @@ describe('fix', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
@@ -124 +125 @@ describe('fix', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
@@ -127 +128 @@ describe('fix', function () {
|
||||
- assert.strictEqual(b.toString(), '-0.(6)')
|
||||
+ assert.strictEqual(HACK(b).toString(), '-0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/floor.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/floor.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -96 +97 @@ describe('floor', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/gcd.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/gcd.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -62 +63 @@ describe('gcd', function () {
|
||||
- assert.strictEqual(gcd(a, math.fraction(3, 7)).toString(), '0.017(857142)')
|
||||
+ assert.strictEqual(HACK(gcd(a, math.fraction(3, 7))).toString(), '0.017(857142)')
|
||||
--- a/test/unit-tests/function/arithmetic/multiply.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/multiply.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -129 +130 @@ describe('multiply', function () {
|
||||
- assert.strictEqual(multiply(math.fraction(2), math.fraction(1, 3)).toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(multiply(math.fraction(2), math.fraction(1, 3))).toString(), '0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/round.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/round.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -82 +83 @@ describe('round', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/subtract.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/subtract.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -76,2 +77,2 @@ describe('subtract', function () {
|
||||
- assert.strictEqual(subtract(a, math.fraction(1, 6)).toString(), '0.1(6)')
|
||||
- assert.strictEqual(a.toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(subtract(a, math.fraction(1, 6))).toString(), '0.1(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||
@@ -80 +81 @@ describe('subtract', function () {
|
||||
- assert.strictEqual(subtract(math.fraction(1), math.fraction(1, 3)).toString(), '0.(6)')
|
||||
+ assert.strictEqual(HACK(subtract(math.fraction(1), math.fraction(1, 3))).toString(), '0.(6)')
|
||||
--- a/test/unit-tests/function/arithmetic/unaryMinus.test.js
|
||||
+++ b/test/unit-tests/function/arithmetic/unaryMinus.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -31 +32 @@ describe('unaryMinus', function () {
|
||||
- assert.deepStrictEqual(math.unaryMinus(bignumber(0)).toString(), '0')
|
||||
+ assert.deepStrictEqual(HACK(math.unaryMinus(bignumber(0))).toString(), '0')
|
||||
--- a/test/unit-tests/function/relational/compare.test.js
|
||||
+++ b/test/unit-tests/function/relational/compare.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -76,2 +77,2 @@ describe('compare', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(3)')
|
||||
- assert.strictEqual(b.toString(), '0.1(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(b).toString(), '0.1(6)')
|
||||
--- a/test/unit-tests/function/relational/compareNatural.test.js
|
||||
+++ b/test/unit-tests/function/relational/compareNatural.test.js
|
||||
@@ -0,0 +1 @@
|
||||
+import { HACK } from '../../../../src/utils/string.js'
|
||||
@@ -57,2 +58,2 @@ describe('compareNatural', function () {
|
||||
- assert.strictEqual(a.toString(), '0.(3)')
|
||||
- assert.strictEqual(b.toString(), '0.1(6)')
|
||||
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||
+ assert.strictEqual(HACK(b).toString(), '0.1(6)')
|
||||
--- a/test/unit-tests/type/matrix/Matrix.test.js
|
||||
+++ b/test/unit-tests/type/matrix/Matrix.test.js
|
||||
@@ -44 +44 @@ describe('matrix', function () {
|
||||
- assert.throws(function () { m.toString() }, /Cannot invoke toString on a Matrix interface/)
|
||||
+ if (0) assert.throws(function () { m.toString() }, /Cannot invoke toString on a Matrix interface/)
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "bin" \
|
||||
&& minify_in_situ "src" \
|
||||
&& minify_in_situ "test" \
|
||||
&& minify_in_situ "tools" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& rm -rf lib \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "lib" \
|
||||
&& npm run test:all
|
||||
84
test/release/rollup-es.sh
Executable file
84
test/release/rollup-es.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/rollup \
|
||||
&& git clone https://github.com/rollup/rollup.git tmp/rollup \
|
||||
&& cd tmp/rollup \
|
||||
&& rm -rf .git/hooks \
|
||||
&& git checkout 3d80c06f895eab41e648ee99786fa68c72458b80 \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -23 +22,0 @@
|
||||
- "prepublishOnly": "npm run lint && npm run test:only && npm run test:leak",
|
||||
--- a/rollup.config.js
|
||||
+++ b/rollup.config.js
|
||||
@@ -1,5 +1,4 @@
|
||||
import { readFileSync } from 'fs';
|
||||
-import buble from 'rollup-plugin-buble';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import json from 'rollup-plugin-json';
|
||||
@@ -25,12 +24,6 @@ export default [
|
||||
input: 'src/node-entry.js',
|
||||
plugins: [
|
||||
json(),
|
||||
- buble({
|
||||
- include: ['src/**', 'node_modules/acorn/**'],
|
||||
- target: {
|
||||
- node: '4'
|
||||
- }
|
||||
- }),
|
||||
resolve(),
|
||||
commonjs()
|
||||
],
|
||||
@@ -48,12 +41,6 @@ export default [
|
||||
input: 'src/browser-entry.js',
|
||||
plugins: [
|
||||
json(),
|
||||
- buble({
|
||||
- include: ['src/**', 'node_modules/acorn/**'],
|
||||
- target: {
|
||||
- node: '4'
|
||||
- }
|
||||
- }),
|
||||
resolve(),
|
||||
commonjs(),
|
||||
{
|
||||
@@ -80,7 +67,6 @@ export default [
|
||||
plugins: [
|
||||
string({ include: '**/*.md' }),
|
||||
json(),
|
||||
- buble({ target: { node: 4 } }),
|
||||
commonjs({
|
||||
include: 'node_modules/**'
|
||||
}),
|
||||
--- a/test/mocha.opts
|
||||
+++ b/test/mocha.opts
|
||||
@@ -1,2 +1 @@
|
||||
---require buble/register
|
||||
test/test.js
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "bin" \
|
||||
&& minify_in_situ "browser" \
|
||||
&& minify_in_situ "src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& rm -rf dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& node_modules/.bin/mocha
|
||||
52
test/release/rollup-ts.sh
Executable file
52
test/release/rollup-ts.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
|
||||
do
|
||||
echo "$i"
|
||||
node_modules/.bin/esbuild --loader=ts --target=node14 < "$i" \
|
||||
| uglify-js $UGLIFY_OPTIONS -o "$i"
|
||||
done
|
||||
}
|
||||
|
||||
rm -rf tmp/rollup \
|
||||
&& git clone --depth 1 --branch v2.39.1 https://github.com/rollup/rollup.git tmp/rollup \
|
||||
&& cd tmp/rollup \
|
||||
&& rm -rf .git/hooks \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -27,4 +26,0 @@
|
||||
- "postinstall": "husky install",
|
||||
- "postpublish": "pinst --enable",
|
||||
- "prepare": "npm run build",
|
||||
- "prepublishOnly": "pinst --disable && npm ci && npm run lint:nofix && npm run security && npm run build:bootstrap && npm run test:all",
|
||||
--- a/test/cli/index.js
|
||||
+++ b/test/cli/index.js
|
||||
@@ -13,0 +14,3 @@ sander.rimrafSync(__dirname, 'node_modules');
|
||||
+sander.rimrafSync(__dirname, 'samples', 'watch', 'bundle-error');
|
||||
+sander.rimrafSync(__dirname, 'samples', 'watch', 'watch-config-error');
|
||||
+sander.rimrafSync(__dirname, 'samples', 'watch', 'watch-config-initial-error');
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
npm install esbuild-wasm@0.8.56 \
|
||||
&& minify_in_situ "cli" \
|
||||
&& minify_in_situ "src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& rm -rf dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& node_modules/.bin/mocha test/test.js \
|
||||
&& node_modules/.bin/mocha test/browser/index.js
|
||||
90
test/release/sucrase.sh
Executable file
90
test/release/sucrase.sh
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js=$PWD/bin/uglifyjs
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
for i in `find $DIRS -type f -name '*.mjs'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
|
||||
do
|
||||
echo "$i"
|
||||
node_modules/.bin/esbuild --loader=ts --target=node14 < "$i" \
|
||||
| uglify-js $UGLIFY_OPTIONS -o "$i"
|
||||
done
|
||||
}
|
||||
|
||||
rm -rf tmp/sucrase \
|
||||
&& git clone https://github.com/alangpierce/sucrase.git tmp/sucrase \
|
||||
&& cd tmp/sucrase \
|
||||
&& rm -rf .git/hooks \
|
||||
&& git checkout 38b66f3009feb76750a799deea211adcc83574f1 \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -25 +24,0 @@
|
||||
- "prepublishOnly": "yarn clean && yarn build",
|
||||
@@ -65 +63,0 @@
|
||||
- "test262-harness": "^6.5.0",
|
||||
--- a/script/build.ts
|
||||
+++ b/script/build.ts
|
||||
@@ -16 +15,0 @@ async function main(): Promise<void> {
|
||||
- () => buildBenchmark(),
|
||||
@@ -18,5 +16,0 @@ async function main(): Promise<void> {
|
||||
- () => buildIntegration("./integrations/gulp-plugin"),
|
||||
- () => buildIntegration("./integrations/jest-plugin"),
|
||||
- () => buildIntegration("./integrations/webpack-loader"),
|
||||
- () => buildIntegration("./integrations/webpack-object-rest-spread-plugin"),
|
||||
- () => buildWebsite(),
|
||||
@@ -66,3 +59,0 @@ async function buildSucrase(): Promise<void> {
|
||||
- // Also add in .d.ts files from tsc, which only need to be compiled once.
|
||||
- await run(\`\${TSC} --project ./src --outDir ./dist-types\`);
|
||||
- await mergeDirectoryContents("./dist-types/src", "./dist");
|
||||
@@ -70 +61 @@ async function buildSucrase(): Promise<void> {
|
||||
- await run("yarn link");
|
||||
+ await run("npm link");
|
||||
--- a/src/identifyShadowedGlobals.ts
|
||||
+++ b/src/identifyShadowedGlobals.ts
|
||||
@@ -23,0 +24 @@ export default function identifyShadowedGlobals(
|
||||
+export { identifyShadowedGlobals as HACK };
|
||||
--- a/src/parser/tokenizer/state.ts
|
||||
+++ b/src/parser/tokenizer/state.ts
|
||||
@@ -100,0 +101 @@ export default class State {
|
||||
+export { State as HACK };
|
||||
--- a/src/transformers/JSXTransformer.ts
|
||||
+++ b/src/transformers/JSXTransformer.ts
|
||||
@@ -253,0 +254 @@ export default class JSXTransformer extends Transformer {
|
||||
+export { JSXTransformer as HACK };
|
||||
--- a/src/util/getClassInfo.ts
|
||||
+++ b/src/util/getClassInfo.ts
|
||||
@@ -164,0 +165 @@ export default function getClassInfo(
|
||||
+export { getClassInfo as HACK };
|
||||
--- a/src/util/getDeclarationInfo.ts
|
||||
+++ b/src/util/getDeclarationInfo.ts
|
||||
@@ -40,0 +41 @@ export default function getDeclarationInfo(tokens: TokenProcessor): DeclarationI
|
||||
+export { getDeclarationInfo as HACK };
|
||||
--- a/src/util/getJSXPragmaInfo.ts
|
||||
+++ b/src/util/getJSXPragmaInfo.ts
|
||||
@@ -14,0 +15 @@ export default function getJSXPragmaInfo(options: Options): JSXPragmaInfo {
|
||||
+export { getJSXPragmaInfo as HACK };
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
npm install esbuild-wasm@0.8.56 \
|
||||
&& minify_in_situ "src" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm install \
|
||||
&& npm run clean \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& minify_in_situ "dist-self-build" \
|
||||
&& npm run test-only
|
||||
47
test/release/web-tooling-benchmark.sh
Executable file
47
test/release/web-tooling-benchmark.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
|
||||
alias uglify-js="node --max-old-space-size=4096 $PWD/bin/uglifyjs"
|
||||
UGLIFY_OPTIONS=$@
|
||||
|
||||
minify_in_situ() {
|
||||
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||
DIRS="$1"
|
||||
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||
for i in `find $DIRS -type f -name '*.js'`
|
||||
do
|
||||
ARGS="$ARGS $i"
|
||||
done
|
||||
uglify-js $ARGS
|
||||
}
|
||||
|
||||
rm -rf tmp/web-tooling-benchmark \
|
||||
&& git clone --depth 1 --branch v0.5.3 https://github.com/v8/web-tooling-benchmark.git tmp/web-tooling-benchmark \
|
||||
&& cd tmp/web-tooling-benchmark \
|
||||
&& rm -rf .git/hooks \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -12 +11,0 @@
|
||||
- "postinstall": "npm run build:terser-bundled && npm run build:uglify-js-bundled && npm run build",
|
||||
--- a/src/cli-flags-helper.js
|
||||
+++ b/src/cli-flags-helper.js
|
||||
@@ -7 +6,0 @@ const targetList = new Set([
|
||||
- "chai",
|
||||
--- a/src/cli.js
|
||||
+++ b/src/cli.js
|
||||
@@ -18,0 +19 @@ suite.on("error", event => {
|
||||
+ global.process.exitCode = 42;
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "src" \
|
||||
&& minify_in_situ "third_party" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm ci \
|
||||
&& rm -rf build/* \
|
||||
&& npm run build:terser-bundled \
|
||||
&& npm run build:uglify-js-bundled \
|
||||
&& minify_in_situ "build" \
|
||||
&& rm -rf dist \
|
||||
&& npm run build \
|
||||
&& minify_in_situ "dist" \
|
||||
&& node dist/cli.js
|
||||
@@ -27,7 +27,7 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
|
||||
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
|
||||
if ([
|
||||
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
|
||||
/\b(async[ \t]+function|setInterval|setTimeout)\b/,
|
||||
/\b(async[ \t]+function|setImmediate|setInterval|setTimeout)\b/,
|
||||
/\basync([ \t]+|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
|
||||
].some(function(pattern) {
|
||||
return pattern.test(code);
|
||||
@@ -175,12 +175,14 @@ function setup(global, builtins, setup_log, setup_tty) {
|
||||
[
|
||||
// for Node.js v0.12
|
||||
"Buffer",
|
||||
"clearImmediate",
|
||||
"clearInterval",
|
||||
"clearTimeout",
|
||||
// for Node.js v0.12
|
||||
"DTRACE_NET_STREAM_END",
|
||||
// for Node.js v8
|
||||
"process",
|
||||
"setImmediate",
|
||||
"setInterval",
|
||||
"setTimeout",
|
||||
].forEach(function(name) {
|
||||
|
||||
@@ -149,6 +149,7 @@ var SUPPORT = function(matrix) {
|
||||
for_of: "for (var a of []);",
|
||||
generator: "function* f(){}",
|
||||
let: "let a;",
|
||||
new_target: "function f() { new.target; }",
|
||||
nullish: "0 ?? 0",
|
||||
rest: "var [...a] = [];",
|
||||
rest_object: "var {...a} = {};",
|
||||
@@ -157,6 +158,9 @@ var SUPPORT = function(matrix) {
|
||||
template: "``",
|
||||
trailing_comma: "function f(a,) {}",
|
||||
});
|
||||
if (SUPPORT.exponentiation && sandbox.run_code("console.log(10 ** 100 === Math.pow(10, 100));") !== "true\n") {
|
||||
SUPPORT.exponentiation = false;
|
||||
}
|
||||
|
||||
var VALUES = [
|
||||
'"a"',
|
||||
@@ -184,9 +188,9 @@ var VALUES = [
|
||||
"25. ",
|
||||
"0x26.toString()",
|
||||
"NaN",
|
||||
"undefined",
|
||||
"Infinity",
|
||||
"null",
|
||||
"Infinity",
|
||||
"undefined",
|
||||
"[]",
|
||||
"[,0][1]", // an array with elisions... but this is always false
|
||||
"([,0].length === 2)", // an array with elisions... this is always true
|
||||
@@ -240,51 +244,28 @@ BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS.push(" in ");
|
||||
|
||||
var ASSIGNMENTS = [
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
"=",
|
||||
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
"+=",
|
||||
|
||||
var ASSIGNMENTS = [ "=" ];
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
ASSIGNMENTS.push("+=");
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat([
|
||||
"-=",
|
||||
"*=",
|
||||
"/=",
|
||||
"%=",
|
||||
"&=",
|
||||
"|=",
|
||||
"^=",
|
||||
"<<=",
|
||||
">>=",
|
||||
">>>=",
|
||||
"%=",
|
||||
];
|
||||
]);
|
||||
if (SUPPORT.exponentiation) {
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
ASSIGNMENTS.push("**=");
|
||||
}
|
||||
|
||||
var UNARY_SAFE = [
|
||||
"+",
|
||||
@@ -363,11 +344,13 @@ var lambda_vars = [];
|
||||
var unique_vars = [];
|
||||
var classes = [];
|
||||
var async = false;
|
||||
var has_await = false;
|
||||
var export_default = false;
|
||||
var generator = false;
|
||||
var loops = 0;
|
||||
var funcs = 0;
|
||||
var clazz = 0;
|
||||
var imports = 0;
|
||||
var in_class = 0;
|
||||
var called = Object.create(null);
|
||||
var labels = 10000;
|
||||
@@ -392,6 +375,14 @@ function appendExport(stmtDepth, allowDefault) {
|
||||
return "";
|
||||
}
|
||||
|
||||
function mayDefer(code) {
|
||||
if (SUPPORT.arrow && rng(200) == 0) {
|
||||
has_await = true;
|
||||
return "void setImmediate(() => (" + code + "))";
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
function createTopLevelCode() {
|
||||
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
|
||||
block_vars.length = 0;
|
||||
@@ -399,11 +390,13 @@ function createTopLevelCode() {
|
||||
unique_vars.length = 0;
|
||||
classes.length = 0;
|
||||
async = false;
|
||||
has_await = false;
|
||||
export_default = false;
|
||||
generator = false;
|
||||
loops = 0;
|
||||
funcs = 0;
|
||||
clazz = 0;
|
||||
imports = 0;
|
||||
in_class = 0;
|
||||
called = Object.create(null);
|
||||
var s = [
|
||||
@@ -419,7 +412,9 @@ function createTopLevelCode() {
|
||||
}
|
||||
});
|
||||
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||
s.push("console.log(null, a, b, c, Infinity, NaN, undefined);");
|
||||
var log = "console.log(null, a, b, c, Infinity, NaN, undefined)";
|
||||
if (SUPPORT.arrow && has_await && rng(20) == 0) log = "setImmediate(() => " + log + ")";
|
||||
s.push(log + ";");
|
||||
return s.join("\n");
|
||||
}
|
||||
|
||||
@@ -708,7 +703,7 @@ function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
||||
consts.forEach(addAvoidVar);
|
||||
lets.forEach(addAvoidVar);
|
||||
var s = [];
|
||||
if (SUPPORT.class) while (rng(100) == 0) {
|
||||
if (SUPPORT.class) while (rng(200) == 0) {
|
||||
var name = "C" + clazz++;
|
||||
classes.push(name);
|
||||
s.push(appendExport(stmtDepth, true) + createClassLiteral(recurmax, stmtDepth, canThrow, name));
|
||||
@@ -806,8 +801,8 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var lambda_len = lambda_vars.length;
|
||||
var save_async = async;
|
||||
async = SUPPORT.async && rng(50) == 0;
|
||||
var save_generator = generator;
|
||||
async = SUPPORT.async && rng(200) == 0;
|
||||
generator = SUPPORT.generator && rng(50) == 0;
|
||||
if (async && generator && !SUPPORT.async_generator) {
|
||||
if (rng(2)) {
|
||||
@@ -919,6 +914,21 @@ function getLabel(label) {
|
||||
return label && " L" + label;
|
||||
}
|
||||
|
||||
function declareVarName(name, no_var) {
|
||||
if (!SUPPORT.let || !no_var && rng(10)) return "var ";
|
||||
block_vars.push(name);
|
||||
return rng(2) ? "let " : "const ";
|
||||
}
|
||||
|
||||
function createImportAlias() {
|
||||
if (rng(10)) return "alias" + imports++;
|
||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||
var name = createVarName(MANDATORY);
|
||||
block_vars.push(name);
|
||||
unique_vars.length -= 6;
|
||||
return name;
|
||||
}
|
||||
|
||||
function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth, target) {
|
||||
++stmtDepth;
|
||||
var loop = ++loops;
|
||||
@@ -955,6 +965,8 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
||||
return label.target + "for (var brake" + loop + " = 5; " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " && brake" + loop + " > 0; --brake" + loop + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
||||
case STMT_FOR_ENUM:
|
||||
var block_len = block_vars.length;
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var label = createLabel(canBreak, canContinue);
|
||||
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
||||
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
||||
@@ -963,12 +975,8 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
var init = "";
|
||||
if (!/^key/.test(key)) {
|
||||
if (!(of && bug_for_of_var) && rng(10) == 0) init = "var ";
|
||||
} else if (!SUPPORT.let || !(of && bug_for_of_var) && rng(10)) {
|
||||
init = "var ";
|
||||
} else if (rng(2)) {
|
||||
init = "let ";
|
||||
} else {
|
||||
init = "const ";
|
||||
init = declareVarName(key, of && bug_for_of_var);
|
||||
}
|
||||
if (!SUPPORT.destructuring || of && !(canThrow && rng(20) == 0) || rng(10)) {
|
||||
init += key;
|
||||
@@ -997,14 +1005,29 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
s += '"" + (' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "); ";
|
||||
}
|
||||
s += label.target + " for ";
|
||||
if (await) s += "await ";
|
||||
if (await) {
|
||||
s += "await ";
|
||||
has_await = true;
|
||||
}
|
||||
s += "(" + init + " of expr" + loop + ") {";
|
||||
} else {
|
||||
s += createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; ";
|
||||
s += label.target + " for (" + init + " in expr" + loop + ") {";
|
||||
}
|
||||
if (rng(3)) s += "c = 1 + c; var " + createVarName(MANDATORY) + " = expr" + loop + "[" + key + "]; ";
|
||||
if (/^key/.test(key)) VAR_NAMES.push(key);
|
||||
if (rng(3)) {
|
||||
s += "c = 1 + c; ";
|
||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||
var name;
|
||||
do {
|
||||
name = createVarName(MANDATORY);
|
||||
} while (name == key);
|
||||
unique_vars.length -= 6;
|
||||
s += declareVarName(name) + name + " = expr" + loop + "[" + key + "]; ";
|
||||
}
|
||||
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
||||
VAR_NAMES.length = nameLenBefore;
|
||||
block_vars.length = block_len;
|
||||
return "{" + s + "}";
|
||||
case STMT_SEMI:
|
||||
return use_strict && rng(20) === 0 ? '"use strict";' : ";";
|
||||
@@ -1020,30 +1043,20 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
||||
case STMT_VAR:
|
||||
if (SUPPORT.destructuring && stmtDepth == 1 && rng(5) == 0) {
|
||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||
var s = "";
|
||||
if (rng(2)) {
|
||||
var name = createVarName(MANDATORY);
|
||||
block_vars.push(name);
|
||||
s += " " + name;
|
||||
}
|
||||
var s = rng(2) ? " " + createImportAlias() : "";
|
||||
if (rng(10)) {
|
||||
if (s) s += ",";
|
||||
if (rng(2)) {
|
||||
var name = createVarName(MANDATORY);
|
||||
block_vars.push(name);
|
||||
s += " * as " + name;
|
||||
s += " * as " + createImportAlias();
|
||||
} else {
|
||||
var names = [];
|
||||
for (var i = rng(4); --i >= 0;) {
|
||||
var name = createVarName(MANDATORY);
|
||||
block_vars.push(name);
|
||||
var name = createImportAlias();
|
||||
names.push(rng(2) ? getDotKey() + " as " + name : name);
|
||||
}
|
||||
s += " { " + names.join(", ") + " }";
|
||||
}
|
||||
}
|
||||
unique_vars.length -= 6;
|
||||
if (s) s += " from";
|
||||
return "import" + s + ' "path/to/module.js";';
|
||||
} else if (SUPPORT.destructuring && rng(20) == 0) {
|
||||
@@ -1191,7 +1204,10 @@ function createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
return "((c = c + 1) + (" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + "))"; // c only gets incremented
|
||||
default:
|
||||
var expr = "(" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + ")";
|
||||
if (async && rng(50) == 0) return "(await" + expr + ")";
|
||||
if (async && rng(50) == 0) {
|
||||
has_await = true;
|
||||
return "(await" + expr + ")";
|
||||
}
|
||||
if (generator && rng(50) == 0) return "(yield" + (canThrow && rng(20) == 0 ? "*" : "") + expr + ")";
|
||||
return expr;
|
||||
}
|
||||
@@ -1223,6 +1239,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
case p++:
|
||||
return createValue();
|
||||
case p++:
|
||||
if (SUPPORT.destructuring && rng(20) == 0) {
|
||||
var name = "alias" + rng(imports + 2);
|
||||
return canThrow && rng(20) == 0 ? name : "typeof " + name + ' != "undefined" && ' + name;
|
||||
}
|
||||
case p++:
|
||||
return getVarName();
|
||||
case p++:
|
||||
@@ -1257,8 +1277,8 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var lambda_len = lambda_vars.length;
|
||||
var save_async = async;
|
||||
async = SUPPORT.async && rng(50) == 0;
|
||||
var save_generator = generator;
|
||||
async = SUPPORT.async && rng(200) == 0;
|
||||
generator = SUPPORT.generator && rng(50) == 0;
|
||||
if (async && generator && !SUPPORT.async_generator) {
|
||||
if (rng(2)) {
|
||||
@@ -1361,13 +1381,16 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
s.push(
|
||||
instantiate + makeFunction(name) + "(" + createParams(save_async, save_generator) + "){",
|
||||
strictMode(),
|
||||
defns()
|
||||
strictMode()
|
||||
);
|
||||
var add_new_target = SUPPORT.new_target && VALUES.indexOf("new.target") < 0;
|
||||
if (add_new_target) VALUES.push("new.target");
|
||||
s.push(defns());
|
||||
if (instantiate) for (var i = rng(4); --i >= 0;) {
|
||||
s.push((in_class ? "if (this) " : "") + createThisAssignment(recurmax, stmtDepth, canThrow));
|
||||
}
|
||||
s.push(_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
if (add_new_target) VALUES.splice(VALUES.indexOf("new.target"), 1);
|
||||
});
|
||||
generator = save_generator;
|
||||
async = save_async;
|
||||
@@ -1452,31 +1475,35 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
case p++:
|
||||
case p++:
|
||||
var name = getVarName();
|
||||
var s = name + "." + getDotKey();
|
||||
s = "typeof " + s + ' == "function" && --_calls_ >= 0 && ' + s + createArgs(recurmax, stmtDepth, canThrow);
|
||||
return canThrow && rng(20) == 0 ? s : name + " && " + s;
|
||||
var fn = name + "." + getDotKey();
|
||||
var s = "typeof " + fn + ' == "function" && --_calls_ >= 0 && ';
|
||||
s += rng(5) ? fn : "(" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ", " + fn + ")";
|
||||
s += createArgs(recurmax, stmtDepth, canThrow);
|
||||
return mayDefer(canThrow && rng(20) == 0 ? s : name + " && " + s);
|
||||
case p++:
|
||||
if (SUPPORT.class && classes.length) switch (rng(20)) {
|
||||
case 0:
|
||||
return "--_calls_ >= 0 && new " + classes[rng(classes.length)] + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
||||
case 1:
|
||||
var s = "--_calls_ >= 0 && new ";
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var class_len = classes.length;
|
||||
var name;
|
||||
if (canThrow && rng(20) == 0) {
|
||||
in_class++;
|
||||
name = createVarName(MAYBE);
|
||||
in_class--;
|
||||
} else if (rng(2)) {
|
||||
name = "C" + clazz++;
|
||||
classes.push(name);
|
||||
if (SUPPORT.class) {
|
||||
if (classes.length && rng(20) == 0) {
|
||||
return "--_calls_ >= 0 && new " + classes[rng(classes.length)] + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
||||
}
|
||||
if (rng(200) == 0) {
|
||||
var s = "--_calls_ >= 0 && new ";
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var class_len = classes.length;
|
||||
var name;
|
||||
if (canThrow && rng(20) == 0) {
|
||||
in_class++;
|
||||
name = createVarName(MAYBE);
|
||||
in_class--;
|
||||
} else if (rng(2)) {
|
||||
name = "C" + clazz++;
|
||||
classes.push(name);
|
||||
}
|
||||
s += createClassLiteral(recurmax, stmtDepth, canThrow, name);
|
||||
classes.length = class_len;
|
||||
VAR_NAMES.length = nameLenBefore;
|
||||
s += createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
||||
return s;
|
||||
}
|
||||
s += createClassLiteral(recurmax, stmtDepth, canThrow, name);
|
||||
classes.length = class_len;
|
||||
VAR_NAMES.length = nameLenBefore;
|
||||
s += createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
||||
return s;
|
||||
}
|
||||
case p++:
|
||||
case p++:
|
||||
@@ -1486,7 +1513,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
name = rng(3) == 0 ? getVarName() : "f" + rng(funcs + 2);
|
||||
} while (name in called && !called[name]);
|
||||
called[name] = true;
|
||||
return "typeof " + name + ' == "function" && --_calls_ >= 0 && ' + name + createArgs(recurmax, stmtDepth, canThrow);
|
||||
return mayDefer("typeof " + name + ' == "function" && --_calls_ >= 0 && ' + name + createArgs(recurmax, stmtDepth, canThrow));
|
||||
}
|
||||
_createExpression.N = p;
|
||||
return _createExpression(recurmax, noComma, stmtDepth, canThrow);
|
||||
@@ -1546,15 +1573,19 @@ var SAFE_KEYS = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"undefined",
|
||||
"null",
|
||||
"NaN",
|
||||
"Infinity",
|
||||
"done",
|
||||
"foo",
|
||||
"NaN",
|
||||
"null",
|
||||
"Infinity",
|
||||
"undefined",
|
||||
"async",
|
||||
"done",
|
||||
"get",
|
||||
"in",
|
||||
"length",
|
||||
"next",
|
||||
"set",
|
||||
"static",
|
||||
"then",
|
||||
"value",
|
||||
"var",
|
||||
@@ -1648,7 +1679,7 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
|
||||
generator = false;
|
||||
name = "constructor";
|
||||
} else {
|
||||
async = SUPPORT.async && rng(50) == 0;
|
||||
async = SUPPORT.async && rng(200) == 0;
|
||||
generator = SUPPORT.generator && rng(50) == 0;
|
||||
if (async && generator && !SUPPORT.async_generator) {
|
||||
if (rng(2)) {
|
||||
@@ -1895,7 +1926,11 @@ function createTypeofExpr(recurmax, stmtDepth, canThrow) {
|
||||
}
|
||||
|
||||
function createValue() {
|
||||
return VALUES[rng(VALUES.length)];
|
||||
var v;
|
||||
do {
|
||||
v = VALUES[rng(VALUES.length)];
|
||||
} while (v == "new.target" && rng(200));
|
||||
return v;
|
||||
}
|
||||
|
||||
function createBinaryOp(noComma, canThrow) {
|
||||
|
||||
Reference in New Issue
Block a user