Compare commits

..

258 Commits

Author SHA1 Message Date
Alex Lam S.L
9a074c2637 Merge pull request #1972 from alexlamsl/harmony-v3.0.9
Merging from master for 3.0.9
2017-05-19 10:38:45 +08:00
alexlamsl
02b14528fa Merge branch 'master' into harmony-v3.0.9 2017-05-19 09:51:00 +08:00
Alex Lam S.L
3db2001633 suppress unused on block variables (#1969)
fixes #1968
2017-05-19 00:28:19 +08:00
Alex Lam S.L
aaba482e48 Merge pull request #1967 from alexlamsl/harmony-v3.0.8
Merging from master for 3.0.8
2017-05-18 16:02:29 +08:00
alexlamsl
5f29fced0a Merge branch 'master' into harmony-v3.0.8 2017-05-18 14:54:18 +08:00
kzc
b1b918e6d6 better extends paren fix (#1962) 2017-05-18 02:36:29 +08:00
kzc
ebb469e4cd fix class extends expression (#1956) 2017-05-17 03:29:25 +08:00
kzc
c22d26b483 support export default of anonymous functions and classes (#1954) 2017-05-17 03:28:24 +08:00
Alex Lam S.L
f751e64d49 Merge pull request #1951 from alexlamsl/harmony-v3.0.7
Merging from master for 3.0.7
2017-05-17 01:03:55 +08:00
alexlamsl
60c56a24b9 Merge branch 'master' into harmony-v3.0.7 2017-05-16 20:02:30 +08:00
Alex Lam S.L
01f23cf5a1 Merge pull request #1948 from alexlamsl/harmony-v3.0.6
Merging from master for 3.0.6
2017-05-16 13:26:45 +08:00
alexlamsl
99fb3e8f0d Merge branch 'master' into harmony-v3.0.6 2017-05-16 06:48:23 +08:00
Alex Lam S.L
756c9aa7dc keep minify() options in sync (#1940) 2017-05-15 20:29:48 +08:00
Alex Lam S.L
07d6bfd707 Merge pull request #1939 from alexlamsl/harmony-v3.0.5
Merging from master for 3.0.5
2017-05-15 19:48:00 +08:00
alexlamsl
81243c4e71 Merge branch 'master' into harmony-v3.0.5 2017-05-15 18:58:54 +08:00
alexlamsl
cd6e849555 Revert "remove support for const (#1910)"
This reverts commit c391576d52.
2017-05-15 18:38:16 +08:00
kzc
91de285166 uglify-es: update homepage in package.json (#1933)
to point to harmony branch on github
2017-05-14 00:25:06 +08:00
kzc
4d8f289eb0 fix export default expression; (#1932) 2017-05-13 12:56:46 +08:00
Alex Lam S.L
945ba64160 Merge pull request #1923 from alexlamsl/harmony-v3.0.4
Merging from master for 3.0.4
2017-05-12 06:52:21 +08:00
Anthony Van de Gejuchte
c699200398 Make sure globals can be accessed from the browser (#1920)
Note: no tests as there are no integration tests
2017-05-12 05:50:35 +08:00
alexlamsl
daf44f2b21 Merge branch 'master' into harmony-v3.0.4 2017-05-12 05:13:11 +08:00
Gyusun Yeom
fcd90db30d fix safari syntax error - declare twice (#1851)
To avoid Safari bug, scope of for loop should enclose parent scope variables.


fixes #1753
2017-05-11 16:48:43 +08:00
Alex Lam S.L
e2888bdc43 Merge pull request #1901 from alexlamsl/harmony-v3.0.3
Merging from master for 3.0.3
2017-05-10 14:26:58 +08:00
alexlamsl
fb50b7b627 Merge branch 'master' into harmony-v3.0.3 2017-05-10 11:52:59 +08:00
kzc
9d59c693c2 fix for-of loop with const iterator (#1899) 2017-05-10 11:36:03 +08:00
kzc
6ddb5bd94d Remove incorrect git clone instructions from uglify-es README (#1896) 2017-05-10 11:06:22 +08:00
kzc
eda49605c5 Have harmony docs use uglify-es package name. (#1894) 2017-05-10 04:41:09 +08:00
Alex Lam S.L
1e9ef17e32 Merge pull request #1892 from alexlamsl/harmony-v3.0.2
Merging from master for 3.0.2
2017-05-10 03:14:45 +08:00
alexlamsl
222100ea4c Merge branch 'master' into harmony-v3.0.2 2017-05-10 01:57:32 +08:00
Alex Lam S.L
93db48a317 rename package 2017-05-10 01:46:55 +08:00
Alex Lam S.L
2944e3df7d fix collapse_vars on destructuring declarations (#1889)
fixes #1886
2017-05-09 17:44:28 +08:00
Alex Lam S.L
e0ae8da089 Merge pull request #1885 from alexlamsl/harmony-v3.0.1
Merging from master for 3.0.1
2017-05-09 02:49:28 +08:00
alexlamsl
81f1311b24 Merge branch 'master' into harmony-v3.0.1 2017-05-09 02:10:06 +08:00
Alex Lam S.L
2433bb4e52 fix Unicode handling in parser (#1884)
There was an implicit assumption that first character within surrogate header range implies the next character must form a surrogate pair, which is not necessarily true.
2017-05-09 01:58:31 +08:00
Alex Lam S.L
3fac29a017 Merge pull request #1876 from alexlamsl/harmony-v3.0.0
Merging from master for 3.0.0
2017-05-08 01:44:07 +08:00
alexlamsl
b4c18f6b83 Merge branch 'master' into harmony-v3.0.0 2017-05-07 15:34:16 +08:00
kzc
73d6438773 fix \\n and \\r in template strings (#1857)
fixes #1856
2017-04-30 17:05:32 +08:00
kzc
5c6316a37d fix class method formatting (#1853)
fixes #1852
2017-04-29 18:13:25 +08:00
Alex Lam S.L
278577f3cb Merge pull request #1805 from alexlamsl/harmony-v2.8.22
Merging from master for 2.8.22
2017-04-09 17:27:30 +08:00
alexlamsl
0d8597e904 Merge branch 'master' into harmony-v2.8.22 2017-04-09 15:50:38 +08:00
Anthony Van de Gejuchte
c20bb99a62 Put expression after extend between parentheses if necessary (#1780) 2017-04-04 12:38:13 +08:00
Anthony Van de Gejuchte
2377171200 Fix walker not able to handle destr pattern in spread when compressing (#1438) 2017-04-04 01:23:22 +08:00
Anthony Van de Gejuchte
603d92effc Allow AST_DefaultAssign as parameter (#1778)
This may be the case for parsing arrow functions,
as left side expressions are converted to destructuring patterns
before being converted to parameters.
2017-04-04 00:46:05 +08:00
Anthony Van de Gejuchte
17f0cc359f Allow empty destructuring (#1773) 2017-04-03 17:21:27 +08:00
Alex Lam S.L
35bae3fcd0 Merge pull request #1766 from alexlamsl/harmony-v2.8.21
Merging from master for 2.8.21
2017-04-02 18:10:58 +08:00
alexlamsl
4614b5b46e Merge branch 'master' into harmony-v2.8.21 2017-04-02 17:25:20 +08:00
Ondřej Španěl
2f93058c6e More variants of import added (#1738)
- `import * from "x.js"`
- `import * as Name from "x.js"`
2017-03-31 17:52:56 +08:00
Ondřej Španěl
a729c43e87 Another variant of export added - export {Name}. (#1737) 2017-03-31 17:51:27 +08:00
Alex Lam S.L
66e9039350 Merge pull request #1740 from alexlamsl/harmony-v2.8.19
Merging from master for 2.8.19
2017-03-31 13:28:56 +08:00
alexlamsl
d717bf9ce8 Merge branch 'master' into harmony 2017-03-31 12:54:03 +08:00
Ondřej Španěl
5dea52266b [ES6] Implemented parse for export Name from Module variants. (#1701)
- add `AST_Export` new variants output
- add tests to `test/compress/`
- update `$propdoc` of `AST_Export` ("exported_names" & "module_name")
- add tests for `export ...  as ...` variants
2017-03-30 17:07:50 +08:00
Alex Lam S.L
fccefbeaca Merge pull request #1717 from alexlamsl/harmony-v2.8.17
Merging from master for 2.8.17
2017-03-29 01:01:28 +08:00
alexlamsl
1e2b0aaa04 Merge branch 'master' into harmony-v2.8.17 2017-03-28 22:03:46 +08:00
kzc
6a54de79b5 optimize trivial arrow functions with a return statement in braces (#1681)
fixes #1676
2017-03-26 12:03:11 +08:00
Alex Lam S.L
9e2290b29c Merge pull request #1636 from alexlamsl/harmony-v2.8.15
Merging from master for 2.8.15
2017-03-23 16:08:53 +08:00
alexlamsl
97d0fc271d Merge branch 'master' into harmony-v2.8.15 2017-03-23 15:28:17 +08:00
Alex Lam S.L
7906033e82 Merge pull request #1624 from alexlamsl/harmony-v2.8.14
Merging from master for 2.8.14
2017-03-19 18:24:29 +08:00
alexlamsl
4bf21ce5c1 add expect_stdout to tests 2017-03-19 15:35:39 +08:00
alexlamsl
44d6b47bdc Merge branch 'master' into harmony-v2.8.14 2017-03-19 15:31:18 +08:00
Alex Lam S.L
129e449c8e Merge pull request #1614 from alexlamsl/harmony-v2.8.13
Merging from master for 2.8.13
2017-03-18 13:02:09 +08:00
alexlamsl
75c3c8963f Merge branch 'master' into harmony-v2.8.13 2017-03-18 02:52:45 +08:00
Alex Zaworski
d26b7522d9 Allow 'name' as object literal shorthand property (#1617)
fixes #1613
2017-03-18 01:29:13 +08:00
Alex Lam S.L
2fd86d3cb0 Merge pull request #1601 from alexlamsl/harmony-v2.8.12
Merging from master for 2.8.12
2017-03-14 14:29:32 +08:00
alexlamsl
8f7ab602e2 Merge branch 'master' into harmony-v2.8.12 2017-03-14 13:17:42 +08:00
Alex Lam S.L
1dd339f95e fix unused crashes (#1599)
- `AST_DefaultAssign` on `keep_fargs`
- `AST_Expansion on` `keep_fargs`
- `AST_Destructuring` on top-level declarations without `toplevel`
2017-03-14 13:13:43 +08:00
Alex Lam S.L
c7063c1f38 Merge pull request #1591 from alexlamsl/harmony-v2.8.11
Merging from master for 2.8.11
2017-03-10 16:38:23 +08:00
alexlamsl
f4a12b34f2 Merge branch 'master' into harmony-v2.8.11 2017-03-10 11:17:49 +08:00
Alex Lam S.L
5d5c7934a5 Merge pull request #1582 from alexlamsl/harmony-v2.8.10
Merging from master for 2.8.10
2017-03-09 13:14:55 +08:00
alexlamsl
8f4b45f4f8 Merge branch 'master' into harmony-v2.8.10 2017-03-09 06:02:28 +08:00
Alex Lam S.L
952e2656eb Merge pull request #1567 from alexlamsl/harmony-v2.8.8
Merging from master for 2.8.8
2017-03-07 23:56:23 +08:00
qinayi
240383a314 is_block_scope return true when current node is an instance of AST_IterationStatement. then the scope of let variable can be figured out accurately (#1561) 2017-03-07 23:50:58 +08:00
alexlamsl
250b782b1e Merge branch 'master' into harmony-v2.8.8 2017-03-07 20:25:52 +08:00
Alex Lam S.L
3c2b3aeddb Merge pull request #1554 from alexlamsl/harmony-v2.8.6
Merging from master for 2.8.7
2017-03-05 23:03:30 +08:00
alexlamsl
aa605495f8 Merge branch 'master' into harmony-v2.8.6 2017-03-05 21:42:34 +08:00
kzc
33a26d456b patch up #1543 for harmony
fixes #1537
2017-03-05 21:39:31 +08:00
alexlamsl
49d9ac1c43 Merge branch 'master' into harmony-v2.8.6 2017-03-05 16:03:56 +08:00
Alex Lam S.L
c8e61448cb Merge pull request #1541 from alexlamsl/harmony-v2.8.5
Merging from master for 2.8.5
2017-03-03 07:30:28 +08:00
alexlamsl
f704e9b65c fix destructing crash in reduce_vars
fixes #1531
2017-03-03 07:23:46 +08:00
alexlamsl
0b77d861a8 Merge branch 'master' into harmony-v2.8.5 2017-03-03 07:17:52 +08:00
Alex Lam S.L
e27dab7e7c Merge pull request #1528 from alexlamsl/harmony-v2.8.4
Merging from master for 2.8.4
2017-03-02 11:22:06 +08:00
alexlamsl
80f3ad3ce0 Merge branch 'master' into harmony-v2.8.4 2017-03-02 11:16:55 +08:00
Alex Lam S.L
22f7af205d Merge pull request #1521 from alexlamsl/harmony-v2.8.2
Merging from master for 2.8.2
2017-03-01 11:13:32 +08:00
alexlamsl
8a7a4749c7 Merge branch 'master' into harmony-v2.8.2 2017-03-01 11:06:33 +08:00
Alex Lam S.L
514fc68f4f Merge pull request #1509 from alexlamsl/harmony-2.8.0
Merging from master for 2.8.0
2017-02-28 23:14:25 +08:00
alexlamsl
478aaab469 fix parser test
not sure if `start.pos` is correct, but oh well
2017-02-28 14:08:31 +08:00
alexlamsl
ab217539e9 restore sourceMappingURL in test 2017-02-28 13:23:02 +08:00
alexlamsl
a942dc07c4 fix parser tests
update exception messages
2017-02-28 03:58:01 +08:00
kzc
a0eaff750d fix parsing of arrow function with bind
fixes #1510
2017-02-28 02:47:33 +08:00
alexlamsl
57777b6cfa Merge branch 'master' into harmony-2.8.0 2017-02-28 02:28:58 +08:00
kzc
8d205f7f39 fix parser handling of comments 2017-02-27 14:54:47 +08:00
alexlamsl
bc9bfd15a2 fix test 2017-02-27 11:39:48 +08:00
alexlamsl
9fc1c4b3b5 update test
top-level block-variables not within blocks are global variables
2017-02-27 06:23:12 +08:00
alexlamsl
c59bf5e8d8 fix SymbolDef.global
properly compute for top-level block-variables
2017-02-27 06:20:08 +08:00
alexlamsl
d2d3a6e065 fix double-descend()
for `AST_Export` in `AST_Toplevel.figure_out_scope()`
2017-02-27 06:06:09 +08:00
alexlamsl
7755733716 fix "Starting destructuring."
commit 32f76f7ff does not take into account `AST_SymbolFunarg` is also `AST_SymbolVar`, so don't need to call `AST_Scope.def_variable()` twice
2017-02-27 05:30:18 +08:00
alexlamsl
b3a987b0df fix up drop_unused() 2017-02-27 05:11:01 +08:00
alexlamsl
88a338f29e Merge branch 'master' into harmony-2.8.0 2017-02-27 04:37:48 +08:00
Anthony Van de Gejuchte
07734b000a Destructuring consistency fixes (#1417)
- Use AST_Destructuring for lhf assignment patterns
- Use AST_DefaultAssign for default assignments
- Add more checks for lhs expressions
- Add lots of testing
- Cleanup ast (e.g. remove default property)
- Fix #1402 based on a patch from @kzc
- Refine spread allowance in array destructring pattern
- Add destructuring AST tree checker
2017-02-24 08:49:19 +08:00
Anthony Van de Gejuchte
85c1cba760 Remove duplicated code (#1456)
[ES6] Remove duplicated code
2017-02-24 08:48:13 +08:00
Richard van Velzen
4bd31607f6 Merge branch 'master' into harmony 2017-01-26 13:02:22 +01:00
Anthony Van de Gejuchte
4728bc73ad Allow parsing regexp after arrow token (#1439) 2017-01-26 12:06:46 +01:00
Anthony Van de Gejuchte
52ce9a333c Fix compression with unused containing destructuring 2017-01-19 21:04:28 +01:00
kzc
abbeb266b5 [ES6] output parens for yield when parented by AST_Dot or AST_Sub (#1419) 2017-01-19 17:15:59 +01:00
Anthony Van de Gejuchte
b11c5151bc Fix regression with non-ascii function identifiers
Regression since 110a1ac885
2017-01-19 16:47:37 +01:00
Richard van Velzen
962b1f3d40 Merge branch 'master' into harmony 2016-11-30 18:59:32 +01:00
Richard van Velzen
3ee46e91e8 Merge branch 'master' into harmony 2016-11-29 22:32:49 +01:00
Richard van Velzen
ee26e7f11b Merge branch 'master' into harmony 2016-11-29 20:50:27 +01:00
Anthony Van de Gejuchte
937f534392 Fix flag name in readme 2016-11-29 20:44:22 +01:00
Anthony Van de Gejuchte
1b2c02c944 Fix nlb property for template strings tokens starting with nlb
Also add .gitattributes to checkout lf eol style
2016-11-29 20:36:00 +01:00
Anthony Van de Gejuchte
0aa526e72c Do not allow arrow functions in the middle of an expression 2016-11-29 20:32:05 +01:00
Anthony Van de Gejuchte
c2112d5886 Fix case where a lonely var is used as computed property 2016-11-29 20:19:01 +01:00
Anthony Van de Gejuchte
5f6825f9ec Introduce is_block_scope to AST_Node to determine block scope.
Will return false if AST_Node is instance of AST_Scope for now.
2016-10-24 21:28:32 +02:00
Anthony Van de Gejuchte
7e80a979a7 Remove AST_ObjectComputedKeyVal 2016-10-23 22:12:30 +02:00
Richard van Velzen
b7bb706150 Merge branch 'master' into harmony 2016-10-23 22:11:27 +02:00
Anthony Van de Gejuchte
32c2cc33bb Improve binding patterns for arrow functions 2016-10-23 21:13:12 +02:00
Anthony Van de Gejuchte
947b8750e8 Make classes implicitly strict mode 2016-10-17 20:24:38 +02:00
kzc
88f6ff38d1 [ES6] fix template string escaping of \${...} 2016-10-01 11:32:36 +02:00
kzc
4198095a9c [ES6] fix parsing spread arguments that are expressions 2016-09-29 13:34:22 -04:00
Anthony Van de Gejuchte
13ed445607 Improve support for binding pattern
Including improvements for parameters, variable assignment and
catch parameter.
2016-09-05 17:48:48 +02:00
Richard van Velzen
1db50c3b16 Don't parenthesize arrow functions in parameter lists 2016-09-02 09:35:31 +02:00
Richard van Velzen
7f6b5d662b Merge branch 'master' into harmony 2016-08-30 15:16:23 +02:00
Anthony Van de Gejuchte
1c15d0db45 Fix quoting of properties
- Make AST_ConciseMethod child of AST_ObjectProperty.
- Fix some typos.
2016-08-26 15:06:24 +02:00
Richard van Velzen
67461666dc Merge branch 'master' into harmony 2016-08-17 21:30:35 +02:00
Richard van Velzen
45d81f881b Merge branch 'master' into harmony 2016-08-17 20:21:38 +02:00
Richard van Velzen
8c7d23dfb1 Merge branch 'master' into harmony 2016-08-17 08:50:31 +02:00
Richard van Velzen
7fa0dbdeb9 Ignore default reserved properties in compress test 2016-08-15 09:54:15 +02:00
Richard van Velzen
c644c1292d Merge branch 'master' into harmony 2016-08-15 09:09:04 +02:00
kzc
d224d71b8d [ES6] Fix handling of semicolons in export parse. 2016-08-14 21:43:24 +02:00
Anthony Van de Gejuchte
27d3669800 Don't allow escaped surrogated identifiers + introduce ascii_identifiers
Don't use 2 characters for surrogates in identifiers because there is
support for the \u{} syntax when escaped identifiers were introduced.

Also catch eof errors while reading identifier names

Introduce ascii_identifiers:

By setting ascii_identifiers to undefined (default value),
ascii_identifiers will print identifiers using the same setting as
ascii_only within the limits of the ecmascript 6 grammar.

ascii_identifiers accept true and false, allowing identifiers to be
printed under different settings than strings with the ascii_only setting.
2016-08-14 21:36:06 +02:00
Anthony Van de Gejuchte
110a1ac885 Make distinction between * method and * operator
Also add quotes to properties when necessary,
this might be the case if the name isn't a valid
identifier
2016-07-29 21:31:08 +02:00
Anthony Van de Gejuchte
3f8fc3a316 Fix computed getters + cleanup AST 2016-07-21 18:21:46 +02:00
Anthony Van de Gejuchte
88384cf351 Add more globals, whereof most defined after es5.1
Also do not pollute env with mocks replacing standard globals
2016-07-21 16:52:04 +02:00
Anthony Van de Gejuchte
72a9d799b6 Various property fixes
* Implement getter/setter with computed value
* Fix parsing getter/setter after static or generator token
* Allow storing expressions for computed expression in AST_SymbolMethod
* Allow get and set in shorthand properties in object literals

Fixes #1094, #1146 and #1221
2016-07-21 16:50:32 +02:00
Anthony Van de Gejuchte
766fafda8b Don't remove empty generators passed as parameter 2016-07-19 18:13:07 +02:00
kzc
842ac27efb [ES6] Get compress and global_defs working for AST_Class 2016-07-17 19:56:02 +02:00
Anthony Van de Gejuchte
0af42d1831 Template fixes
* Fixes #1147: template strings not obeying -b ascii_only true
* Allow evaluation of template expressions by adding optimizers and
  walkers
* Make sure tagged templates are never changed
* Remove template tokenizer in parser, add template tokenizer in
  tokenizer. It is using a brace counter to track brace position of
  templates
* Add tokens `template_head` and `template_substitution` but parsing
  tokens stays mostly the same
* Do not output strings anymore in AST_TemplateString, instead use
  AST_TemplateSegment
* Fix parsing tagged templates, allowing multiple templates behind
  as spec allows this

These changes don't influence tagged templates because raw content
may influence code execution, however they are safe to do in normal
templates:
* Allow basic string concatenation of templates where possible
* Allow custom character escape style similar to strings, except in
  tagged templates

Note that expressions are still compressed in tagged templates.

Optional things that may be improved later:
* Custom quote style for templates if it doesn't have expressions.
  Making it obey the quote_style option if this is the case.
2016-07-17 00:36:42 +02:00
Anthony Van de Gejuchte
ff7f6139ba Improve multi-line comment parsing
* Make sure comments are skipped correctly with surrogates
* Fix regression in multiline comments with nlb
2016-07-12 00:08:35 +02:00
Richard van Velzen
0db7caf13b Merge branch 'master' into harmony 2016-07-03 21:39:00 +02:00
Anthony Van de Gejuchte
d9bc6f303c Fix output arrow function with 1 param with default value
Fixes #1090
2016-07-03 21:37:53 +02:00
Anthony Van de Gejuchte
6fd9b338dd Merge branch 'master' into harmony 2016-07-03 21:35:00 +02:00
Anthony Van de Gejuchte
d8d4e71b9e Fix uses_with/uses_eval/directives state in block scope 2016-07-01 15:43:17 +02:00
Anthony Van de Gejuchte
fb2f8d1a51 Add reserved words to list unescapable keywords
Additionals:
* Update list reserved keywords
2016-06-30 22:47:44 +02:00
Anthony Van de Gejuchte
54a783ba84 Add ecma5 flag for codegen 2016-06-30 22:47:44 +02:00
Anthony Van de Gejuchte
63c432f4fa Extend unicode support
* Support \u{xxxx} syntax
 * Add support for surrogate pairs
 * Allow identifiers to have unicode escape sequence
2016-06-30 22:47:44 +02:00
Anthony Van de Gejuchte
07785d0003 Throw error if new.target is like new.foo 2016-06-25 19:32:53 +02:00
Anthony Van de Gejuchte
6eaeb19a4a Add exponentiation operator 2016-06-22 12:23:37 +02:00
Anthony Van de Gejuchte
2246c79318 Merge branch 'master' into fix-harmony 2016-06-20 19:21:25 +02:00
Anthony Van de Gejuchte
dda58244b6 Fixes to prevent failing tests after merging master
* Add missing quote properties to AST_ObjectKeyVal
 * Avoid test results being interpret as directives
2016-06-20 15:02:09 +02:00
Anthony Van de Gejuchte
ca04508cd1 Restrict yield outside generators in strict mode
* Move some yield/generic tests from compress/harmony.js to
  compress/yield.js
 * Adjust error messages to conform ecmascript standards
2016-06-19 21:03:36 +02:00
Anthony Van de Gejuchte
6b03b800b3 Only last parameter between parentheses can have spread 2016-06-19 20:51:29 +02:00
Anthony Van de Gejuchte
f9cab7ad61 Allow expand in array literals 2016-06-19 20:49:18 +02:00
Richard van Velzen
0a3d780327 Merge branch 'master' into harmony 2016-06-12 17:29:42 +02:00
Anthony Van de Gejuchte
b0555a123a Fix newline handling after yield
YieldExpressions can only be defined as:
 * `yield`
 * `yield` [no nlb] AssignmentExpression
 * `yield` [no nlb] `*` AssignmentExpression
2016-06-11 21:41:16 +02:00
Richard van Velzen
fa29344781 Merge branch 'master' into harmony 2016-06-09 22:29:52 +02:00
Anthony Van de Gejuchte
dcfc514c38 Improve yield support and restrict usage of strict
- Partially reverting 91cdb93e57 and eaf3911c31 and reimplement
- Add generators support for objects and classes
- Only classes can have static methods so restrict use of it

Special thanks to @rvanvelzen and @kzc for reviewing this patch and
providing constructive feedback over and over again.
2016-06-09 22:22:15 +02:00
Anthony Van de Gejuchte
8ad8d7b717 Add Symbol to builtins 2016-05-24 17:57:18 +02:00
Richard van Velzen
0357e5923f Merge branch 'master' into harmony 2016-05-24 17:56:20 +02:00
Richard van Velzen
f63803e3e3 Merge branch 'master' into harmony 2016-05-16 09:53:13 +02:00
Richard van Velzen
63be1f3a4d Only allow var definitions to be moved into the for-init clause
Fixes #1079
2016-05-15 21:00:51 +02:00
Richard van Velzen
e36e07fa77 Merge branch 'master' into harmony 2016-05-04 20:13:35 +02:00
Richard van Velzen
d1b4f61f93 Merge pull request #1059 from not-an-aardvark/harmony
Avoid syntax error in yield assignments
2016-04-26 11:51:13 +02:00
not-an-aardvark
5b893c8ec3 Avoid syntax error in yield assignments (fixes #1054) 2016-04-25 19:14:44 -04:00
Richard van Velzen
8571a08a93 Do not attempt evaluating class expressions
Broadly the same as function expressions - these actually are statements but
we're limited by the inheritance tree.

Fixes #1044
2016-04-19 20:01:26 +02:00
Richard van Velzen
68cc14f846 Fixups after merge 2016-04-18 15:51:32 +02:00
Richard van Velzen
f94497d1d6 Merge branch 'master' into harmony 2016-04-18 15:50:35 +02:00
Richard van Velzen
eaf3911c31 Consider yield expressions as having side-effects
See #1043
2016-04-13 14:39:49 +02:00
Darío Javier Cravero
91cdb93e57 Implement harmony generators and yield
Uses #716's implementation and adds tests.

Fixes #716.
2016-04-13 14:22:08 +02:00
Fábio Santos
634f231b78 First class block scope
- Make let, const, and class symbols be declared in a block scope.
- Piggy back on existing catch symbol implementation to get block-aware mangling working
- Make sure unused block-scoped declarations can be dropped
- Don't eliminate a block if it has a block-scoped declaration
- Remove silly empty anonymous blocks left over from drop_unused
- AST_Toplevel now gets to call drop_unused too, since block-scoped variables aren't global!
- Don't consider block declarations global
2016-03-27 19:40:20 +02:00
Fábio Santos
6702cae918 fix #1021 2016-03-27 12:21:39 +01:00
Fábio Santos
6d2f77c180 fix #1003 by removing AST_ObjectSymbol and using AST_ObjectKeyVal for the same effect 2016-03-14 13:42:50 +01:00
Fábio Santos
accca2445f fix crash: Import statements don't abort 2016-03-14 12:54:05 +01:00
Fábio Santos
0bc4f6edb4 Don't mangle exported symbols 2016-03-14 12:54:05 +01:00
Fábio Santos
ce84a706a3 Implement the export statement 2016-03-14 12:54:05 +01:00
Fábio Santos
86b5248837 Mangling externally imported names by using aliasing 2016-03-14 12:54:05 +01:00
Fábio Santos
59e1601fb8 importing names in the modules, not just default imports 2016-03-14 12:54:05 +01:00
Fábio Santos
d35a9e7839 Importing names from places 2016-03-14 12:54:05 +01:00
Fábio Santos
0465bd270d Starting out the import statement 2016-03-14 12:54:05 +01:00
viclm
6780d0906c Fix eager parsing of arrow functions for non-punc tokens 2016-03-10 22:18:48 +01:00
Darío Javier Cravero
0b303379c0 fix: don't fail if definition is undefined
Running `uglifyjs --verbose --compress --mangle --screw-ie8 class.js`
with
`class.js`:
```
class Foo {
  bar() {
  }
}
```
Fails with:
```
undefined:4041
  return this.definition().unmangleable(options);
TypeError: Cannot read property 'unmangleable' of undefined
...
```
2016-02-10 10:17:32 +01:00
Fábio Santos
d7ec2ecc12 Fix #931: Create arrow functions in maybe_assign so that they can be used in assignments 2016-02-09 00:02:23 +00:00
Richard van Velzen
2827fa8699 Merge branch 'harmony' of github.com:mishoo/UglifyJS2 into harmony 2016-01-19 19:22:35 +01:00
Richard van Velzen
c80ec625ec Add test for bad template string parsing 2016-01-19 19:22:22 +01:00
Fugiman
5e78f20f1c Remove duplicate error message 2016-01-19 19:22:22 +01:00
Fugiman
1f75232062 Fix template string parsing 2016-01-19 19:22:22 +01:00
Fábio Santos
028ff64e9a Default values inside destructurings 2016-01-19 19:22:22 +01:00
Fábio Santos
7a8cffd631 Move the idea of a symbol having a default value up the class chain. 2016-01-19 19:22:22 +01:00
Fábio Santos
5b553aafe2 Destructuring parameters with defaults. function x({ foo, bar } = {}) { } 2016-01-19 19:22:22 +01:00
Fábio Santos
084437bc6d Non-destructuring default parameters 2016-01-19 19:22:22 +01:00
Richard van Velzen
1cd9a2df9a Merge pull request #872 from fabiosantoscode/feature/harmony-defaults
Feature/harmony defaults
2016-01-05 21:39:23 +01:00
Richard van Velzen
7f3dbb6df7 Merge branch 'master' into harmony 2015-12-26 17:59:38 +01:00
Richard van Velzen
e4d73d8b7c Merge pull request #870 from fabiosantoscode/feature/harmony-class
Harmony: classes
2015-12-07 18:59:07 +01:00
Fábio Santos
8220dbbea0 Default values inside destructurings 2015-11-22 19:04:42 +00:00
Fábio Santos
59e999597e Move the idea of a symbol having a default value up the class chain. 2015-11-22 19:00:54 +00:00
Fábio Santos
cbcb3ac44e Destructuring parameters with defaults. function x({ foo, bar } = {}) { } 2015-11-22 18:02:51 +00:00
Fábio Santos
f07ab4666f Non-destructuring default parameters 2015-11-22 17:40:05 +00:00
Fábio Santos
a800356ad0 Implement new.target 2015-11-21 14:48:23 +00:00
Fábio Santos
e076abdbf2 Mangle class names correctly 2015-11-21 13:59:18 +00:00
Fábio Santos
425613b0d2 mangle class names 2015-11-21 12:20:20 +00:00
Fábio Santos
69da8e53e0 Separate class expressions from class declarations and their symbols like defuns 2015-11-21 09:17:32 +00:00
Fábio Santos
bb6b3a773a Make AST_Class inherit AST_Scope instead of AST_Object
This is one of those days I'd love to use multiple inheritance.

An AST_Class has lots of common with AST_Object, but unfortunately
`instanceof AST_Scope` is used very, very much, and a class has its name
inside its own special pocket scope. This compels me to make AST_Class
inherit Scope instead.

It looks like, although there is much in common with AST_Object,
`instanceof AST_Object` seldom are made, perhaps because it is less
often necessary to traverse an object than a scope.
2015-11-20 19:34:10 +00:00
Fábio Santos
364d20f8fb Add mangle = { ...mangleopts } option to tests. 2015-11-20 18:11:17 +00:00
Richard van Velzen
392ac4ff31 Merge branch 'master' into harmony 2015-10-28 20:38:07 +01:00
Fábio Santos
9ffed2bea6 static properties 2015-10-27 12:24:37 +00:00
Fábio Santos
5f7cb6939c Starting ES6 classes 2015-10-27 12:24:37 +00:00
Fábio Santos
64e7a00399 Accept keyword names as concise method names 2015-10-27 09:31:16 +01:00
Fábio Santos
c99eaae360 Make concise methods work with propmangle 2015-10-27 09:31:16 +01:00
Fábio Santos
34213ea2f8 Create a new symbol for methods' names 2015-10-27 09:31:16 +01:00
Fábio Santos
da8c428a07 Just making sure that concise methods are separated by commas. When classes come, they won't be necessary. 2015-10-27 09:31:16 +01:00
Fábio Santos
0d8dea9538 start concise methods 2015-10-27 09:31:16 +01:00
Richard van Velzen
2babe737e0 Merge pull request #844 from fabiosantoscode/harmony-allow-of
Harmony: allow use of `of` as a name.
2015-10-27 09:26:51 +01:00
Fábio Santos
2cce61c564 Allow 'of' to be a name. 2015-10-26 20:56:59 +00:00
Richard van Velzen
246ec416c0 Merge branch 'master' into harmony 2015-10-20 21:58:58 +02:00
Richard van Velzen
6be9c752d5 Merge branch 'master' into harmony 2015-10-20 20:12:10 +02:00
Fábio Santos
76ed083e47 Using single quotes 2015-10-12 21:39:19 +01:00
Fábio Santos
b31918bbf0 computed properties 2015-10-12 21:38:20 +01:00
Richard van Velzen
b14496c742 Merge branch 'master' into harmony
Conflicts:
	lib/compress.js
2015-10-12 08:54:44 +02:00
Richard van Velzen
991fa99655 Merge branch 'master' into harmony 2015-09-13 14:17:45 +02:00
Fábio Santos
3d7f73114d Add a test to make sure future generations don't hoist lets 2015-09-13 14:15:53 +02:00
Fábio Santos
dde9e293df parse, output the let statement 2015-09-13 14:15:53 +02:00
Richard van Velzen
34685a6f55 Merge pull request #794 from fabiosantoscode/feature/harmony-template-strings-2
Harmony: template strings
2015-09-08 21:23:41 +02:00
Richard van Velzen
9812c826e0 Merge pull request #795 from fabiosantoscode/harmony-fix-cannot-destructure-crash
Fix crash, remove unused code and state variable.
2015-09-06 17:05:34 +02:00
Fábio Santos
2fac2bbfe4 Remove unused state variable in_parameters, and also remove unreachable code (try_an_object always returned an object!) 2015-09-05 23:01:29 +01:00
Fábio Santos
242c61be94 prefixed template strings, like "String.rawfoo\nbar". 2015-09-05 22:48:38 +01:00
Fábio Santos
e1cb1a0e3c Parse and output ES6 template strings. Yikes! 2015-09-05 22:32:57 +01:00
Richard van Velzen
af22b9c657 Merge pull request #768 from fabiosantoscode/feature/harmony-destructuring-expression
Feature/harmony destructuring expression
2015-08-25 19:00:36 +02:00
Fábio Santos
adee5023c0 What about --mangle-props being on and --mangle being off? 2015-08-25 17:52:51 +01:00
Fábio Santos
7ee8f3512e play nice with propmangle 2015-08-25 17:49:29 +01:00
Fábio Santos
dc5db9b6ca Starting destructuring expressions 2015-08-25 17:49:27 +01:00
Fábio Santos
079aaa0d48 Tolerate expansions in vardefs, too! 2015-08-21 12:04:26 +02:00
Fábio Santos
d4f17f29ae Destructuring vardef in for..of and for..in 2015-08-21 12:04:26 +02:00
Fábio Santos
e99bc914ca Do not mangle a name if it is in a destructuring vardef. 2015-08-21 12:04:26 +02:00
Fábio Santos
025d34bfa2 Add holes in destructuring defs, also make them nestable 2015-08-21 12:04:26 +02:00
Fábio Santos
c44c2d6c21 Parse and compress destructuring VarDefs 2015-08-21 12:04:26 +02:00
Fábio Santos
824ecfb8a2 A little refactoring. Add a new function to get all symbols in a destructuring. 2015-08-21 12:04:26 +02:00
Fábio Santos
ceebc466b9 prepare AST_Destructuring for the Ents 2015-08-21 12:04:26 +02:00
Richard van Velzen
35b31bdd4e Merge branch 'master' into harmony 2015-08-21 11:58:35 +02:00
Richard van Velzen
c8b82583d2 Merge pull request #773 from fabiosantoscode/harmony-typeof-arrows
Fix evaluating the typeof an arrow function.
2015-08-21 11:51:42 +02:00
Richard van Velzen
9f9179ba1a Merge pull request #774 from fabiosantoscode/feature/harmony-symbol
remove Symbol's argument when we're unsafe and Symbol is undeclared
2015-08-21 11:51:02 +02:00
Richard van Velzen
872231a0ca Merge pull request #775 from fabiosantoscode/feature/binary-literals
Parse ES6 number literals, round 2
2015-08-21 11:50:39 +02:00
Fábio Santos
36420183fd s/binary/number/g 2015-08-17 16:23:43 +01:00
Fábio Santos
a8f8aa518b Add new-style octal literals and make the B and the O case insensitive. 2015-08-17 11:50:56 +01:00
Fábio Santos
4c12cccff9 remove Symbol's argument when we're unsafe and it's undeclared 2015-08-14 22:44:16 +01:00
Fábio Santos
dcce4e5c66 Fix evaluating the typeof an arrow function. Using evaluate on used to cause a crash. 2015-08-14 22:05:42 +01:00
Richard van Velzen
56c0b834d6 Merge pull request #771 from fabiosantoscode/feature/binary-literals
Parse binary number literals
2015-08-14 14:59:55 +02:00
Fábio Santos
6f864402d3 Parse binary number literals 2015-08-14 03:24:54 +01:00
Richard van Velzen
8909e9e1cb Merge pull request #763 from fabiosantoscode/feature/harmony-super
Feature/harmony super
2015-08-07 08:54:20 +02:00
Fábio Santos
e80ed38772 Super! 2015-08-07 02:44:53 +01:00
Fábio Santos
9863f0efa3 expand parameters
Conflicts:
	test/compress/harmony.js
2015-08-05 21:15:23 +02:00
Richard van Velzen
e8664e63ef Merge branch 'master' into harmony 2015-08-05 21:13:11 +02:00
Fábio Santos
ddd30eeaaa Uglifyjs already supports super as an implicit global! Just adding a test to indicate that. 2015-08-05 11:49:37 +01:00
Fábio Santos
a68953c491 => with destructuring arguments. Requires a lot of parser changes 2015-08-04 00:57:53 +01:00
Fábio Santos
fa5c4f2d03 Adding arrow functions 2015-08-04 00:57:53 +01:00
Fábio Santos
9d7d365c2b for...of 2015-07-29 15:10:54 +02:00
Fábio Santos
ad344c5be3 Add a test to verify that destructuring arguments work with #203 code 2015-07-29 14:54:45 +02:00
Fábio Santos
96b89e34a3 test that names used in destructurings don't get hoisted 2015-07-29 14:54:45 +02:00
Fábio Santos
4644becb9b do not support destructuring arguments and ngInject 2015-07-29 14:54:45 +02:00
Fábio Santos
f7460166dd remove trace statement 2015-07-29 14:54:45 +02:00
Fábio Santos
32f76f7ff8 Starting destructuring. 2015-07-29 14:54:45 +02:00
298 changed files with 20775 additions and 116088 deletions

20
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,20 @@
**Bug report or feature request?**
<!-- Note: sub-optimal but correct code is not a bug -->
**ES5 or ES6+ input?**
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
**Uglify version (`uglifyjs -V`)**
**JavaScript input** <!-- ideally as small as possible -->
**The `uglifyjs` CLI command executed or `minify()` options used.**
**JavaScript output or error produced.**
<!--
Note: `uglify-js` only supports ES5.
Those wishing to minify ES6 should use `uglify-es`.
-->

View File

@@ -1,51 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
<!-- Note: sub-optimal but correct code is not a bug -->
**Uglify version (`uglifyjs -V`)**
**JavaScript input**
<!--
A complete parsable JS program exhibiting the issue with UglifyJS alone
- without third party tools or libraries.
Ideally the input should be as small as possible, but may be large if isolating
the problem proves to be difficult. The most important thing is that the
standalone program reliably exhibits the bug when minified. Provide a link to a
gist if necessary.
Solely providing minified output without the original uglify JS input is not
useful in determining the cause of the problem. Issues without a reproducible
test case will be closed.
-->
**The `uglifyjs` CLI command executed or `minify()` options used.**
<!--
Command-line or API call to UglifyJS without third party tools or libraries.
For users using bundlers or transpilers, you may be able to gather the required
information through setting the `UGLIFY_BUG_REPORT` environment variable:
export UGLIFY_BUG_REPORT=1 (bash)
set UGLIFY_BUG_REPORT=1 (Command Prompt)
$Env:UGLIFY_BUG_REPORT=1 (PowerShell)
before running your usual build process. The resulting "minified" output should
contain the necessary details for this report.
-->
**JavaScript output or error produced.**
<!--
Only minified code that produces different output (or error) from the original
upon execution would be considered a bug.
-->

View File

@@ -1,58 +0,0 @@
name: Build testing
on:
pull_request:
push:
branches: [ master ]
jobs:
ufuzz:
strategy:
fail-fast: false
matrix:
options:
- '-mb braces'
- '--ie -c'
- '-mc'
- '-p acorn --toplevel -mco spidermonkey'
- '--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

View File

@@ -1,28 +0,0 @@
name: CI
on:
pull_request:
push:
branches: [ master ]
jobs:
test:
strategy:
matrix:
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', latest ]
os: [ ubuntu-latest, windows-latest ]
script: [ compress, mocha, release/benchmark, release/jetstream ]
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
runs-on: ${{ matrix.os }}
env:
NODE: ${{ matrix.node }}
TYPE: ${{ matrix.script }}
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: tmp
key: tmp ${{ matrix.script }}
- name: Perform tests
shell: bash
run: |
. ./test/release/install.sh
node test/$TYPE

View File

@@ -1,44 +0,0 @@
name: Fuzzing
on:
pull_request:
schedule:
- cron: '*/15 * * * *'
workflow_dispatch:
workflow_run:
branches: [ master ]
types: [ completed ]
workflows: [ 'Build testing', CI ]
env:
BASE_URL: https://api.github.com/repos/${{ github.repository }}
TOKEN: ${{ github.token }}
jobs:
ufuzz:
strategy:
fail-fast: false
matrix:
include:
- node: latest
os: macos-latest
- node: '8'
os: ubuntu-latest
- node: '8'
os: ubuntu-latest
- node: '8'
os: windows-latest
- node: '8'
os: windows-latest
name: ${{ matrix.node }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
env:
NODE: ${{ matrix.node }}
steps:
- uses: actions/checkout@v2
- name: Perform fuzzing
shell: bash
run: |
. ./test/release/install.sh
if [[ $GITHUB_EVENT_NAME == "pull_request" ]]; then
node test/ufuzz/job 5000
else
node test/ufuzz/job $BASE_URL $TOKEN $GITHUB_RUN_NUMBER
fi

11
.travis.yml Normal file
View File

@@ -0,0 +1,11 @@
language: node_js
node_js:
- "0.10"
- "0.12"
- "4"
- "6"
env:
- UGLIFYJS_TEST_ALL=1
matrix:
fast_finish: true
sudo: false

View File

@@ -1,61 +0,0 @@
Contributing
============
## Documentation
Every new feature and API change should be accompanied by a README additon.
## Testing
All features and bugs should have tests that verify the fix. You can run all
tests using `npm test`.
The most common type of test are tests that verify input and output of the
Uglify transforms. These tests exist in `test/compress`. New tests can be added
either to an existing file or in a new file `issue-xxx.js`.
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
## Code style
- File encoding must be `UTF-8`.
- `LF` is always used as a line ending.
- Statements end with semicolons.
- Indentation uses 4 spaces, switch `case` 2 spaces.
- Identifiers use `snake_case`.
- Strings use double quotes (`"`).
- Use a trailing comma for multiline array and object literals to minimize diffs.
- The Uglify code only uses ES5, even in the `harmony` branch.
- Line length should be at most 80 cols, except when it is easier to read a
longer line.
- If both sides of a comparison are of the same type, `==` and `!=` are used.
- Multiline conditions place `&&` and `||` first on the line.
**Example feature**
```js
OPT(AST_Debugger, function(self, compressor) {
if (compressor.option("drop_debugger"))
return make_node(AST_EmptyStatement, self);
return self;
});
```
**Example test case**
```js
drop_debugger: {
options = {
drop_debugger: true,
}
input: {
debugger;
if (foo) debugger;
}
expect: {
if (foo);
}
}
```

View File

@@ -1,6 +1,6 @@
UglifyJS is released under the BSD license:
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

1016
README.md

File diff suppressed because it is too large Load Diff

24
appveyor.yml Normal file
View File

@@ -0,0 +1,24 @@
environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.12"
- nodejs_version: "4.0"
- nodejs_version: "6.0"
matrix:
fast_finish: true
platform:
- x86
- x64
install:
- ps: Install-Product node $env:nodejs_version $env:platform
- npm install
test_script:
- node --version
- npm --version
- npm test
build: off

View File

@@ -3,307 +3,161 @@
"use strict";
require("../tools/tty");
// workaround for tty output truncation upon process.exit()
[process.stdout, process.stderr].forEach(function(stream){
if (stream._handle && stream._handle.setBlocking)
stream._handle.setBlocking(true);
});
var fs = require("fs");
var info = require("../package.json");
var path = require("path");
var program = require("commander");
var UglifyJS = require("../tools/node");
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
var files = {};
var options = {};
var short_forms = {
b: "beautify",
c: "compress",
d: "define",
e: "enclose",
h: "help",
m: "mangle",
o: "output",
O: "output-opts",
p: "parse",
v: "version",
V: "version",
var options = {
compress: false,
mangle: false
};
var args = process.argv.slice(2);
var paths = [];
var output, nameCache;
var specified = {};
while (args.length) {
var arg = args.shift();
if (arg[0] != "-") {
paths.push(arg);
} else if (arg == "--") {
paths = paths.concat(args);
break;
} else if (arg[1] == "-") {
process_option(arg.slice(2));
} else [].forEach.call(arg.slice(1), function(letter, index, arg) {
if (!(letter in short_forms)) fatal("invalid option -" + letter);
process_option(short_forms[letter], index + 1 < arg.length);
});
program.version(info.name + ' ' + info.version);
program.parseArgv = program.parse;
program.parse = undefined;
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
program.option("-o, --output <file>", "Output file (default STDOUT).");
program.option("--comments [filter]", "Preserve copyright comments in the output.");
program.option("--config-file <file>", "Read minify() options from JSON file.");
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
program.option("--ie8", "Support non-standard Internet Explorer 8.");
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
program.option("--name-cache <file>", "File to hold mangled name mappings.");
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
program.option("--stats", "Display operations run time on STDERR.")
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
program.option("--verbose", "Print diagnostic messages.");
program.option("--warn", "Print warning messages.");
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
program.arguments("[files...]").parseArgv(process.argv);
if (program.configFile) {
options = JSON.parse(read_file(program.configFile));
}
function process_option(name, no_value) {
specified[name] = true;
switch (name) {
case "help":
switch (read_value()) {
case "ast":
print(UglifyJS.describe_ast());
break;
case "options":
var text = [];
var toplevels = [];
var padding = "";
var defaults = UglifyJS.default_options();
for (var name in defaults) {
var option = defaults[name];
if (option && typeof option == "object") {
text.push("--" + ({
output: "beautify",
sourceMap: "source-map",
}[name] || name) + " options:");
text.push(format_object(option));
text.push("");
} else {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
toplevels.push([ {
keep_fargs: "keep-fargs",
keep_fnames: "keep-fnames",
nameCache: "name-cache",
}[name] || name, option ]);
}
}
toplevels.forEach(function(tokens) {
text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
});
print(text.join("\n"));
break;
default:
print([
"Usage: uglifyjs [files...] [options]",
"",
"Options:",
" -h, --help Print usage information.",
" `--help options` for details on available options.",
" -v, -V, --version Print version number.",
" -p, --parse <options> Specify parser options.",
" -c, --compress [options] Enable compressor/specify compressor options.",
" -m, --mangle [options] Mangle names/specify mangler options.",
" --mangle-props [options] Mangle properties/specify mangler options.",
" -b, --beautify [options] Beautify output/specify output options.",
" -O, --output-opts <options> Output options (beautify disabled).",
" -o, --output <file> Output file (default STDOUT).",
" --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.",
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
" --ie Support non-standard Internet Explorer.",
" --keep-fargs Do not mangle/drop function arguments.",
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
" --name-cache <file> File to hold mangled name mappings.",
" --rename Force symbol expansion.",
" --no-rename Disable symbol expansion.",
" --self Build UglifyJS as a library (implies --wrap UglifyJS)",
" --source-map [options] Enable source map/specify source map options.",
" --timings Display operations run time on STDERR.",
" --toplevel Compress and/or mangle variables in toplevel scope.",
" --v8 Support non-standard Chrome & Node.js.",
" --validate Perform validation during AST manipulations.",
" --verbose Print diagnostic messages.",
" --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"));
}
process.exit();
case "version":
print(info.name + " " + info.version);
process.exit();
case "config-file":
var config = JSON.parse(read_file(read_value(true)));
if (config.mangle && config.mangle.properties && config.mangle.properties.regex) {
config.mangle.properties.regex = UglifyJS.parse(config.mangle.properties.regex, {
expression: true,
}).value;
}
for (var key in config) if (!(key in options)) options[key] = config[key];
break;
case "compress":
case "mangle":
options[name] = parse_js(read_value(), options[name]);
break;
case "source-map":
options.sourceMap = parse_js(read_value(), options.sourceMap);
break;
case "enclose":
options[name] = read_value();
break;
case "annotations":
case "ie":
case "ie8":
case "timings":
case "toplevel":
case "v8":
case "validate":
case "webkit":
options[name] = true;
break;
case "no-annotations":
options.annotations = false;
break;
case "keep-fargs":
options.keep_fargs = true;
break;
case "keep-fnames":
options.keep_fnames = true;
break;
case "wrap":
options[name] = read_value(true);
break;
case "verbose":
options.warnings = "verbose";
break;
case "warn":
if (!options.warnings) options.warnings = true;
break;
case "beautify":
options.output = parse_js(read_value(), options.output);
if (!("beautify" in options.output)) options.output.beautify = true;
break;
case "output-opts":
options.output = parse_js(read_value(true), options.output);
break;
case "comments":
if (typeof options.output != "object") options.output = {};
options.output.comments = read_value();
if (options.output.comments === true) options.output.comments = "some";
break;
case "define":
if (typeof options.compress != "object") options.compress = {};
options.compress.global_defs = parse_js(read_value(true), options.compress.global_defs, "define");
break;
case "mangle-props":
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
break;
case "name-cache":
nameCache = read_value(true);
options.nameCache = JSON.parse(read_file(nameCache, "{}"));
break;
case "output":
output = read_value(true);
break;
case "parse":
options.parse = parse_js(read_value(true), options.parse);
break;
case "rename":
options.rename = true;
break;
case "no-rename":
options.rename = false;
break;
case "in-situ":
case "reduce-test":
case "self":
break;
default:
fatal("invalid option --" + name);
}
function read_value(required) {
if (no_value || !args.length || args[0][0] == "-") {
if (required) fatal("missing option argument for --" + name);
return true;
}
return args.shift();
}
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
fatal("ERROR: cannot write source map to STDOUT");
}
if (!output && options.sourceMap && options.sourceMap.url != "inline") fatal("cannot write source map to STDOUT");
if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot be used with --output-opts");
[ "compress", "mangle" ].forEach(function(name) {
if (!(name in options)) options[name] = false;
[
"compress",
"ie8",
"mangle",
"sourceMap",
"toplevel",
"wrap"
].forEach(function(name) {
if (name in program) {
options[name] = program[name];
}
});
if (options.mangle && options.mangle.properties) {
if (options.mangle.properties.domprops) {
delete options.mangle.properties.domprops;
if (program.beautify) {
options.output = typeof program.beautify == "object" ? program.beautify : {};
if (!("beautify" in options.output)) {
options.output.beautify = true;
}
}
if (program.comments) {
if (typeof options.output != "object") options.output = {};
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
}
if (program.define) {
if (typeof options.compress != "object") options.compress = {};
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
for (var expr in program.define) {
options.compress.global_defs[expr] = program.define[expr];
}
}
if (program.keepFnames) {
options.keep_fnames = true;
}
if (program.mangleProps) {
if (program.mangleProps.domprops) {
delete program.mangleProps.domprops;
} else {
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
if (typeof program.mangleProps != "object") program.mangleProps = {};
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
require("../tools/domprops").forEach(function(name) {
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
UglifyJS._push_uniq(program.mangleProps.reserved, name);
});
}
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.properties = program.mangleProps;
}
if (/^ast|spidermonkey$/.test(output)) {
if (typeof options.output != "object") options.output = {};
options.output.ast = true;
options.output.code = false;
var cache;
if (program.nameCache) {
cache = JSON.parse(read_file(program.nameCache, "{}"));
if (options.mangle) {
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.cache = to_cache("vars");
if (options.mangle.properties) {
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
options.mangle.properties.cache = to_cache("props");
}
}
}
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
&& options.sourceMap && options.sourceMap.content == "inline") {
fatal("inline source map only works with built-in parser");
if (program.output == "ast") {
options.output = {
ast: true,
code: false
};
}
if (options.warnings) {
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
delete options.warnings;
if (program.parse) {
if (program.parse.acorn || program.parse.spidermonkey) {
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
} else {
options.parse = program.parse;
}
}
var convert_path = function(name) {
return name;
};
if (typeof options.sourceMap == "object" && "base" in options.sourceMap) {
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
convert_path = function() {
var base = options.sourceMap.base;
var base = program.sourceMap.base;
delete options.sourceMap.base;
return function(name) {
return path.relative(base, name);
};
}();
}
if (specified["self"]) {
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
if (!options.wrap) options.wrap = "UglifyJS";
paths = UglifyJS.FILES;
if (program.verbose) {
options.warnings = "verbose";
} else if (program.warn) {
options.warnings = true;
}
if (specified["in-situ"]) {
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
fatal("incompatible options specified");
if (program.self) {
if (program.args.length) {
console.error("WARN: Ignoring input files since --self was passed");
}
paths.forEach(function(name) {
print(name);
if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified");
files = {};
if (!options.wrap) options.wrap = "UglifyJS";
simple_glob(UglifyJS.FILES).forEach(function(name) {
files[convert_path(name)] = read_file(name);
output = name;
run();
});
} else if (paths.length) {
simple_glob(paths).forEach(function(name) {
run();
} else if (program.args.length) {
simple_glob(program.args).forEach(function(name) {
files[convert_path(name)] = read_file(name);
});
run();
} else {
var timerId = process.stdin.isTTY && process.argv.length < 3 && setTimeout(function() {
print_error("Waiting for input... (use `--help` to print usage information)");
}, 1500);
var chunks = [];
process.stdin.setEncoding("utf8");
process.stdin.once("data", function() {
clearTimeout(timerId);
}).on("data", function(chunk) {
process.stdin.on("data", function(chunk) {
chunks.push(chunk);
}).on("end", function() {
files = { STDIN: chunks.join("") };
files = [ chunks.join("") ];
run();
});
process.stdin.resume();
@@ -314,54 +168,21 @@ function convert_ast(fn) {
}
function run() {
var content = options.sourceMap && options.sourceMap.content;
if (content && content != "inline") {
UglifyJS.AST_Node.info("Using input source map: {content}", {
content : content,
});
options.sourceMap.content = read_file(content, content);
}
UglifyJS.AST_Node.warn_function = function(msg) {
console.error("WARN:", msg);
};
if (program.stats) program.stats = Date.now();
try {
if (options.parse) {
if (options.parse.acorn) {
var annotations = Object.create(null);
if (program.parse) {
if (program.parse.acorn) {
files = convert_ast(function(toplevel, name) {
var content = files[name];
var list = annotations[name] = [];
var prev = -1;
return require("acorn").parse(content, {
allowHashBang: true,
ecmaVersion: "latest",
return require("acorn").parse(files[name], {
locations: true,
onComment: function(block, text, start, end) {
var match = /[@#]__PURE__/.exec(text);
if (!match) {
if (start != prev) return;
match = [ list[prev] ];
}
while (/\s/.test(content[end])) end++;
list[end] = match[0];
prev = end;
},
preserveParens: true,
program: toplevel,
sourceFile: name,
sourceType: "module",
sourceFile: name
});
});
files.walk(new UglifyJS.TreeWalker(function(node) {
if (!(node instanceof UglifyJS.AST_Call)) return;
var list = annotations[node.start.file];
var pure = list[node.start.pos];
if (!pure) {
var tokens = node.start.parens;
if (tokens) for (var i = 0; !pure && i < tokens.length; i++) {
pure = list[tokens[i].pos];
}
}
if (pure) node.pure = pure;
}));
} else if (options.parse.spidermonkey) {
} else if (program.parse.spidermonkey) {
files = convert_ast(function(toplevel, name) {
var obj = JSON.parse(files[name]);
if (!toplevel) return obj;
@@ -373,71 +194,35 @@ function run() {
} catch (ex) {
fatal(ex);
}
var result;
if (specified["reduce-test"]) {
// load on demand - assumes cloned repository
var reduce_test = require("../test/reduce");
if (Object.keys(files).length != 1) fatal("can only test on a single file");
result = reduce_test(files[Object.keys(files)[0]], options, {
log: print_error,
verbose: true,
});
} else {
result = UglifyJS.minify(files, options);
}
var result = UglifyJS.minify(files, options);
if (result.error) {
var ex = result.error;
if (ex.name == "SyntaxError") {
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
var file = files[ex.filename];
if (file) {
var col = ex.col;
var lines = file.split(/\r?\n/);
var line = lines[ex.line - 1];
if (!line && !col) {
line = lines[ex.line - 2];
col = line.length;
}
if (line) {
var limit = 70;
if (col > limit) {
line = line.slice(col - limit);
col = limit;
}
print_error(line.slice(0, 80));
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
}
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
var col = ex.col;
var lines = files[ex.filename].split(/\r?\n/);
var line = lines[ex.line - 1];
if (!line && !col) {
line = lines[ex.line - 2];
col = line.length;
}
} else if (ex.defs) {
print_error("Supported options:");
print_error(format_object(ex.defs));
if (line) {
if (col > 40) {
line = line.slice(col - 40);
col = 40;
}
console.error(line.slice(0, 80));
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
}
}
if (ex.defs) {
console.error("Supported options:");
console.error(ex.defs);
}
fatal(ex);
} else if (output == "ast") {
if (!options.compress && !options.mangle) {
var toplevel = result.ast;
if (!(toplevel instanceof UglifyJS.AST_Toplevel)) {
if (!(toplevel instanceof UglifyJS.AST_Statement)) toplevel = new UglifyJS.AST_SimpleStatement({
body: toplevel,
});
toplevel = new UglifyJS.AST_Toplevel({
body: [ toplevel ],
});
}
toplevel.figure_out_scope({});
}
print(JSON.stringify(result.ast, function(key, value) {
if (value) switch (key) {
case "enclosed":
return value.length ? value.map(symdef) : undefined;
case "functions":
case "globals":
case "variables":
return value.size() ? value.map(symdef) : undefined;
case "thedef":
return symdef(value);
}
if (skip_property(key, value)) return;
} else if (program.output == "ast") {
console.log(JSON.stringify(result.ast, function(key, value) {
if (skip_key(key)) return;
if (value instanceof UglifyJS.AST_Token) return;
if (value instanceof UglifyJS.Dictionary) return;
if (value instanceof UglifyJS.AST_Node) {
@@ -451,37 +236,34 @@ function run() {
}
return value;
}, 2));
} else if (output == "spidermonkey") {
print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2));
} else if (output) {
var code;
if (result.ast) {
var opts = {};
for (var name in options.output) {
if (!/^ast|code$/.test(name)) opts[name] = options.output[name];
} else if (program.output == "spidermonkey") {
console.log(JSON.stringify(UglifyJS.minify(result.code, {
compress: false,
mangle: false,
output: {
ast: true,
code: false
}
code = UglifyJS.AST_Node.from_mozilla_ast(result.ast.to_mozilla_ast()).print_to_string(opts);
} else {
code = result.code;
}).ast.to_mozilla_ast(), null, 2));
} else if (program.output) {
fs.writeFileSync(program.output, result.code);
if (result.map) {
fs.writeFileSync(program.output + ".map", result.map);
}
fs.writeFileSync(output, code);
if (result.map) fs.writeFileSync(output + ".map", result.map);
} else {
print(result.code);
console.log(result.code);
}
if (nameCache) fs.writeFileSync(nameCache, JSON.stringify(options.nameCache));
if (result.timings) for (var phase in result.timings) {
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
if (program.nameCache) {
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
}));
}
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
}
function fatal(message) {
if (message instanceof Error) {
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
} else {
message = "ERROR: " + message;
}
print_error(message);
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
console.error(message);
process.exit(1);
}
@@ -505,7 +287,7 @@ function simple_glob(glob) {
.replace(/\?/g, "[^/\\\\]") + "$";
var mod = process.platform === "win32" ? "i" : "";
var rx = new RegExp(pattern, mod);
var results = entries.sort().filter(function(name) {
var results = entries.filter(function(name) {
return rx.test(name);
}).map(function(name) {
return path.join(dir, name);
@@ -525,77 +307,78 @@ function read_file(path, default_value) {
}
}
function parse_js(value, options, flag) {
if (!options || typeof options != "object") options = Object.create(null);
if (typeof value == "string") try {
UglifyJS.parse(value, {
expression: true
}).walk(new UglifyJS.TreeWalker(function(node) {
if (node instanceof UglifyJS.AST_Assign) {
var name = node.left.print_to_string();
var value = node.right;
if (flag) {
options[name] = value;
} else if (value instanceof UglifyJS.AST_Array) {
options[name] = value.elements.map(to_string);
} else {
options[name] = to_string(value);
function parse_js(flag, constants) {
return function(value, options) {
options = options || {};
try {
UglifyJS.minify(value, {
parse: {
expression: true
},
compress: false,
mangle: false,
output: {
ast: true,
code: false
}
return true;
}
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
var name = node.print_to_string();
options[name] = true;
return true;
}
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
if (node instanceof UglifyJS.AST_Assign) {
var name = node.left.print_to_string();
var value = node.right;
if (!constants) {
options[name] = value;
} else if (value instanceof UglifyJS.AST_Array) {
options[name] = value.elements.map(to_string);
} else {
options[name] = to_string(value);
}
return true;
}
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
var name = node.print_to_string();
options[name] = true;
return true;
}
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
function to_string(value) {
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
quote_keys: true
});
}
}));
} catch (ex) {
if (flag) {
fatal("cannot parse arguments for '" + flag + "': " + value);
} else {
options[value] = null;
function to_string(value) {
return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({
quote_keys: true
});
}
}));
} catch(ex) {
fatal("Error parsing arguments for '" + flag + "': " + value);
}
return options;
}
return options;
}
function skip_property(key, value) {
return skip_keys.indexOf(key) >= 0
// only skip truthy_keys if their value is falsy
|| truthy_keys.indexOf(key) >= 0 && !value;
function parse_source_map() {
var parse = parse_js("sourceMap", true);
return function(value, options) {
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
var settings = parse(value, options);
if (!hasContent && settings.content && settings.content != "inline") {
console.error("INFO: Using input source map:", settings.content);
settings.content = read_file(settings.content, settings.content);
}
return settings;
}
}
function symdef(def) {
var ret = (1e6 + def.id) + " " + def.name;
if (def.mangled_name) ret += " " + def.mangled_name;
return ret;
function to_cache(key) {
if (cache[key]) {
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
} else {
cache[key] = {
cname: -1,
props: new UglifyJS.Dictionary()
};
}
return cache[key];
}
function format_object(obj) {
var lines = [];
var padding = "";
Object.keys(obj).map(function(name) {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
return [ name, JSON.stringify(obj[name]) ];
}).forEach(function(tokens) {
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
});
return lines.join("\n");
}
function print_error(msg) {
process.stderr.write(msg);
process.stderr.write("\n");
}
function print(txt) {
process.stdout.write(txt);
process.stdout.write("\n");
function skip_key(key) {
return skip_keys.indexOf(key) >= 0;
}

2148
lib/ast.js

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,267 +1,149 @@
"use strict";
var to_ascii, to_base64;
if (typeof Buffer == "undefined") {
to_ascii = atob;
to_base64 = btoa;
} else if (typeof Buffer.alloc == "undefined") {
to_ascii = function(b64) {
return new Buffer(b64, "base64").toString();
};
to_base64 = function(str) {
return new Buffer(str).toString("base64");
};
} else {
to_ascii = function(b64) {
return Buffer.from(b64, "base64").toString();
};
to_base64 = function(str) {
return Buffer.from(str).toString("base64");
};
}
var to_ascii = typeof atob == "undefined" ? function(b64) {
return new Buffer(b64, "base64").toString();
} : atob;
var to_base64 = typeof btoa == "undefined" ? function(str) {
return new Buffer(str).toString("base64");
} : btoa;
function read_source_map(name, toplevel) {
var comments = toplevel.end.comments_after;
for (var i = comments.length; --i >= 0;) {
var comment = comments[i];
if (comment.type != "comment1") break;
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
if (!match) break;
if (match[1] == "sourceMappingURL") {
match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]);
if (!match) break;
return to_ascii(match[2]);
}
}
AST_Node.warn("inline source map not found: {name}", {
name: name,
});
}
function parse_source_map(content) {
try {
return JSON.parse(content);
} catch (ex) {
throw new Error("invalid input source map: " + content);
function read_source_map(code) {
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
if (!match) {
AST_Node.warn("inline source map not found");
return null;
}
return to_ascii(match[2]);
}
function set_shorthand(name, options, keys) {
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}
function init_cache(cache) {
if (!cache) return;
if (!("props" in cache)) {
cache.props = new Dictionary();
} else if (!(cache.props instanceof Dictionary)) {
cache.props = Dictionary.fromObject(cache.props);
if (options[name]) {
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}
}
function to_json(cache) {
return {
props: cache.props.toObject()
};
}
function minify(files, options) {
var warn_function = AST_Node.warn_function;
try {
if (typeof files == "string") {
files = [ files ];
}
options = defaults(options, {
annotations: undefined,
compress: {},
enclose: false,
ie: false,
ie8: false,
keep_fargs: false,
keep_fnames: false,
mangle: {},
nameCache: null,
output: {},
parse: {},
rename: undefined,
sourceMap: false,
timings: false,
toplevel: false,
v8: false,
validate: false,
warnings: false,
webkit: false,
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;
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
if (options.ie8) options.ie = options.ie || options.ie8;
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output" ]);
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle" ]);
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, [ "compress", "mangle", "output" ]);
var quoted_props;
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
set_shorthand("warnings", options, [ "compress" ]);
if (options.mangle) {
options.mangle = defaults(options.mangle, {
cache: options.nameCache && (options.nameCache.vars || {}),
cache: null,
eval: false,
ie: false,
keep_fargs: false,
ie8: false,
keep_classnames: false,
keep_fnames: false,
properties: false,
reserved: [],
safari10: false,
toplevel: false,
v8: false,
webkit: false,
}, true);
if (options.mangle.properties) {
if (typeof options.mangle.properties != "object") {
options.mangle.properties = {};
}
if (options.mangle.properties.keep_quoted) {
quoted_props = options.mangle.properties.reserved;
if (!Array.isArray(quoted_props)) quoted_props = [];
options.mangle.properties.reserved = quoted_props;
}
if (options.nameCache && !("cache" in options.mangle.properties)) {
options.mangle.properties.cache = options.nameCache.props || {};
}
}
init_cache(options.mangle.cache);
init_cache(options.mangle.properties.cache);
}
if (options.sourceMap) {
options.sourceMap = defaults(options.sourceMap, {
content: null,
filename: null,
includeSources: false,
names: true,
root: null,
url: null,
}, true);
}
var warnings = [];
if (options.warnings) AST_Node.log_function(function(warning) {
warnings.push(warning);
}, options.warnings == "verbose");
if (timings) timings.parse = Date.now();
if (options.warnings && !AST_Node.warn_function) {
AST_Node.warn_function = function(warning) {
warnings.push(warning);
};
}
var toplevel;
if (files instanceof AST_Toplevel) {
toplevel = files;
} else {
if (typeof files == "string") {
files = [ files ];
}
options.parse = options.parse || {};
options.parse.toplevel = null;
var source_map_content = options.sourceMap && options.sourceMap.content;
if (typeof source_map_content == "string" && source_map_content != "inline") {
source_map_content = parse_source_map(source_map_content);
}
if (source_map_content) options.sourceMap.orig = Object.create(null);
for (var name in files) if (HOP(files, name)) {
for (var name in files) {
options.parse.filename = name;
options.parse.toplevel = toplevel = parse(files[name], options.parse);
if (source_map_content == "inline") {
var inlined_content = read_source_map(name, toplevel);
if (inlined_content) {
options.sourceMap.orig[name] = parse_source_map(inlined_content);
}
} else if (source_map_content) {
options.sourceMap.orig[name] = source_map_content;
options.parse.toplevel = parse(files[name], options.parse);
if (options.sourceMap && options.sourceMap.content == "inline") {
if (Object.keys(files).length > 1)
throw new Error("inline source map only works with singular input");
options.sourceMap.content = read_source_map(files[name]);
}
}
toplevel = options.parse.toplevel;
}
if (quoted_props) {
reserve_quoted_keys(toplevel, quoted_props);
if (options.wrap) {
toplevel = toplevel.wrap_commonjs(options.wrap);
}
[ "enclose", "wrap" ].forEach(function(action) {
var option = options[action];
if (!option) return;
var orig = toplevel.print_to_string().slice(0, -1);
toplevel = toplevel[action](option);
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
});
if (options.validate) toplevel.validate_ast();
if (timings) timings.rename = Date.now();
if (options.rename) {
toplevel.figure_out_scope(options.mangle);
toplevel.expand_names(options.mangle);
}
if (timings) timings.compress = Date.now();
if (options.compress) {
toplevel.figure_out_scope(options.mangle);
toplevel = new Compressor(options.compress).compress(toplevel);
if (options.validate) toplevel.validate_ast();
}
if (timings) timings.scope = Date.now();
if (options.mangle) toplevel.figure_out_scope(options.mangle);
if (timings) timings.mangle = Date.now();
if (options.mangle) {
toplevel.figure_out_scope(options.mangle);
base54.reset();
toplevel.compute_char_frequency(options.mangle);
toplevel.mangle_names(options.mangle);
if (options.mangle.properties) {
toplevel = mangle_properties(toplevel, options.mangle.properties);
}
}
if (timings) timings.properties = Date.now();
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
if (timings) timings.output = Date.now();
var result = {};
var output = defaults(options.output, {
ast: false,
code: true,
});
if (output.ast) result.ast = toplevel;
if (output.code) {
if (options.output.ast) {
result.ast = toplevel;
}
if (!HOP(options.output, "code") || options.output.code) {
if (options.sourceMap) {
output.source_map = SourceMap(options.sourceMap);
if (typeof options.sourceMap.content == "string") {
options.sourceMap.content = JSON.parse(options.sourceMap.content);
}
options.output.source_map = SourceMap({
file: options.sourceMap.filename,
orig: options.sourceMap.content,
root: options.sourceMap.root
});
if (options.sourceMap.includeSources) {
if (files instanceof AST_Toplevel) {
throw new Error("original source content unavailable");
} else for (var name in files) if (HOP(files, name)) {
output.source_map.setSourceContent(name, files[name]);
for (var name in files) {
options.output.source_map.get().setSourceContent(name, files[name]);
}
}
}
delete output.ast;
delete output.code;
var stream = OutputStream(output);
delete options.output.ast;
delete options.output.code;
var stream = OutputStream(options.output);
toplevel.print(stream);
result.code = stream.get();
if (options.sourceMap) {
result.map = output.source_map.toString();
var url = options.sourceMap.url;
if (url) {
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
if (url == "inline") {
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
} else {
result.code += "\n//# sourceMappingURL=" + url;
}
result.map = options.output.source_map.toString();
if (options.sourceMap.url == "inline") {
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
} else if (options.sourceMap.url) {
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
}
}
}
if (options.nameCache && options.mangle) {
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
if (options.mangle.properties && options.mangle.properties.cache) {
options.nameCache.props = to_json(options.mangle.properties.cache);
}
}
if (timings) {
timings.end = Date.now();
result.timings = {
parse: 1e-3 * (timings.rename - timings.parse),
rename: 1e-3 * (timings.compress - timings.rename),
compress: 1e-3 * (timings.scope - timings.compress),
scope: 1e-3 * (timings.mangle - timings.scope),
mangle: 1e-3 * (timings.properties - timings.mangle),
properties: 1e-3 * (timings.output - timings.properties),
output: 1e-3 * (timings.end - timings.output),
total: 1e-3 * (timings.end - timings.start)
};
}
if (warnings.length) {
result.warnings = warnings;
}
@@ -269,7 +151,6 @@ function minify(files, options) {
} catch (ex) {
return { error: ex };
} finally {
AST_Node.log_function();
AST_Node.disable_validation();
AST_Node.warn_function = warn_function;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
/***********************************************************************
A JavaScript tokenizer / parser / beautifier / compressor.
https://github.com/mishoo/UglifyJS
https://github.com/mishoo/UglifyJS2
-------------------------------- (C) ---------------------------------
@@ -43,8 +43,17 @@
"use strict";
var builtins = function() {
var names = new Dictionary();
function find_builtins(reserved) {
// Compatibility fix for some standard defined globals not defined on every js environment
var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
var objects = {};
var global_ref = typeof global === "object" ? global : self;
new_globals.forEach(function (new_global) {
objects[new_global] = global_ref[new_global] || new Function();
});
// NaN will be included due to Number.NaN
[
"null",
@@ -54,206 +63,227 @@ var builtins = function() {
"-Infinity",
"undefined",
].forEach(add);
[
Array,
Boolean,
Date,
Error,
Function,
Math,
Number,
Object,
RegExp,
String,
].forEach(function(ctor) {
[ Object, Array, Function, Number,
String, Boolean, Error, Math,
Date, RegExp, objects.Symbol, ArrayBuffer,
DataView, decodeURI, decodeURIComponent,
encodeURI, encodeURIComponent, eval, EvalError,
Float32Array, Float64Array, Int8Array, Int16Array,
Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
objects.WeakMap, objects.WeakSet
].forEach(function(ctor){
Object.getOwnPropertyNames(ctor).map(add);
if (ctor.prototype) {
Object.getOwnPropertyNames(new ctor()).map(add);
Object.getOwnPropertyNames(ctor.prototype).map(add);
}
});
return names;
function add(name) {
names.set(name, true);
}
}();
function reserve_quoted_keys(ast, reserved) {
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ClassProperty) {
if (node.start && node.start.quote) add(node.key);
} else if (node instanceof AST_ObjectProperty) {
if (node.start && node.start.quote) add(node.key);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
}
}));
function add(name) {
push_uniq(reserved, name);
}
}
function addStrings(node, add) {
if (node instanceof AST_Conditional) {
addStrings(node.consequent, add);
addStrings(node.alternative, add);
} else if (node instanceof AST_Sequence) {
addStrings(node.tail_node(), add);
} else if (node instanceof AST_String) {
add(node.value);
}
}
function mangle_properties(ast, options) {
options = defaults(options, {
builtins: false,
cache: null,
debug: false,
keep_quoted: false,
only_cache: false,
regex: null,
reserved: null,
}, true);
var reserved = options.builtins ? new Dictionary() : builtins.clone();
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
reserved.set(name, true);
});
var cname = -1;
var cache;
if (options.cache) {
cache = options.cache.props;
cache.each(function(name) {
reserved.set(name, true);
});
} else {
cache = new Dictionary();
var reserved = options.reserved || [];
if (!options.builtins) find_builtins(reserved);
var cache = options.cache;
if (cache == null) {
cache = {
cname: -1,
props: new Dictionary()
};
}
var regex = options.regex;
var keep_quoted = options.keep_quoted;
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
// the same as passing an empty string.
var debug = options.debug !== false;
var debug_suffix;
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
var debug_name_suffix;
if (debug) {
debug_name_suffix = (options.debug === true ? "" : options.debug);
}
var names_to_mangle = new Dictionary();
var unmangleable = reserved.clone();
var names_to_mangle = [];
var unmangleable = [];
var to_keep = {};
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_Binary) {
if (node.operator == "in") addStrings(node.left, add);
} else if (node.TYPE == "Call") {
var exp = node.expression;
if (exp instanceof AST_Dot) switch (exp.property) {
case "defineProperty":
case "getOwnPropertyDescriptor":
if (node.args.length < 2) break;
exp = exp.expression;
if (!(exp instanceof AST_SymbolRef)) break;
if (exp.name != "Object") break;
if (!exp.definition().undeclared) break;
addStrings(node.args[1], add);
break;
case "hasOwnProperty":
if (node.args.length < 1) break;
addStrings(node.args[0], add);
break;
}
} else if (node instanceof AST_ClassProperty) {
if (typeof node.key == "string") add(node.key);
} else if (node instanceof AST_Dot) {
ast.walk(new TreeWalker(function(node){
if (node instanceof AST_ObjectKeyVal) {
add(node.key, keep_quoted && node.quote);
}
else if (node instanceof AST_ObjectProperty) {
// setter or getter, since KeyVal is handled above
add(node.key.name);
}
else if (node instanceof AST_Dot) {
add(node.property);
} else if (node instanceof AST_ObjectProperty) {
if (typeof node.key == "string") add(node.key);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
}
else if (node instanceof AST_Sub) {
addStrings(node.property, keep_quoted);
}
else if (node instanceof AST_ConciseMethod) {
add(node.name.name);
}
}));
// step 2: renaming properties
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_Binary) {
if (node.operator == "in") mangleStrings(node.left);
} else if (node.TYPE == "Call") {
var exp = node.expression;
if (exp instanceof AST_Dot) switch (exp.property) {
case "defineProperty":
case "getOwnPropertyDescriptor":
if (node.args.length < 2) break;
exp = exp.expression;
if (!(exp instanceof AST_SymbolRef)) break;
if (exp.name != "Object") break;
if (!exp.definition().undeclared) break;
mangleStrings(node.args[1]);
break;
case "hasOwnProperty":
if (node.args.length < 1) break;
mangleStrings(node.args[0]);
break;
}
} else if (node instanceof AST_ClassProperty) {
if (typeof node.key == "string") node.key = mangle(node.key);
} else if (node instanceof AST_Dot) {
node.property = mangle(node.property);
} else if (node instanceof AST_ObjectProperty) {
if (typeof node.key == "string") node.key = mangle(node.key);
} else if (node instanceof AST_Sub) {
if (!options.keep_quoted) mangleStrings(node.property);
// step 2: transform the tree, renaming properties
return ast.transform(new TreeTransformer(function(node){
if (node instanceof AST_ObjectKeyVal) {
if (!(keep_quoted && node.quote))
node.key = mangle(node.key);
}
else if (node instanceof AST_ObjectProperty) {
// setter or getter
node.key.name = mangle(node.key.name);
}
else if (node instanceof AST_Dot) {
node.property = mangle(node.property);
}
else if (node instanceof AST_Sub) {
if (!keep_quoted)
node.property = mangleStrings(node.property);
}
else if (node instanceof AST_ConciseMethod) {
if (should_mangle(node.name.name)) {
node.name.name = mangle(node.name.name);
}
}
// else if (node instanceof AST_String) {
// if (should_mangle(node.value)) {
// AST_Node.warn(
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
// file : node.start.file,
// line : node.start.line,
// col : node.start.col,
// prop : node.value
// }
// );
// }
// }
}));
// only function declarations after this line
function can_mangle(name) {
if (unmangleable.has(name)) return false;
if (unmangleable.indexOf(name) >= 0) return false;
if (reserved.indexOf(name) >= 0) return false;
if (options.only_cache) {
return cache.props.has(name);
}
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
return true;
}
function should_mangle(name) {
if (reserved.has(name)) return false;
if (keep_quoted && name in to_keep) return false;
if (regex && !regex.test(name)) return false;
return cache.has(name) || names_to_mangle.has(name);
if (reserved.indexOf(name) >= 0) return false;
return cache.props.has(name)
|| names_to_mangle.indexOf(name) >= 0;
}
function add(name) {
if (can_mangle(name)) names_to_mangle.set(name, true);
if (!should_mangle(name)) unmangleable.set(name, true);
function add(name, keep) {
if (keep) {
to_keep[name] = true;
return;
}
if (can_mangle(name))
push_uniq(names_to_mangle, name);
if (!should_mangle(name)) {
push_uniq(unmangleable, name);
}
}
function mangle(name) {
if (!should_mangle(name)) return name;
var mangled = cache.get(name);
if (!should_mangle(name)) {
return name;
}
var mangled = cache.props.get(name);
if (!mangled) {
if (debug) {
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo ---> o._$foo$NNN_.
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
if (can_mangle(debug_mangled)) mangled = debug_mangled;
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
mangled = debug_mangled;
}
}
// either debug mode is off, or it is on and we could not use the mangled name
if (!mangled) do {
mangled = base54(++cname);
} while (!can_mangle(mangled));
if (/^#/.test(name)) mangled = "#" + mangled;
cache.set(name, mangled);
if (!mangled) {
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
// check so we don't collide with a quoted name.
do {
mangled = base54(++cache.cname);
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
}
cache.props.set(name, mangled);
}
return mangled;
}
function mangleStrings(node) {
if (node instanceof AST_Sequence) {
mangleStrings(node.expressions.tail_node());
} else if (node instanceof AST_String) {
node.value = mangle(node.value);
} else if (node instanceof AST_Conditional) {
mangleStrings(node.consequent);
mangleStrings(node.alternative);
function addStrings(node, keep) {
var out = {};
try {
(function walk(node){
node.walk(new TreeWalker(function(node){
if (node instanceof AST_Sequence) {
walk(node.expressions[node.expressions.length - 1]);
return true;
}
if (node instanceof AST_String) {
add(node.value, keep);
return true;
}
if (node instanceof AST_Conditional) {
walk(node.consequent);
walk(node.alternative);
return true;
}
throw out;
}));
})(node);
} catch(ex) {
if (ex !== out) throw ex;
}
}
function mangleStrings(node) {
return node.transform(new TreeTransformer(function(node){
if (node instanceof AST_Sequence) {
var last = node.expressions.length - 1;
node.expressions[last] = mangleStrings(node.expressions[last]);
}
else if (node instanceof AST_String) {
node.value = mangle(node.value);
}
else if (node instanceof AST_Conditional) {
node.consequent = mangleStrings(node.consequent);
node.alternative = mangleStrings(node.alternative);
}
return node;
}));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/***********************************************************************
A JavaScript tokenizer / parser / beautifier / compressor.
https://github.com/mishoo/UglifyJS
https://github.com/mishoo/UglifyJS2
-------------------------------- (C) ---------------------------------
@@ -43,153 +43,55 @@
"use strict";
var vlq_char = characters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
var vlq_bits = vlq_char.reduce(function(map, ch, bits) {
map[ch] = bits;
return map;
}, Object.create(null));
function vlq_decode(indices, str) {
var value = 0;
var shift = 0;
for (var i = 0, j = 0; i < str.length; i++) {
var bits = vlq_bits[str[i]];
value += (bits & 31) << shift;
if (bits & 32) {
shift += 5;
} else {
indices[j++] += value & 1 ? 0x80000000 | -(value >> 1) : value >> 1;
value = shift = 0;
}
}
return j;
}
function vlq_encode(num) {
var result = "";
num = Math.abs(num) << 1 | num >>> 31;
do {
var bits = num & 31;
if (num >>>= 5) bits |= 32;
result += vlq_char[bits];
} while (num);
return result;
}
function create_array_map() {
var map = new Dictionary();
var array = [];
array.index = function(name) {
var index = map.get(name);
if (!(index >= 0)) {
index = array.length;
array.push(name);
map.set(name, index);
}
return index;
};
return array;
}
// a small wrapper around fitzgen's source-map library
function SourceMap(options) {
var sources = create_array_map();
var sources_content = options.includeSources && new Dictionary();
var names = create_array_map();
var mappings = "";
if (options.orig) Object.keys(options.orig).forEach(function(name) {
var map = options.orig[name];
var indices = [ 0, 0, 1, 0, 0 ];
options.orig[name] = {
names: map.names,
mappings: map.mappings.split(/;/).map(function(line) {
indices[0] = 0;
return line.split(/,/).map(function(segment) {
return indices.slice(0, vlq_decode(indices, segment));
});
}),
sources: map.sources,
};
if (!sources_content || !map.sourcesContent) return;
for (var i = 0; i < map.sources.length; i++) {
var content = map.sourcesContent[i];
if (content) sources_content.set(map.sources[i], content);
}
options = defaults(options, {
file : null,
root : null,
orig : null,
orig_line_diff : 0,
dest_line_diff : 0,
});
var prev_source;
var generated_line = 1;
var generated_column = 0;
var source_index = 0;
var original_line = 1;
var original_column = 0;
var name_index = 0;
return {
add: options.orig ? function(source, gen_line, gen_col, orig_line, orig_col, name) {
var map = options.orig[source];
if (map) {
var segments = map.mappings[orig_line - 1];
if (!segments) return;
var indices;
for (var i = 0; i < segments.length; i++) {
var col = segments[i][0];
if (orig_col >= col) indices = segments[i];
if (orig_col <= col) break;
}
if (!indices || indices.length < 4) {
source = null;
} else {
source = map.sources[indices[1]];
orig_line = indices[2];
orig_col = indices[3];
if (indices.length > 4) name = map.names[indices[4]];
}
var generator = new MOZ_SourceMap.SourceMapGenerator({
file : options.file,
sourceRoot : options.root
});
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
if (orig_map && Array.isArray(options.orig.sources)) {
orig_map._sources.toArray().forEach(function(source) {
var sourceContent = orig_map.sourceContentFor(source, true);
if (sourceContent) {
generator.setSourceContent(source, sourceContent);
}
add(source, gen_line, gen_col, orig_line, orig_col, name);
} : add,
setSourceContent: sources_content ? function(source, content) {
if (!sources_content.has(source)) {
sources_content.set(source, content);
}
} : noop,
toString: function() {
return JSON.stringify({
version: 3,
file: options.filename || undefined,
sourceRoot: options.root || undefined,
sources: sources,
sourcesContent: sources_content ? sources.map(function(source) {
return sources_content.get(source) || null;
}) : undefined,
names: names,
mappings: mappings,
});
}
};
});
}
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
if (prev_source == null && source == null) return;
prev_source = source;
if (generated_line < gen_line) {
generated_column = 0;
do {
mappings += ";";
} while (++generated_line < gen_line);
} else if (mappings) {
mappings += ",";
if (orig_map) {
var info = orig_map.originalPositionFor({
line: orig_line,
column: orig_col
});
if (info.source === null) {
return;
}
source = info.source;
orig_line = info.line;
orig_col = info.column;
name = info.name || name;
}
mappings += vlq_encode(gen_col - generated_column);
generated_column = gen_col;
if (source == null) return;
var src_idx = sources.index(source);
mappings += vlq_encode(src_idx - source_index);
source_index = src_idx;
mappings += vlq_encode(orig_line - original_line);
original_line = orig_line;
mappings += vlq_encode(orig_col - original_column);
original_column = orig_col;
if (options.names && name != null) {
var name_idx = names.index(name);
mappings += vlq_encode(name_idx - name_index);
name_index = name_idx;
}
}
}
generator.addMapping({
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
original : { line: orig_line + options.orig_line_diff, column: orig_col },
source : source,
name : name
});
};
return {
add : add,
get : function() { return generator },
toString : function() { return JSON.stringify(generator.toJSON()); }
};
};

View File

@@ -1,7 +1,7 @@
/***********************************************************************
A JavaScript tokenizer / parser / beautifier / compressor.
https://github.com/mishoo/UglifyJS
https://github.com/mishoo/UglifyJS2
-------------------------------- (C) ---------------------------------
@@ -43,6 +43,8 @@
"use strict";
// Tree transformer helpers.
function TreeTransformer(before, after) {
TreeWalker.call(this);
this.before = before;
@@ -50,201 +52,207 @@ function TreeTransformer(before, after) {
}
TreeTransformer.prototype = new TreeWalker;
(function(DEF) {
(function(undefined){
function _(node, descend) {
node.DEFMETHOD("transform", function(tw, in_list){
var x, y;
tw.push(this);
if (tw.before) x = tw.before(this, descend, in_list);
if (x === undefined) {
if (!tw.after) {
x = this;
descend(x, tw);
} else {
tw.stack[tw.stack.length - 1] = x = this;
descend(x, tw);
y = tw.after(x, in_list);
if (y !== undefined) x = y;
}
}
tw.pop(this);
return x;
});
};
function do_list(list, tw) {
return List(list, function(node) {
return MAP(list, function(node){
return node.transform(tw, true);
});
}
};
DEF(AST_Node, noop);
DEF(AST_LabeledStatement, function(self, tw) {
_(AST_Node, noop);
_(AST_LabeledStatement, function(self, tw){
self.label = self.label.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_SimpleStatement, function(self, tw) {
_(AST_SimpleStatement, function(self, tw){
self.body = self.body.transform(tw);
});
DEF(AST_Block, function(self, tw) {
_(AST_Block, function(self, tw){
self.body = do_list(self.body, tw);
});
DEF(AST_Do, function(self, tw) {
self.body = self.body.transform(tw);
self.condition = self.condition.transform(tw);
});
DEF(AST_While, function(self, tw) {
_(AST_DWLoop, function(self, tw){
self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_For, function(self, tw) {
_(AST_For, function(self, tw){
if (self.init) self.init = self.init.transform(tw);
if (self.condition) self.condition = self.condition.transform(tw);
if (self.step) self.step = self.step.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_ForEnumeration, function(self, tw) {
_(AST_ForIn, function(self, tw){
self.init = self.init.transform(tw);
self.object = self.object.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_With, function(self, tw) {
_(AST_With, function(self, tw){
self.expression = self.expression.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_Exit, function(self, tw) {
_(AST_Exit, function(self, tw){
if (self.value) self.value = self.value.transform(tw);
});
DEF(AST_LoopControl, function(self, tw) {
_(AST_LoopControl, function(self, tw){
if (self.label) self.label = self.label.transform(tw);
});
DEF(AST_If, function(self, tw) {
_(AST_If, function(self, tw){
self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw);
if (self.alternative) self.alternative = self.alternative.transform(tw);
});
DEF(AST_Switch, function(self, tw) {
_(AST_Switch, function(self, tw){
self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw);
});
DEF(AST_Case, function(self, tw) {
_(AST_Case, function(self, tw){
self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw);
});
DEF(AST_Try, function(self, tw) {
_(AST_Try, function(self, tw){
self.body = do_list(self.body, tw);
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
});
DEF(AST_Catch, function(self, tw) {
if (self.argname) self.argname = self.argname.transform(tw);
_(AST_Catch, function(self, tw){
self.argname = self.argname.transform(tw);
self.body = do_list(self.body, tw);
});
DEF(AST_Definitions, function(self, tw) {
_(AST_Definitions, function(self, tw){
self.definitions = do_list(self.definitions, tw);
});
DEF(AST_VarDef, function(self, tw) {
_(AST_VarDef, function(self, tw){
self.name = self.name.transform(tw);
if (self.value) self.value = self.value.transform(tw);
});
DEF(AST_DefaultValue, function(self, tw) {
self.name = self.name.transform(tw);
self.value = self.value.transform(tw);
_(AST_Destructuring, function(self, tw) {
self.names = do_list(self.names, tw);
});
DEF(AST_Lambda, function(self, tw) {
_(AST_Lambda, function(self, tw){
if (self.name) self.name = self.name.transform(tw);
self.argnames = do_list(self.argnames, tw);
if (self.rest) self.rest = self.rest.transform(tw);
self.body = do_list(self.body, tw);
});
function transform_arrow(self, tw) {
self.argnames = do_list(self.argnames, tw);
if (self.rest) self.rest = self.rest.transform(tw);
if (self.value) {
self.value = self.value.transform(tw);
if (self.body instanceof AST_Node) {
self.body = self.body.transform(tw);
} else {
self.body = do_list(self.body, tw);
}
}
DEF(AST_Arrow, transform_arrow);
DEF(AST_AsyncArrow, transform_arrow);
DEF(AST_Class, function(self, tw) {
if (self.name) self.name = self.name.transform(tw);
if (self.extends) self.extends = self.extends.transform(tw);
self.properties = do_list(self.properties, tw);
});
DEF(AST_ClassProperty, function(self, tw) {
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
if (self.value) self.value = self.value.transform(tw);
});
DEF(AST_Call, function(self, tw) {
_(AST_Call, function(self, tw){
self.expression = self.expression.transform(tw);
self.args = do_list(self.args, tw);
});
DEF(AST_Sequence, function(self, tw) {
_(AST_Sequence, function(self, tw){
self.expressions = do_list(self.expressions, tw);
});
DEF(AST_Await, function(self, tw) {
_(AST_Dot, function(self, tw){
self.expression = self.expression.transform(tw);
});
DEF(AST_Yield, function(self, tw) {
if (self.expression) self.expression = self.expression.transform(tw);
});
DEF(AST_Dot, function(self, tw) {
self.expression = self.expression.transform(tw);
});
DEF(AST_Sub, function(self, tw) {
_(AST_Sub, function(self, tw){
self.expression = self.expression.transform(tw);
self.property = self.property.transform(tw);
});
DEF(AST_Spread, function(self, tw) {
_(AST_Yield, function(self, tw){
if (self.expression) self.expression = self.expression.transform(tw);
});
_(AST_Unary, function(self, tw){
self.expression = self.expression.transform(tw);
});
DEF(AST_Unary, function(self, tw) {
self.expression = self.expression.transform(tw);
});
DEF(AST_Binary, function(self, tw) {
_(AST_Binary, function(self, tw){
self.left = self.left.transform(tw);
self.right = self.right.transform(tw);
});
DEF(AST_Conditional, function(self, tw) {
_(AST_Conditional, function(self, tw){
self.condition = self.condition.transform(tw);
self.consequent = self.consequent.transform(tw);
self.alternative = self.alternative.transform(tw);
});
DEF(AST_Array, function(self, tw) {
_(AST_Array, function(self, tw){
self.elements = do_list(self.elements, tw);
});
DEF(AST_DestructuredArray, function(self, tw) {
self.elements = do_list(self.elements, tw);
if (self.rest) self.rest = self.rest.transform(tw);
_(AST_Object, function(self, tw){
self.properties = do_list(self.properties, tw);
});
DEF(AST_DestructuredKeyVal, function(self, tw) {
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
_(AST_ObjectProperty, function(self, tw){
if (self.key instanceof AST_Node) {
self.key = self.key.transform(tw);
}
self.value = self.value.transform(tw);
});
DEF(AST_DestructuredObject, function(self, tw) {
self.properties = do_list(self.properties, tw);
if (self.rest) self.rest = self.rest.transform(tw);
});
DEF(AST_Object, function(self, tw) {
_(AST_Class, function(self, tw){
if (self.name) self.name = self.name.transform(tw);
if (self.extends) self.extends = self.extends.transform(tw);
self.properties = do_list(self.properties, tw);
});
DEF(AST_ObjectProperty, function(self, tw) {
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
self.value = self.value.transform(tw);
_(AST_Expansion, function(self, tw){
self.expression = self.expression.transform(tw);
});
DEF(AST_ExportDeclaration, function(self, tw) {
self.body = self.body.transform(tw);
_(AST_Export, function(self, tw){
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
});
DEF(AST_ExportDefault, function(self, tw) {
self.body = self.body.transform(tw);
});
DEF(AST_ExportReferences, function(self, tw) {
self.properties = do_list(self.properties, tw);
});
DEF(AST_Import, function(self, tw) {
if (self.all) self.all = self.all.transform(tw);
if (self.default) self.default = self.default.transform(tw);
if (self.properties) self.properties = do_list(self.properties, tw);
});
DEF(AST_Template, function(self, tw) {
if (self.tag) self.tag = self.tag.transform(tw);
self.expressions = do_list(self.expressions, tw);
});
})(function(node, descend) {
node.DEFMETHOD("transform", function(tw, in_list) {
var x, y;
tw.push(this);
if (tw.before) x = tw.before(this, descend, in_list);
if (typeof x === "undefined") {
x = this;
descend(x, tw);
if (tw.after) {
y = tw.after(x, in_list);
if (typeof y !== "undefined") x = y;
_(AST_TemplateString, function(self, tw) {
for (var i = 0; i < self.segments.length; i++) {
if (!(self.segments[i] instanceof AST_TemplateSegment)) {
self.segments[i] = self.segments[i].transform(tw);
}
}
tw.pop();
return x;
});
});
_(AST_PrefixedTemplateString, function(self, tw) {
self.template_string = self.template_string.transform(tw);
});
})();

View File

@@ -1,7 +1,7 @@
/***********************************************************************
A JavaScript tokenizer / parser / beautifier / compressor.
https://github.com/mishoo/UglifyJS
https://github.com/mishoo/UglifyJS2
-------------------------------- (C) ---------------------------------
@@ -43,17 +43,40 @@
"use strict";
function array_to_hash(a) {
var ret = Object.create(null);
for (var i = 0; i < a.length; ++i)
ret[a[i]] = true;
return ret;
};
function slice(a, start) {
return Array.prototype.slice.call(a, start || 0);
};
function characters(str) {
return str.split("");
}
};
function member(name, array) {
return array.indexOf(name) >= 0;
}
};
function find_if(func, array) {
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
}
for (var i = 0, n = array.length; i < n; ++i) {
if (func(array[i]))
return array[i];
}
};
function repeat_string(str, i) {
if (i <= 0) return "";
if (i == 1) return str;
var d = repeat_string(str, i >> 1);
d += d;
if (i & 1) d += str;
return d;
};
function configure_error_stack(fn) {
Object.defineProperty(fn.prototype, "stack", {
@@ -62,7 +85,7 @@ function configure_error_stack(fn) {
err.name = this.name;
try {
throw err;
} catch (e) {
} catch(e) {
return e.stack;
}
}
@@ -72,21 +95,36 @@ function configure_error_stack(fn) {
function DefaultsError(msg, defs) {
this.message = msg;
this.defs = defs;
}
};
DefaultsError.prototype = Object.create(Error.prototype);
DefaultsError.prototype.constructor = DefaultsError;
DefaultsError.prototype.name = "DefaultsError";
configure_error_stack(DefaultsError);
DefaultsError.croak = function(msg, defs) {
throw new DefaultsError(msg, defs);
};
function defaults(args, defs, croak) {
if (croak) for (var i in args) {
if (HOP(args, i) && !HOP(defs, i)) throw new DefaultsError("`" + i + "` is not a supported option", defs);
if (args === true)
args = {};
var ret = args || {};
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
DefaultsError.croak("`" + i + "` is not a supported option", defs);
for (var i in defs) if (HOP(defs, i)) {
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
}
for (var i in args) {
if (HOP(args, i)) defs[i] = args[i];
return ret;
};
function merge(obj, ext) {
var count = 0;
for (var i in ext) if (HOP(ext, i)) {
obj[i] = ext[i];
count++;
}
return defs;
}
return count;
};
function noop() {}
function return_false() { return false; }
@@ -94,140 +132,205 @@ function return_true() { return true; }
function return_this() { return this; }
function return_null() { return null; }
var List = (function() {
function List(a, f) {
var ret = [];
for (var i = 0; i < a.length; i++) {
var MAP = (function(){
function MAP(a, f, backwards) {
var ret = [], top = [], i;
function doit() {
var val = f(a[i], i);
if (val === skip) continue;
if (val instanceof Splice) {
ret.push.apply(ret, val.v);
var is_last = val instanceof Last;
if (is_last) val = val.v;
if (val instanceof AtTop) {
val = val.v;
if (val instanceof Splice) {
top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
} else {
top.push(val);
}
}
else if (val !== skip) {
if (val instanceof Splice) {
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
} else {
ret.push(val);
}
}
return is_last;
};
if (a instanceof Array) {
if (backwards) {
for (i = a.length; --i >= 0;) if (doit()) break;
ret.reverse();
top.reverse();
} else {
ret.push(val);
for (i = 0; i < a.length; ++i) if (doit()) break;
}
}
return ret;
}
List.is_op = function(val) {
return val === skip || val instanceof Splice;
else {
for (i in a) if (HOP(a, i)) if (doit()) break;
}
return top.concat(ret);
};
List.splice = function(val) {
return new Splice(val);
};
var skip = List.skip = {};
function Splice(val) {
this.v = val;
}
return List;
MAP.at_top = function(val) { return new AtTop(val) };
MAP.splice = function(val) { return new Splice(val) };
MAP.last = function(val) { return new Last(val) };
var skip = MAP.skip = {};
function AtTop(val) { this.v = val };
function Splice(val) { this.v = val };
function Last(val) { this.v = val };
return MAP;
})();
function push_uniq(array, el) {
if (array.indexOf(el) < 0) return array.push(el);
}
if (array.indexOf(el) < 0)
array.push(el);
};
function string_template(text, props) {
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
var value = props[p];
return value instanceof AST_Node ? value.print_to_string() : value;
return text.replace(/\{(.+?)\}/g, function(str, p){
return props && props[p];
});
}
};
function remove(array, el) {
var index = array.indexOf(el);
if (index >= 0) array.splice(index, 1);
}
for (var i = array.length; --i >= 0;) {
if (array[i] === el) array.splice(i, 1);
}
};
function makePredicate(words) {
if (!Array.isArray(words)) words = words.split(" ");
var map = Object.create(null);
words.forEach(function(word) {
map[word] = true;
function mergeSort(array, cmp) {
if (array.length < 2) return array.slice();
function merge(a, b) {
var r = [], ai = 0, bi = 0, i = 0;
while (ai < a.length && bi < b.length) {
cmp(a[ai], b[bi]) <= 0
? r[i++] = a[ai++]
: r[i++] = b[bi++];
}
if (ai < a.length) r.push.apply(r, a.slice(ai));
if (bi < b.length) r.push.apply(r, b.slice(bi));
return r;
};
function _ms(a) {
if (a.length <= 1)
return a;
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
left = _ms(left);
right = _ms(right);
return merge(left, right);
};
return _ms(array);
};
function set_difference(a, b) {
return a.filter(function(el){
return b.indexOf(el) < 0;
});
return map;
}
};
function set_intersection(a, b) {
return a.filter(function(el){
return b.indexOf(el) >= 0;
});
};
// this function is taken from Acorn [1], written by Marijn Haverbeke
// [1] https://github.com/marijnh/acorn
function makePredicate(words) {
if (!(words instanceof Array)) words = words.split(" ");
var f = "", cats = [];
out: for (var i = 0; i < words.length; ++i) {
for (var j = 0; j < cats.length; ++j)
if (cats[j][0].length == words[i].length) {
cats[j].push(words[i]);
continue out;
}
cats.push([words[i]]);
}
function quote(word) {
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
switch (s) {
case "\u2028": return "\\u2028";
case "\u2029": return "\\u2029";
}
return s;
});
}
function compareTo(arr) {
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
f += "switch(str){";
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
f += "return true}return false;";
}
// When there are more than three length categories, an outer
// switch first dispatches on the lengths, to save on comparisons.
if (cats.length > 3) {
cats.sort(function(a, b) {return b.length - a.length;});
f += "switch(str.length){";
for (var i = 0; i < cats.length; ++i) {
var cat = cats[i];
f += "case " + cat[0].length + ":";
compareTo(cat);
}
f += "}";
// Otherwise, simply generate a flat `switch` statement.
} else {
compareTo(words);
}
return new Function("str", f);
};
function all(array, predicate) {
for (var i = array.length; --i >= 0;)
if (!predicate(array[i], i))
if (!predicate(array[i]))
return false;
return true;
}
};
function Dictionary() {
this.values = Object.create(null);
}
this._values = Object.create(null);
this._size = 0;
};
Dictionary.prototype = {
set: function(key, val) {
if (key == "__proto__") {
this.proto_value = val;
} else {
this.values[key] = val;
}
if (!this.has(key)) ++this._size;
this._values["$" + key] = val;
return this;
},
add: function(key, val) {
var list = this.get(key);
if (list) {
list.push(val);
if (this.has(key)) {
this.get(key).push(val);
} else {
this.set(key, [ val ]);
}
return this;
},
get: function(key) {
return key == "__proto__" ? this.proto_value : this.values[key];
},
get: function(key) { return this._values["$" + key] },
del: function(key) {
if (key == "__proto__") {
delete this.proto_value;
} else {
delete this.values[key];
if (this.has(key)) {
--this._size;
delete this._values["$" + key];
}
return this;
},
has: function(key) {
return key == "__proto__" ? "proto_value" in this : key in this.values;
},
all: function(predicate) {
for (var i in this.values)
if (!predicate(this.values[i], i)) return false;
if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false;
return true;
},
has: function(key) { return ("$" + key) in this._values },
each: function(f) {
for (var i in this.values)
f(this.values[i], i);
if ("proto_value" in this) f(this.proto_value, "__proto__");
for (var i in this._values)
f(this._values[i], i.substr(1));
},
size: function() {
return Object.keys(this.values).length + ("proto_value" in this);
return this._size;
},
map: function(f) {
var ret = [];
for (var i in this.values)
ret.push(f(this.values[i], i));
if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__"));
for (var i in this._values)
ret.push(f(this._values[i], i.substr(1)));
return ret;
},
clone: function() {
var ret = new Dictionary();
this.each(function(value, i) {
ret.set(i, value);
});
return ret;
},
toObject: function() {
var obj = {};
this.each(function(value, i) {
obj["$" + i] = value;
});
return obj;
},
toObject: function() { return this._values }
};
Dictionary.fromObject = function(obj) {
var dict = new Dictionary();
for (var i in obj)
if (HOP(obj, i)) dict.set(i.slice(1), obj[i]);
dict._size = merge(dict._values, obj);
return dict;
};
@@ -238,48 +341,22 @@ function HOP(obj, prop) {
// return true if the node at the top of the stack (that means the
// innermost node in the current output) is lexically the first in
// a statement.
function first_in_statement(stack, arrow, export_default) {
function first_in_statement(stack) {
var node = stack.parent(-1);
for (var i = 0, p; p = stack.parent(i++); node = p) {
if (is_arrow(p)) {
return arrow && p.value === node;
} else if (p instanceof AST_Binary) {
if (p.left === node) continue;
} else if (p.TYPE == "Call") {
if (p.expression === node) continue;
} else if (p instanceof AST_Conditional) {
if (p.condition === node) continue;
} else if (p instanceof AST_ExportDefault) {
return export_default;
} else if (p instanceof AST_PropAccess) {
if (p.expression === node) continue;
} else if (p instanceof AST_Sequence) {
if (p.expressions[0] === node) continue;
} else if (p instanceof AST_SimpleStatement) {
for (var i = 0, p; p = stack.parent(i); i++) {
if (p instanceof AST_Statement && p.body === node)
return true;
} else if (p instanceof AST_Template) {
if (p.tag === node) continue;
} else if (p instanceof AST_UnaryPostfix) {
if (p.expression === node) continue;
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
(p instanceof AST_Dot && p.expression === node ) ||
(p instanceof AST_Sub && p.expression === node ) ||
(p instanceof AST_Conditional && p.condition === node ) ||
(p instanceof AST_Binary && p.left === node ) ||
(p instanceof AST_UnaryPostfix && p.expression === node ))
{
node = p;
} else {
return false;
}
return false;
}
}
function DEF_BITPROPS(ctor, props) {
if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", "));
props.forEach(function(name, pos) {
var mask = 1 << pos;
Object.defineProperty(ctor.prototype, name, {
get: function() {
return !!(this._bits & mask);
},
set: function(val) {
if (val)
this._bits |= mask;
else
this._bits &= ~mask;
},
});
});
}

View File

@@ -1,17 +1,23 @@
{
"name": "uglify-js",
"name": "uglify-es",
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.15.2",
"version": "3.0.9",
"engines": {
"node": ">=0.8.0"
},
"maintainers": [
"Alex Lam <alexlamsl@gmail.com>",
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
],
"repository": "mishoo/UglifyJS",
"repository": {
"type": "git",
"url": "https://github.com/mishoo/UglifyJS2.git"
},
"bugs": {
"url": "https://github.com/mishoo/UglifyJS2/issues"
},
"main": "tools/node.js",
"bin": {
"uglifyjs": "bin/uglifyjs"
@@ -22,35 +28,17 @@
"tools",
"LICENSE"
],
"dependencies": {
"commander": "~2.9.0",
"source-map": "~0.5.1"
},
"devDependencies": {
"acorn": "~8.2.1",
"semver": "~6.3.0"
"acorn": "~5.0.3",
"mocha": "~2.3.4",
"semver": "~5.3.0"
},
"scripts": {
"test": "node test/compress.js && node test/mocha.js"
"test": "node test/run-tests.js"
},
"keywords": [
"cli",
"compress",
"compressor",
"ecma",
"ecmascript",
"es",
"es5",
"javascript",
"js",
"jsmin",
"min",
"minification",
"minifier",
"minify",
"optimize",
"optimizer",
"pack",
"packer",
"parse",
"parser",
"uglifier",
"uglify"
]
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
}

View File

@@ -4,46 +4,43 @@
"use strict";
var createHash = require("crypto").createHash;
var fetch = require("./fetch");
var spawn = require("child_process").spawn;
var zlib = require("zlib");
var fork = require("child_process").fork;
var args = process.argv.slice(2);
if (!args.length) args.push("-mc");
args.unshift("bin/uglifyjs");
args.push("--timings");
if (!args.length) {
args.push("-mc");
}
args.push("--stats");
var urls = [
"https://code.jquery.com/jquery-3.4.1.js",
"https://code.angularjs.org/1.7.8/angular.js",
"https://unpkg.com/mathjs@6.2.3/dist/math.js",
"https://unpkg.com/react@15.3.2/dist/react.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.js",
"https://cdnjs.cloudflare.com/ajax/libs/antd/4.18.7/antd.js",
"https://code.jquery.com/jquery-3.2.1.js",
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js",
"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.12.2/ember.prod.js",
"https://raw.githubusercontent.com/kangax/html-minifier/v4.0.0/dist/htmlminifier.js",
"https://unpkg.com/react@15.3.2/dist/react.js",
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
];
var results = {};
var remaining = 2 * urls.length;
function done() {
if (!--remaining) {
var failures = [];
var sum = { input: 0, output: 0, gzip: 0 };
urls.forEach(function(url) {
var info = results[url];
console.log();
console.log(url);
console.log(info.log);
var elapsed = 0;
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
elapsed += 1e-3 * parseInt(time);
return "";
}));
console.log("Run-time:", elapsed.toFixed(3), "s");
console.log("Original:", info.input, "bytes");
console.log("Uglified:", info.output, "bytes");
console.log("GZipped: ", info.gzip, "bytes");
console.log("SHA1 sum:", info.sha1);
if (info.code) {
failures.push(url);
}
sum.input += info.input;
sum.output += info.output;
sum.gzip += info.gzip;
});
if (failures.length) {
console.error("Benchmark failed:");
@@ -51,13 +48,6 @@ function done() {
console.error(url);
});
process.exit(1);
} else {
console.log();
console.log("Subtotal");
console.log();
console.log("Original:", sum.input, "bytes");
console.log("Uglified:", sum.output, "bytes");
console.log("GZipped: ", sum.gzip, "bytes");
}
}
}
@@ -65,25 +55,17 @@ urls.forEach(function(url) {
results[url] = {
input: 0,
output: 0,
gzip: 0,
log: ""
};
fetch(url, function(err, res) {
if (err) throw err;
var uglifyjs = spawn(process.argv[0], args, { silent: true });
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
res.on("data", function(data) {
results[url].input += data.length;
}).pipe(uglifyjs.stdin);
var sha1 = createHash("sha1");
uglifyjs.stdout.on("data", function(data) {
results[url].output += data.length;
}).pipe(zlib.createGzip({
level: zlib.Z_BEST_COMPRESSION
})).on("data", function(data) {
results[url].gzip += data.length;
sha1.update(data);
}).on("end", function() {
results[url].sha1 = sha1.digest("hex");
}).pipe(createHash("sha1")).on("data", function(data) {
results[url].sha1 = data.toString("hex");
done();
});
uglifyjs.stderr.setEncoding("utf8");

View File

@@ -1,461 +0,0 @@
"use strict";
require("../tools/tty");
var assert = require("assert");
var child_process = require("child_process");
var fs = require("fs");
var path = require("path");
var sandbox = require("./sandbox");
var semver = require("semver");
var U = require("./node");
var batch = 50;
var dir = path.resolve(path.dirname(module.filename), "compress");
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);
var tests = parse_test(path.resolve(dir, file));
process.exit(Object.keys(tests).slice(start, start + batch).filter(function(name) {
return !test_case(tests[name]);
}).length);
} else {
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(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] = true;
}
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).");
console.error("!!! " + Object.keys(failed_files).join(", "));
process.exit(1);
}
})();
}
function evaluate(code) {
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
return new Function("return(" + code + ")")();
}
function log() {
console.log("%s", tmpl.apply(null, arguments));
}
function make_code(ast, options) {
var stream = U.OutputStream(options);
ast.print(stream);
return stream.get();
}
function parse_test(file) {
var script = fs.readFileSync(file, "utf8");
try {
var ast = U.parse(script, {
filename: file
});
} catch (e) {
console.error("Caught error while parsing tests in " + file);
console.error(e);
process.exit(1);
}
var tests = Object.create(null);
var tw = new U.TreeWalker(function(node, descend) {
if (node instanceof U.AST_LabeledStatement
&& tw.parent() instanceof U.AST_Toplevel) {
var name = node.label.name;
if (name in tests) {
throw new Error('Duplicated test name "' + name + '" in ' + file);
}
tests[name] = get_one_test(name, node.body);
return true;
}
if (!(node instanceof U.AST_Toplevel)) croak(node);
});
ast.walk(tw);
return tests;
function croak(node) {
throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
file: file,
line: node.start.line,
col: node.start.col,
code: make_code(node, { beautify: false })
}));
}
function read_string(stat) {
if (stat.TYPE == "SimpleStatement") {
var body = stat.body;
switch(body.TYPE) {
case "String":
return body.value;
case "Array":
return body.elements.map(function(element) {
if (element.TYPE !== "String")
throw new Error("Should be array of strings");
return element.value;
}).join("\n");
}
}
throw new Error("Should be string or array of strings");
}
function get_one_test(name, block) {
var test = { name: name, options: {} };
var tw = new U.TreeWalker(function(node, descend) {
if (node instanceof U.AST_Assign) {
if (!(node.left instanceof U.AST_SymbolRef)) {
croak(node);
}
var name = node.left.name;
test[name] = evaluate(node.right);
return true;
}
if (node instanceof U.AST_LabeledStatement) {
var label = node.label;
assert.ok([
"input",
"expect",
"expect_exact",
"expect_warnings",
"expect_stdout",
"node_version",
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
name: label.name,
line: label.start.line,
col: label.start.col
}));
var stat = node.body;
if (label.name == "expect_exact" || label.name == "node_version") {
test[label.name] = read_string(stat);
} else if (label.name == "expect_stdout") {
var body = stat.body;
if (body instanceof U.AST_Boolean) {
test[label.name] = body.value;
} else if (body instanceof U.AST_Call) {
var ctor = global[body.expression.name];
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
line: label.start.line,
col: label.start.col
}));
test[label.name] = ctor.apply(null, body.args.map(function(node) {
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
line: label.start.line,
col: label.start.col
}));
return node.value;
}));
} else {
test[label.name] = read_string(stat) + "\n";
}
} else {
test[label.name] = stat;
}
return true;
}
});
block.walk(tw);
return test;
}
}
// Try to reminify original input with standard options
// to see if it matches expect_stdout.
function reminify(orig_options, input_code, input_formatted, stdout) {
for (var i = 0; i < minify_options.length; i++) {
var options = JSON.parse(minify_options[i]);
if (options.compress) [
"keep_fargs",
"keep_fnames",
].forEach(function(name) {
if (name in orig_options) {
options.compress[name] = orig_options[name];
}
});
var options_formatted = JSON.stringify(options, null, 4);
options.validate = true;
var result = U.minify(input_code, options);
if (result.error) {
log([
"!!! failed input reminify",
"---INPUT---",
"{input}",
"---OPTIONS---",
"{options}",
"--ERROR---",
"{error}",
"",
"",
].join("\n"), {
input: input_formatted,
options: options_formatted,
error: result.error,
});
return false;
} else {
var toplevel = sandbox.has_toplevel(options);
var expected = stdout[toplevel ? 1 : 0];
var actual = sandbox.run_code(result.code, toplevel);
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
actual = expected;
}
if (!sandbox.same_stdout(expected, actual)) {
log([
"!!! failed running reminified input",
"---INPUT---",
"{input}",
"---OPTIONS---",
"{options}",
"---OUTPUT---",
"{output}",
"---EXPECTED {expected_type}---",
"{expected}",
"---ACTUAL {actual_type}---",
"{actual}",
"",
"",
].join("\n"), {
input: input_formatted,
options: options_formatted,
output: result.code,
expected_type: typeof expected == "string" ? "STDOUT" : "ERROR",
expected: expected,
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
actual: actual,
});
return false;
}
}
}
return true;
}
function test_case(test) {
log(" Running test [{name}]", { name: test.name });
U.AST_Node.enable_validation();
var output_options = test.beautify || {};
var expect;
if (test.expect) {
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
} else {
expect = test.expect_exact;
}
var input = to_toplevel(test.input, test.mangle);
var input_code = make_code(input);
var input_formatted = make_code(test.input, {
annotations: true,
beautify: true,
comments: "all",
keep_quoted_props: true,
quote_style: 3,
});
try {
input.validate_ast();
U.parse(input_code);
} catch (ex) {
log([
"!!! Cannot parse input",
"---INPUT---",
"{input}",
"--PARSE ERROR--",
"{error}",
"",
"",
].join("\n"), {
input: input_formatted,
error: ex,
});
return false;
}
var warnings_emitted = [];
if (test.expect_warnings) {
var expected_warnings = make_code(test.expect_warnings, {
beautify: false,
quote_style: 2, // force double quote to match JSON
});
U.AST_Node.log_function(function(text) {
warnings_emitted.push(text);
}, /"INFO: /.test(expected_warnings));
}
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
var quoted_props = test.mangle.properties.reserved;
if (!Array.isArray(quoted_props)) quoted_props = [];
test.mangle.properties.reserved = quoted_props;
U.reserve_quoted_keys(input, quoted_props);
}
if (test.rename) {
input.figure_out_scope(test.mangle);
input.expand_names(test.mangle);
}
var cmp = new U.Compressor(test.options, true);
var output = cmp.compress(input);
output.figure_out_scope(test.mangle);
if (test.mangle) {
output.compute_char_frequency(test.mangle);
output.mangle_names(test.mangle);
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
}
var output_code = make_code(output, output_options);
U.AST_Node.log_function();
if (expect != output_code) {
log([
"!!! failed",
"---INPUT---",
"{input}",
"---OUTPUT---",
"{output}",
"---EXPECTED---",
"{expected}",
"",
"",
].join("\n"), {
input: input_formatted,
output: output_code,
expected: expect
});
return false;
}
// expect == output
try {
output.validate_ast();
U.parse(output_code);
} catch (ex) {
log([
"!!! Test matched expected result but cannot parse output",
"---INPUT---",
"{input}",
"---OUTPUT---",
"{output}",
"--REPARSE ERROR--",
"{error}",
"",
"",
].join("\n"), {
input: input_formatted,
output: output_code,
error: ex,
});
return false;
}
if (test.expect_warnings) {
warnings_emitted = warnings_emitted.map(function(input) {
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
});
var actual_warnings = JSON.stringify(warnings_emitted);
if (expected_warnings != actual_warnings) {
log([
"!!! failed",
"---INPUT---",
"{input}",
"---EXPECTED WARNINGS---",
"{expected_warnings}",
"---ACTUAL WARNINGS---",
"{actual_warnings}",
"",
"",
].join("\n"), {
input: input_formatted,
expected_warnings: expected_warnings,
actual_warnings: actual_warnings,
});
return false;
}
}
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
var toplevel = sandbox.has_toplevel({
compress: test.options,
mangle: test.mangle
});
var actual = stdout[toplevel ? 1 : 0];
if (test.expect_stdout === true || test.expect_stdout instanceof Error && test.expect_stdout.name === actual.name) {
test.expect_stdout = actual;
}
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
log([
"!!! Invalid input or expected stdout",
"---INPUT---",
"{input}",
"---EXPECTED {expected_type}---",
"{expected}",
"---ACTUAL {actual_type}---",
"{actual}",
"",
"",
].join("\n"), {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
actual: actual,
});
return false;
}
actual = sandbox.run_code(output_code, toplevel);
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
log([
"!!! failed",
"---INPUT---",
"{input}",
"---EXPECTED {expected_type}---",
"{expected}",
"---ACTUAL {actual_type}---",
"{actual}",
"",
"",
].join("\n"), {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
actual: actual,
});
return false;
}
if (!reminify(test.options, input_code, input_formatted, stdout)) {
return false;
}
}
return true;
}
function tmpl() {
return U.string_template.apply(null, arguments);
}
function to_toplevel(input, mangle_options) {
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
var directive = true;
var offset = input.start.line;
var tokens = [];
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
if (!directive || node === input) return;
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
return new U.AST_Directive(node.body);
} else {
directive = false;
}
})));
toplevel.figure_out_scope(mangle_options);
return toplevel;
}

View File

@@ -1,474 +0,0 @@
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,
unsafe: true,
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());",
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
// NOTE trailing comma doesn't contribute to length of an array
// That also means the array changes length if previous element is a hole too and got cut off
holes_and_undefined: {
input: {
w = [1,,];
@@ -13,13 +15,11 @@ holes_and_undefined: {
}
}
constant_join_1: {
constant_join: {
options = {
evaluate: true,
side_effects: true,
strings: true,
unsafe: true,
}
unsafe : true,
evaluate : true
};
input: {
var a = [ "foo", "bar", "baz" ].join("");
var a1 = [ "foo", "bar", "baz" ].join();
@@ -58,7 +58,7 @@ constant_join_1: {
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
var c6 = [ "1,2,,,foo,bar", baz() ].join();
var d = "foo-3bar-baz";
var e = (foo, bar, "");
var e = [].join(foo + bar);
var f = "";
var g = "";
}
@@ -66,10 +66,9 @@ constant_join_1: {
constant_join_2: {
options = {
evaluate: true,
strings: true,
unsafe: true,
}
unsafe : true,
evaluate : true
};
input: {
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
@@ -94,14 +93,85 @@ constant_join_2: {
}
}
spread_with_variable_as_last_element: {
input: {
var values = [4, 5, 6];
var a = [1, 2, 3, ...values];
}
expect: {
var values = [4, 5, 6];
var a = [1, 2, 3, ...values];
}
}
spread_with_variable_in_middle: {
input: {
var values = [4, 5, 6];
var a = [1, 2, 3, ...values, 7,,,];
}
expect: {
var values = [4, 5, 6];
var a = [1, 2, 3, ...values, 7,,,];
}
}
spread_with_variable_at_front: {
input: {
var values = [1, 2, 3];
var a = [...values, 4, 5, 6];
}
expect: {
var values = [1, 2, 3];
var a = [...values, 4, 5, 6];
}
}
spread_with_variable_at_front_after_elisions: {
input: {
var values = [1, 2, 3];
var a = [,,,...values, 4, 5, 6];
}
expect: {
var values = [1, 2, 3];
var a = [,,,...values, 4, 5, 6];
}
}
spread_with_array_at_end: {
input: {
var a = [1, 2, ...[4, 5, 6]];
}
expect: {
var a = [1, 2, ...[4, 5, 6]];
}
}
spread_with_logical_expression_at_end: {
options = { evaluate: true }
input: {
var a = [1, 2, 3, ...[2+2]]
}
expect: {
var a = [1, 2, 3, ...[4]]
}
}
spread_with_logical_expression_at_middle: {
options = { evaluate: true }
input: {
var a = [1, 1, ...[1+1, 1+2, 2+3], 8]
}
expect: {
var a = [1, 1, ...[2, 3, 5], 8]
}
}
constant_join_3: {
options = {
evaluate: true,
strings: true,
unsafe: true,
}
evaluate: true,
};
input: {
var foo, bar, baz;
var a = [ null ].join();
var b = [ , ].join();
var c = [ , 1, , 3 ].join();
@@ -116,7 +186,6 @@ constant_join_3: {
var l = [ foo, bar + "baz" ].join("");
}
expect: {
var foo, bar, baz;
var a = "";
var b = "";
var c = ",1,,3";
@@ -134,293 +203,50 @@ constant_join_3: {
for_loop: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unsafe: true,
unused: true,
}
unsafe : true,
unused : true,
evaluate : true,
reduce_vars : true
};
input: {
function f0() {
var a = [1, 2, 3];
var b = 0;
for (var i = 0; i < a.length; i++)
b += a[i];
return b;
for (var i = 0; i < a.length; i++) {
console.log(a[i]);
}
}
function f1() {
var a = [1, 2, 3];
var b = 0;
for (var i = 0, len = a.length; i < len; i++)
b += a[i];
return b;
for (var i = 0, len = a.length; i < len; i++) {
console.log(a[i]);
}
}
function f2() {
var a = [1, 2, 3];
for (var i = 0; i < a.length; i++)
for (var i = 0; i < a.length; i++) {
a[i]++;
return a[2];
}
}
console.log(f0(), f1(), f2());
}
expect: {
function f0() {
var a = [1, 2, 3];
var b = 0;
for (var i = 0; i < 3; i++)
b += a[i];
return b;
console.log(a[i]);
}
function f1() {
var a = [1, 2, 3];
var b = 0;
for (var i = 0; i < 3; i++)
b += a[i];
return b;
console.log(a[i]);
}
function f2() {
var a = [1, 2, 3];
for (var i = 0; i < a.length; i++)
a[i]++;
return a[2];
}
console.log(f0(), f1(), f2());
}
expect_stdout: "6 6 4"
}
index: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var a = [ 1, 2 ];
console.log(a[0], a[1]);
}
expect: {
console.log(1, 2);
}
expect_stdout: "1 2"
}
length: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var a = [ 1, 2 ];
console.log(a.length);
}
expect: {
console.log(2);
}
expect_stdout: "2"
}
index_length: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var a = [ 1, 2 ];
console.log(a[0], a.length);
}
expect: {
console.log(1, 2);
}
expect_stdout: "1 2"
}
constructor_bad: {
options = {
unsafe: true
}
input: {
try {
Array(NaN);
console.log("FAIL1");
} catch (ex) {
try {
new Array(NaN);
console.log("FAIL2");
} catch (ex) {
console.log("PASS");
}
}
try {
Array(3.14);
console.log("FAIL1");
} catch (ex) {
try {
new Array(3.14);
console.log("FAIL2");
} catch (ex) {
console.log("PASS");
}
}
}
expect: {
try {
Array(NaN);
console.log("FAIL1");
} catch (ex) {
try {
Array(NaN);
console.log("FAIL2");
} catch (ex) {
console.log("PASS");
}
}
try {
Array(3.14);
console.log("FAIL1");
} catch (ex) {
try {
Array(3.14);
console.log("FAIL2");
} catch (ex) {
console.log("PASS");
}
}
}
expect_stdout: [
"PASS",
"PASS",
]
expect_warnings: [
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
]
}
constructor_good: {
options = {
unsafe: true
}
input: {
console.log(Array());
console.log(Array(0));
console.log(Array(1));
console.log(Array(6));
console.log(Array(7));
console.log(Array(1, 2));
console.log(Array(false));
console.log(Array("foo"));
console.log(Array(Array));
console.log(new Array());
console.log(new Array(0));
console.log(new Array(1));
console.log(new Array(6));
console.log(new Array(7));
console.log(new Array(1, 2));
console.log(new Array(false));
console.log(new Array("foo"));
console.log(new Array(Array));
}
expect: {
console.log([]);
console.log([]);
console.log([,]);
console.log([,,,,,,]);
console.log(Array(7));
console.log([ 1, 2 ]);
console.log([ false ]);
console.log([ "foo" ]);
console.log(Array(Array));
console.log([]);
console.log([]);
console.log([,]);
console.log([,,,,,,]);
console.log(Array(7));
console.log([ 1, 2 ]);
console.log([ false ]);
console.log([ "foo" ]);
console.log(Array(Array));
}
expect_stdout: true
expect_warnings: []
}
unsafe_evaluate_modified_binary: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(console && a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(console && a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}
unsafe_evaluate_modified_conditional: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(console ? a : []).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(console ? a : []).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}
unsafe_evaluate_modified_sequence: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(0, a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(0, a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}

137
test/compress/arrow.js Normal file
View File

@@ -0,0 +1,137 @@
arrow_functions_without_body: {
input: {
var a1 = () => 42;
var a2 = (p) => p;
var a3 = p => p;
var a4 = (...p) => p;
var a5 = (b, c) => b + c;
var a6 = (b, ...c) => b + c[0];
var a7 = (...b) => b.join();
}
expect: {
var a1 = () => 42;
var a2 = (p) => p;
var a3 = p => p;
var a4 = (...p) => p;
var a5 = (b, c) => b + c;
var a6 = (b, ...c) => b + c[0];
var a7 = (...b) => b.join();
}
}
arrow_functions_with_body: {
input: {
var a1 = () => {
var a = 42 * Math.random();
return a;
};
var a2 = (p) => {
var a = Math.random() * p;
return a;
};
var a3 = p => {
var a = Math.random() * p;
return a;
};
var a4 = (...p) => {
var a = Math.random() * p;
return a;
};
var a5 = (b, c) => {
var result = b * c + b / c;
return result
};
var a6 = (b, ...c) => {
var result = b;
for (var i = 0; i < c.length; i++)
result += c[i];
return result
};
var a7 = (...b) => {
b.join();
}
}
expect: {
var a1 = () => {
var a = 42 * Math.random();
return a;
};
var a2 = (p) => {
var a = Math.random() * p;
return a;
};
var a3 = p => {
var a = Math.random() * p;
return a;
};
var a4 = (...p) => {
var a = Math.random() * p;
return a;
};
var a5 = (b, c) => {
var result = b * c + b / c;
return result
};
var a6 = (b, ...c) => {
var result = b;
for (var i = 0; i < c.length; i++)
result += c[i];
return result
};
var a7 = (...b) => {
b.join();
};
}
}
arrow_function_with_single_parameter_with_default: {
input: {
var foo = (a = 0) => doSomething(a);
}
expect_exact: "var foo=(a=0)=>doSomething(a);"
}
arrow_binding_pattern: {
input: {
var foo = ([]) => "foo";
var bar = ({}) => "bar";
var with_default = (foo = "default") => foo;
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
var array_after_spread = (...[foo]) => foo;
var array_after_spread = (...{foo}) => foo;
var computed = ({ [compute()]: x }) => {};
var array_hole = ([, , ...x] = [1, 2]) => {};
var object_trailing_elision = ({foo,}) => {};
var spread_empty_array = (...[]) => "foo";
var spread_empty_object = (...{}) => "foo";
}
expect: {
var foo = ([]) => "foo";
var bar = ({}) => "bar";
var with_default = (foo = "default") => foo;
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
var array_after_spread = (...[foo]) => foo;
var array_after_spread = (...{foo}) => foo;
var computed = ({ [compute()]: x }) => {};
var array_hole = ([, , ...x] = [1, 2]) => {};
var object_trailing_elision = ({foo,}) => {};
var spread_empty_array = (...[]) => "foo";
var spread_empty_object = (...{}) => "foo";
}
}
arrow_binding_pattern_strict: {
input: {
var foo = ([,]) => "foo";
}
expect_exact: 'var foo=([,])=>"foo";'
}
arrow_with_regexp: {
input: {
num => /\d{11,14}/.test( num )
}
expect: {
num => /\d{11,14}/.test( num )
}
}

File diff suppressed because it is too large Load Diff

35
test/compress/ascii.js Normal file
View File

@@ -0,0 +1,35 @@
ascii_only_true: {
options = {}
beautify = {
ascii_only : true,
ie8 : false,
beautify : false,
}
input: {
function f() {
return "\x000\x001\x007\x008\x00" +
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
}
}
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
}
ascii_only_false: {
options = {}
beautify = {
ascii_only : false,
ie8 : false,
beautify : false,
}
input: {
function f() {
return "\x000\x001\x007\x008\x00" +
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
}
}
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
}

View File

@@ -1,25 +1,25 @@
asm_mixed: {
options = {
assignments: true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
drop_debugger: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_fnames: false,
loops: true,
negate_iife: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
sequences : true,
properties : true,
dead_code : true,
drop_debugger : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
loops : true,
unused : true,
hoist_funs : true,
keep_fargs : true,
keep_fnames : false,
hoist_vars : true,
if_return : true,
join_vars : true,
cascade : true,
side_effects : true,
negate_iife : true
};
input: {
// adapted from http://asmjs.org/spec/latest/
function asm_GeometricMean(stdlib, foreign, buffer) {
@@ -76,8 +76,9 @@ asm_mixed: {
start = start | 0;
end = end | 0;
var sum = 0.0, p = 0, q = 0;
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0)
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0) {
sum = sum + +log(values[p >> 3]);
}
return +sum;
}
function geometricMean(start, end) {
@@ -90,12 +91,12 @@ asm_mixed: {
function no_asm_GeometricMean(stdlib, foreign, buffer) {
function logSum(start, end) {
start |= 0, end |= 0;
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0)
sum += +log(values[p >> 3]);
var sum = 0, p = 0, q = 0;
for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
return +sum;
}
function geometricMean(start, end) {
return start |= 0, end |= 0, +exp(+logSum(start, end) / (end - start | 0));
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
}
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
return { geometricMean: geometricMean };
@@ -103,131 +104,3 @@ asm_mixed: {
}
}
asm_toplevel: {
options = {}
input: {
"use asm";
0.0;
function f() {
0.0;
(function(){
0.0;
});
}
0.0;
}
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
}
asm_function_expression: {
options = {}
input: {
0.0;
var a = function() {
"use asm";
0.0;
}
function f() {
0.0;
return function(){
"use asm";
0.0;
}
0.0;
}
0.0;
}
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
}
asm_nested_functions: {
options = {}
input: {
0.0;
function a() {
"use asm";
0.0;
}
0.0;
function b() {
0.0;
function c(){
"use asm";
0.0;
}
0.0;
function d(){
0.0;
}
0.0;
}
0.0;
}
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
}
issue_3636_1: {
mangle = {}
input: {
function n(stdlib, foreign, buffer) {
"use asm";
function add(x, y) {
x = x | 0;
y = y | 0;
return x + y | 0;
}
return {
add: add
};
}
console.log(new n().add("foo", 42));
}
expect: {
function n(o, e, u) {
"use asm";
function d(n, o) {
n = n | 0;
o = o | 0;
return n + o | 0;
}
return {
add: d
};
}
console.log(new n().add("foo", 42));
}
expect_stdout: "42"
}
issue_3636_2: {
mangle = {}
input: {
var n = function(stdlib, foreign, buffer) {
"use asm";
function add(x, y) {
x = x | 0;
y = y | 0;
return x + y | 0;
}
return {
add: add
};
};
console.log(new n().add("foo", 42));
}
expect: {
var n = function(n, o, e) {
"use asm";
function r(n, o) {
n = n | 0;
o = o | 0;
return n + o | 0;
}
return {
add: r
};
};
console.log(new n().add("foo", 42));
}
expect_stdout: "42"
}

238
test/compress/assignment.js Normal file
View File

@@ -0,0 +1,238 @@
op_equals_left_local_var: {
options = {
evaluate: true,
}
input: {
var x;
x = x + 3;
x = x - 3;
x = x / 3;
x = x * 3;
x = x >> 3;
x = x << 3;
x = x >>> 3;
x = x | 3;
x = x ^ 3;
x = x % 3;
x = x & 3;
x = x + g();
x = x - g();
x = x / g();
x = x * g();
x = x >> g();
x = x << g();
x = x >>> g();
x = x | g();
x = x ^ g();
x = x % g();
x = x & g();
}
expect: {
var x;
x += 3;
x -= 3;
x /= 3;
x *= 3;
x >>= 3;
x <<= 3;
x >>>= 3;
x |= 3;
x ^= 3;
x %= 3;
x &= 3;
x += g();
x -= g();
x /= g();
x *= g();
x >>= g();
x <<= g();
x >>>= g();
x |= g();
x ^= g();
x %= g();
x &= g();
}
}
op_equals_right_local_var: {
options = {
evaluate: true,
}
input: {
var x;
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x = 3 * x;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x = 3 | x;
x = 3 ^ x;
x = 3 % x;
x = 3 & x;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
expect: {
var x;
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x *= 3;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x |= 3;
x ^= 3;
x = 3 % x;
x &= 3;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
}
op_equals_left_global_var: {
options = {
evaluate: true,
}
input: {
x = x + 3;
x = x - 3;
x = x / 3;
x = x * 3;
x = x >> 3;
x = x << 3;
x = x >>> 3;
x = x | 3;
x = x ^ 3;
x = x % 3;
x = x & 3;
x = x + g();
x = x - g();
x = x / g();
x = x * g();
x = x >> g();
x = x << g();
x = x >>> g();
x = x | g();
x = x ^ g();
x = x % g();
x = x & g();
}
expect: {
x += 3;
x -= 3;
x /= 3;
x *= 3;
x >>= 3;
x <<= 3;
x >>>= 3;
x |= 3;
x ^= 3;
x %= 3;
x &= 3;
x += g();
x -= g();
x /= g();
x *= g();
x >>= g();
x <<= g();
x >>>= g();
x |= g();
x ^= g();
x %= g();
x &= g();
}
}
op_equals_right_global_var: {
options = {
evaluate: true,
}
input: {
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x = 3 * x;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x = 3 | x;
x = 3 ^ x;
x = 3 % x;
x = 3 & x;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
expect: {
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x *= 3;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x |= 3;
x ^= 3;
x = 3 % x;
x &= 3;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
}

View File

@@ -1,805 +0,0 @@
op_equals_left_local_var: {
options = {
assignments: true,
evaluate: true,
}
input: {
var x;
x = x + 3;
x = x - 3;
x = x / 3;
x = x * 3;
x = x >> 3;
x = x << 3;
x = x >>> 3;
x = x | 3;
x = x ^ 3;
x = x % 3;
x = x & 3;
x = x + g();
x = x - g();
x = x / g();
x = x * g();
x = x >> g();
x = x << g();
x = x >>> g();
x = x | g();
x = x ^ g();
x = x % g();
x = x & g();
}
expect: {
var x;
x += 3;
x -= 3;
x /= 3;
x *= 3;
x >>= 3;
x <<= 3;
x >>>= 3;
x |= 3;
x ^= 3;
x %= 3;
x &= 3;
x += g();
x -= g();
x /= g();
x *= g();
x >>= g();
x <<= g();
x >>>= g();
x |= g();
x ^= g();
x %= g();
x &= g();
}
}
op_equals_right_local_var: {
options = {
assignments: true,
evaluate: true,
}
input: {
var x;
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x = 3 * x;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x = 3 | x;
x = 3 ^ x;
x = 3 % x;
x = 3 & x;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
expect: {
var x;
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x *= 3;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x |= 3;
x ^= 3;
x = 3 % x;
x &= 3;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
}
op_equals_left_global_var: {
options = {
assignments: true,
evaluate: true,
}
input: {
x = x + 3;
x = x - 3;
x = x / 3;
x = x * 3;
x = x >> 3;
x = x << 3;
x = x >>> 3;
x = x | 3;
x = x ^ 3;
x = x % 3;
x = x & 3;
x = x + g();
x = x - g();
x = x / g();
x = x * g();
x = x >> g();
x = x << g();
x = x >>> g();
x = x | g();
x = x ^ g();
x = x % g();
x = x & g();
}
expect: {
x += 3;
x -= 3;
x /= 3;
x *= 3;
x >>= 3;
x <<= 3;
x >>>= 3;
x |= 3;
x ^= 3;
x %= 3;
x &= 3;
x += g();
x -= g();
x /= g();
x *= g();
x >>= g();
x <<= g();
x >>>= g();
x |= g();
x ^= g();
x %= g();
x &= g();
}
}
op_equals_right_global_var: {
options = {
assignments: true,
evaluate: true,
}
input: {
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x = 3 * x;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x = 3 | x;
x = 3 ^ x;
x = 3 % x;
x = 3 & x;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
expect: {
x = (x -= 2) ^ x;
x = 3 + x;
x = 3 - x;
x = 3 / x;
x *= 3;
x = 3 >> x;
x = 3 << x;
x = 3 >>> x;
x |= 3;
x ^= 3;
x = 3 % x;
x &= 3;
x = g() + x;
x = g() - x;
x = g() / x;
x = g() * x;
x = g() >> x;
x = g() << x;
x = g() >>> x;
x = g() | x;
x = g() ^ x;
x = g() % x;
x = g() & x;
}
}
increment_decrement_1: {
options = {
assignments: true,
reduce_vars: true,
}
input: {
console.log(function(a) {
a += 1;
a -= 1;
return a;
}(42));
}
expect: {
console.log(function(a){
++a;
--a;
return a;
}(42));
}
expect_stdout: "42"
}
increment_decrement_2: {
options = {
assignments: true,
passes: 2,
reduce_vars: true,
}
input: {
console.log(function(a) {
a = a + 1;
a = a - 1;
a += 1;
a -= 1;
return a;
}(42));
}
expect: {
console.log(function(a){
++a;
--a;
++a;
--a;
return a;
}(42));
}
expect_stdout: "42"
}
issue_3375_1: {
options = {
assignments: true,
reduce_vars: true,
}
input: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b += 1;
--b;
return a;
}("object"));
}
expect: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b += 1;
--b;
return a;
}("object"));
}
expect_stdout: "string object1"
}
issue_3375_2: {
options = {
assignments: true,
reduce_vars: true,
}
input: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b -= 1;
--b;
return a;
}("object"));
}
expect: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = --b;
--b;
return a;
}("object"));
}
expect_stdout: "number NaN"
}
issue_3427: {
options = {
assignments: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
(function() {
var a;
a || (a = {});
})();
}
expect: {}
}
issue_3429_1: {
options = {
assignments: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function(b) {
b && (b = a = "FAIL");
})();
console.log(a);
}
expect: {
var a = "PASS";
(function(b) {
b = b && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "PASS"
}
issue_3429_2: {
options = {
assignments: true,
side_effects: true,
unused: true,
}
input: {
var a;
(function(b) {
b || (b = a = "FAIL");
})(42);
console.log(a);
}
expect: {
var a;
(function(b) {
b = b || (a = "FAIL");
})(42);
console.log(a);
}
expect_stdout: "undefined"
}
issue_3949_1: {
options = {
assignments: true,
evaluate: true,
reduce_vars: true,
}
input: {
var a = 42;
function f() {
var b = a;
b = b >> 2;
return 100 + b;
}
console.log(f());
}
expect: {
var a = 42;
function f() {
var b = a;
b >>= 2;
return 100 + b;
}
console.log(f());
}
expect_stdout: "110"
}
issue_3949_2: {
options = {
assignments: true,
evaluate: true,
reduce_vars: true,
}
input: {
var a = 42;
function f() {
var b = a;
b = 5 & b;
return 100 + b;
}
console.log(f());
}
expect: {
var a = 42;
function f() {
var b = a;
b &= 5;
return 100 + b;
}
console.log(f());
}
expect_stdout: "100"
}
issue_4521: {
options = {
assignments: true,
dead_code: true,
}
input: {
var a = (a = 42 | a) ? console.log(a) : 0;
}
expect: {
var a = (a |= 42) ? console.log(a) : 0;
}
expect_stdout: "42"
}
logical_assignments: {
input: {
var a = 42, b = null, c;
a &&= "foo";
b ||= "bar";
c ??= "baz";
console.log(a, b, c);
}
expect_exact: 'var a=42,b=null,c;a&&="foo";b||="bar";c??="baz";console.log(a,b,c);'
expect_stdout: "foo bar baz"
node_version: ">=15"
}
logical_collapse_vars_1: {
options = {
collapse_vars: true,
}
input: {
var a = "FAIL", b = false;
a = "PASS";
b ??= a;
console.log(a);
}
expect: {
var a = "FAIL", b = false;
a = "PASS";
b ??= a;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_collapse_vars_2: {
options = {
collapse_vars: true,
}
input: {
var a = "PASS";
(function(b) {
b ||= (a = "FAIL", {});
return b;
})(console).log(a);
}
expect: {
var a = "PASS";
(function(b) {
return b ||= (a = "FAIL", {});
})(console).log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_collapse_vars_3: {
options = {
collapse_vars: true,
}
input: {
var a = 6;
a *= 7;
a ??= "FAIL";
console.log(a);
}
expect: {
var a = 6;
a = a * 7 ?? "FAIL";
console.log(a);
}
expect_stdout: "42"
node_version: ">=15"
}
logical_reduce_vars: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_side_effects: {
options = {
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
evaluate_lazy_assignment: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 42;
console.log(a &&= "PASS");
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4815_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4815_2: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4819: {
options = {
comparisons: true,
}
input: {
console.log(void 0 === ([].p &&= 42));
}
expect: {
console.log(void 0 === ([].p &&= 42));
}
expect_stdout: "true"
node_version: ">=15"
}
issue_4827_1: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
A = "FAIL";
var a = A, b = "PASS", c;
c &&= b = a, console.log(b);
}
expect: {
var a = A = "FAIL", b = "PASS", c;
c &&= b = a, console.log(b);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4827_2: {
options = {
collapse_vars: true,
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0, b = "PASS";
function f(c) {
a++,
c &&= b = a;
}
f();
console.log(b);
}
expect: {
var a = 0, b = "PASS";
a++,
c &&= b = a;
var c;
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4827_3: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a = 0, b, c;
a++;
c &&= b = a;
console.log(b);
}
expect: {
var a = 0, b, c;
a++;
c &&= b = a;
console.log(b);
}
expect_stdout: "undefined"
node_version: ">=15"
}
issue_4876: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
try {
var a = null;
var b = a &&= 42;
b.p;
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
var a = null;
var b = a &&= 42;
b.p;
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4924_1: {
options = {
collapse_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b;
console.log("PASS");
a = function() {};
b = function() {}(b ||= a);
}
expect: {
var b;
console.log("PASS");
b = void (b ||= function() {});
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4924_2: {
options = {
collapse_vars: true,
dead_code: true,
passes: 2,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b;
console.log("PASS");
a = function() {};
b = function() {}(b ||= a);
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=15"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,92 +0,0 @@
arithmetic: {
input: {
console.log(((1n + 0x2n) * (0o3n - -4n)) >> (5n - 6n));
}
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
expect_stdout: "42n"
node_version: ">=10.4.0"
}
minus_dot: {
input: {
console.log(typeof -42n.toString(), typeof (-42n).toString());
}
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
expect_stdout: "number string"
node_version: ">=10.4.0"
}
evaluate: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log((0xDEAD_BEEFn).toString(16));
}
expect: {
console.log(0xdeadbeefn.toString(16));
}
expect_stdout: "deadbeef"
node_version: ">=10.4.0"
}
Number: {
options = {
unsafe: true,
}
input: {
console.log(Number(-0xfeed_dead_beef_badn));
}
expect: {
console.log(+("" + -0xfeed_dead_beef_badn));
}
expect_stdout: "-1148098955808013200"
node_version: ">=10.4.0"
}
issue_4590: {
options = {
collapse_vars: true,
}
input: {
A = 1;
0n || console.log("PASS");
}
expect: {
A = 1;
0n || console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=10.4.0"
}
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.4.0"
}

View File

@@ -0,0 +1,177 @@
let_statement: {
input: {
let x = 6;
}
expect_exact: "let x=6;"
}
do_not_hoist_let: {
options = {
hoist_vars: true,
};
input: {
function x() {
if (FOO) {
let let1;
let let2;
var var1;
var var2;
}
}
}
expect: {
function x() {
var var1, var2;
if (FOO) {
let let1;
let let2;
}
}
}
}
do_not_remove_anon_blocks_if_they_have_decls: {
input: {
function x() {
{
let x;
}
{
var x;
}
{
const y;
class Zee {};
}
}
{
let y;
}
{
var y;
}
}
expect: {
function x(){
{
let x
}
var x;
{
const y;
class Zee {}
}
}
{
let y
}
var y;
}
}
remove_unused_in_global_block: {
options = {
unused: true,
}
input: {
{
let x;
const y;
class Zee {};
var w;
}
let ex;
const why;
class Zed {};
var wut;
console.log(x, y, Zee);
}
expect: {
var w;
let ex;
const why;
class Zed {};
var wut;
console.log(x, y, Zee);
}
}
regression_block_scope_resolves: {
mangle = { };
options = {
dead_code: false
};
input: {
(function () {
if(1) {
let x;
const y;
class Zee {};
}
if(1) {
let ex;
const why;
class Zi {};
}
console.log(x, y, Zee, ex, why, Zi);
}());
}
expect: {
(function () {
if (1) {
let o;
const n;
class c {};
}
if (1) {
let o;
const n;
class c {};
}
console.log(x, y, Zee, ex, why, Zi);
}());
}
}
switch_block_scope_mangler: {
mangle = {}
input: {
var fn = function(code) {
switch (code) {
case 1:
let apple = code + 1;
let dog = code + 4;
console.log(apple, dog);
break;
case 2:
let banana = code + 2;
console.log(banana);
break;
default:
let cat = code + 3;
console.log(cat);
}
};
}
expect: {
var fn = function(o) {
switch (o) {
case 1:
let e = o + 1
let c = o + 4;
console.log(e, c);
break;
case 2:
let l = o + 2;
console.log(l);
break;
default:
let a = o + 3;
console.log(a);
}
};
}
}

View File

@@ -1,764 +0,0 @@
iife_boolean_context: {
options = {
booleans: true,
evaluate: true,
}
input: {
console.log(function() {
return Object(1) || false;
}() ? "PASS" : "FAIL");
console.log(function() {
return [].length || true;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function() {
return Object(1);
}() ? "PASS" : "FAIL");
console.log(function() {
return [].length, 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: [
"PASS",
"PASS",
]
expect_warnings: [
"WARN: Dropping side-effect-free || [test/compress/booleans.js:2,19]",
"WARN: Boolean || always true [test/compress/booleans.js:5,19]",
]
}
de_morgan_1a: {
options = {
booleans: true,
}
input: {
function f(a) {
return a || a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a;
}
console.log(f(null), f(42));
}
expect_stdout: "null 42"
}
de_morgan_1b: {
options = {
booleans: true,
}
input: {
function f(a) {
return a && a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a;
}
console.log(f(null), f(42));
}
expect_stdout: "null 42"
}
de_morgan_1c: {
options = {
booleans: true,
}
input: {
console.log(delete (NaN && NaN));
}
expect: {
console.log(delete (0, NaN));
}
expect_stdout: "true"
}
de_morgan_2a: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b) {
return a || (a || b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a || b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"undefined {}",
"42 42",
]
}
de_morgan_2b: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a || (a && b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
}
de_morgan_2c: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a && (a || b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
}
de_morgan_2d: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b) {
return a && (a && b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a && b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"undefined {}",
]
}
de_morgan_3a: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b, c) {
return a || ((a || b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || b || c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"undefined {} true true",
"42 42 42 42",
]
}
de_morgan_3b: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a || ((a || b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || b && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"false false undefined {}",
"42 42 42 42",
]
}
de_morgan_3c: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a || ((a && b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"undefined {} undefined {}",
"42 42 42 42",
]
}
de_morgan_3d: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b, c) {
return a || ((a && b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"42 42 42 42",
]
}
de_morgan_3e: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b, c) {
return a && ((a || b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"42 42 42 42",
]
}
de_morgan_3f: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a && ((a || b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"undefined {} undefined {}",
]
}
de_morgan_3g: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a && ((a && b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && (b || c);
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"undefined {} true true",
]
}
de_morgan_3h: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b, c) {
return a && ((a && b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && b && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"false false undefined {}",
]
}
conditional_chain: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
}
input: {
function f(a, b) {
return a ? a : b ? b : 42;
}
console.log(f("PASS", "FAIL"));
}
expect: {
function f(a, b) {
return a || b || 42;
}
console.log(f("PASS", "FAIL"));
}
expect_stdout: "PASS"
}
negated_if: {
options = {
booleans: true,
conditionals: true,
side_effects: true,
}
input: {
console.log(function(a) {
if (!a)
return a ? "FAIL" : "PASS";
}(!console));
}
expect: {
console.log(function(a) {
if (!a)
return "PASS";
}(!console));
}
expect_stdout: "PASS"
}
concat_truthy: {
options = {
booleans: true,
evaluate: true,
}
input: {
console.log("foo") + (console.log("bar"), "baz") || console.log("moo");
}
expect: {
console.log("foo") + (console.log("bar"), "baz");
}
expect_stdout: [
"foo",
"bar",
]
expect_warnings: [
"WARN: + in boolean context always true [test/compress/booleans.js:1,8]",
"WARN: Condition left of || always true [test/compress/booleans.js:1,8]",
]
}
process_returns: {
options = {
booleans: true,
}
input: {
(function() {
return 42;
})() && console.log("PASS");
}
expect: {
(function() {
return 42;
})() && console.log("PASS");
}
expect_stdout: "PASS"
}
issue_3465_1: {
options = {
booleans: true,
}
input: {
console.log(function(a) {
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
return 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_3465_2: {
options = {
booleans: true,
}
input: {
console.log(function f(a) {
if (!a) console.log(f(42));
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function f(a) {
if (!a) console.log(f(42));
return typeof a;
}() ? "PASS" : "FAIL");
}
expect_stdout: [
"number",
"PASS",
]
}
issue_3465_3: {
options = {
booleans: true,
passes: 2,
unused: true,
}
input: {
console.log(function f(a) {
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
return 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_2737_2: {
options = {
booleans: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function(bar) {
for (;bar();) break;
})(function qux() {
return console.log("PASS"), qux;
});
}
expect: {
(function(bar) {
for (;bar();) break;
})(function() {
return console.log("PASS"), 1;
});
}
expect_stdout: "PASS"
}
issue_3658: {
options = {
booleans: true,
evaluate: true,
reduce_vars: true,
}
input: {
console.log(function f() {
console || f();
return "PASS";
}());
}
expect: {
console.log(function f() {
console || f();
return "PASS";
}());
}
expect_stdout: "PASS"
}
issue_3690: {
options = {
booleans: true,
unused: true,
}
input: {
console.log(function(a) {
return function() {
return a = [ this ];
}() ? "PASS" : "FAIL";
}());
}
expect: {
console.log(function(a) {
return function() {
return 1;
}() ? "PASS" : "FAIL";
}());
}
expect_stdout: "PASS"
}
issue_4374: {
options = {
booleans: true,
conditionals: true,
if_return: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
console.log(f());
function f(a) {
if (null) return 0;
if (a) return 1;
return 0;
}
})();
}
expect: {
(function() {
console.log(function(a) {
return !null && a ? 1 : 0;
}());
})();
}
expect_stdout: "0"
}
issue_5028_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect_stdout: "PASS"
}
issue_5028_2: {
options = {
booleans: true,
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5028_3: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5041_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 42;
if (a)
if ([ a = null ])
if (a)
console.log("FAIL");
else
console.log("PASS");
}
expect: {
var a = 42;
a && [ a = null ] && (a ? console.log("FAIL") : console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_5041_2: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a;
if (!a)
if (a = 42)
if (a)
console.log("PASS");
else
console.log("FAIL");
}
expect: {
var a;
a || (a = 42) && (a ? console.log("PASS") : console.log("FAIL"));
}
expect_stdout: "PASS"
}
issue_5228: {
options = {
booleans: true,
evaluate: true,
inline: true,
passes: 2,
}
input: {
console.log(function() {
return !function() {
do {
return null;
} while (console);
}();
}());
}
expect: {
console.log(function() {
do {
return !0;
} while (console);
return !0;
}());
}
expect_stdout: "true"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
keep_comparisons: {
options = {
comparisons: true,
unsafe_comps: false
}
input: {
var obj1 = {
valueOf: function() {triggeredFirst();}
}
var obj2 = {
valueOf: function() {triggeredSecond();}
}
var result1 = obj1 <= obj2;
var result2 = obj1 < obj2;
var result3 = obj1 >= obj2;
var result4 = obj1 > obj2;
}
expect: {
var obj1 = {
valueOf: function() {triggeredFirst();}
}
var obj2 = {
valueOf: function() {triggeredSecond();}
}
var result1 = obj1 <= obj2;
var result2 = obj1 < obj2;
var result3 = obj1 >= obj2;
var result4 = obj1 > obj2;
}
}
keep_comparisons_with_unsafe_comps: {
options = {
comparisons: true,
unsafe_comps: true
}
input: {
var obj1 = {
valueOf: function() {triggeredFirst();}
}
var obj2 = {
valueOf: function() {triggeredSecond();}
}
var result1 = obj1 <= obj2;
var result2 = obj1 < obj2;
var result3 = obj1 >= obj2;
var result4 = obj1 > obj2;
}
expect: {
var obj1 = {
valueOf: function() {triggeredFirst();}
}
var obj2 = {
valueOf: function() {triggeredSecond();}
}
var result1 = obj2 >= obj1;
var result2 = obj2 > obj1;
var result3 = obj1 >= obj2;
var result4 = obj1 > obj2;
}
}
dont_change_in_or_instanceof_expressions: {
input: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
expect: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
}

View File

@@ -1,524 +0,0 @@
comparisons: {
options = {
comparisons: true,
}
input: {
var obj1, obj2;
var result1 = obj1 <= obj2;
var result2 = obj1 < obj2;
var result3 = obj1 >= obj2;
var result4 = obj1 > obj2;
}
expect: {
var obj1, obj2;
var result1 = obj1 <= obj2;
var result2 = obj1 < obj2;
var result3 = obj2 <= obj1;
var result4 = obj2 < obj1;
}
}
unsafe_comps: {
options = {
comparisons: true,
conditionals: true,
unsafe_comps: true,
}
input: {
var obj1, obj2;
obj1 <= obj2 ? f1() : g1();
obj1 < obj2 ? f2() : g2();
obj1 >= obj2 ? f3() : g3();
obj1 > obj2 ? f4() : g4();
}
expect: {
var obj1, obj2;
(obj2 < obj1 ? g1 : f1)();
(obj1 < obj2 ? f2 : g2)();
(obj1 < obj2 ? g3 : f3)();
(obj2 < obj1 ? f4 : g4)();
}
}
dont_change_in_or_instanceof_expressions: {
input: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
expect: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
}
self_comparison_1: {
options = {
comparisons: true,
}
input: {
a === a;
a !== b;
b.c === a.c;
b.c !== b.c;
}
expect: {
a == a;
a !== b;
b.c === a.c;
b.c != b.c;
}
}
self_comparison_2: {
options = {
comparisons: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
}
input: {
function f() {}
var o = {};
console.log(f != f, o === o);
}
expect: {
function f() {}
var o = {};
console.log(false, true);
}
expect_stdout: "false true"
}
self_comparison_3: {
options = {
comparisons: true,
}
input: {
var a;
function f() {
var b = a;
a = null;
return b;
}
for (var i = 0; i < 2; i++)
console.log(f() === f());
}
expect: {
var a;
function f() {
var b = a;
a = null;
return b;
}
for (var i = 0; i < 2; i++)
console.log(f() === f());
}
expect_stdout: [
"false",
"true",
]
}
self_comparison_4: {
options = {
booleans: true,
comparisons: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var o = {};
console.log(o == o, o != o);
console.log(o === o, o !== o);
}
expect: {
console.log(!0, !1);
console.log(!0, !1);
}
expect_stdout: [
"true false",
"true false",
]
}
issue_2857_1: {
options = {
comparisons: true,
}
input: {
function f1(a) {
a === undefined || a === null;
a === undefined || a !== null;
a !== undefined || a === null;
a !== undefined || a !== null;
a === undefined && a === null;
a === undefined && a !== null;
a !== undefined && a === null;
a !== undefined && a !== null;
}
function f2(a) {
a === null || a === undefined;
a === null || a !== undefined;
a !== null || a === undefined;
a !== null || a !== undefined;
a === null && a === undefined;
a === null && a !== undefined;
a !== null && a === undefined;
a !== null && a !== undefined;
}
}
expect: {
function f1(a) {
null == a;
void 0 === a || null !== a;
void 0 !== a || null === a;
void 0 !== a || null !== a;
void 0 === a && null === a;
void 0 === a && null !== a;
void 0 !== a && null === a;
null != a;
}
function f2(a) {
null == a;
null === a || void 0 !== a;
null !== a || void 0 === a;
null !== a || void 0 !== a;
null === a && void 0 === a;
null === a && void 0 !== a;
null !== a && void 0 === a;
null != a;
}
}
}
issue_2857_2: {
options = {
comparisons: true,
}
input: {
function f(a, p) {
a === undefined || a === null || p;
a === undefined || a !== null || p;
a !== undefined || a === null || p;
a !== undefined || a !== null || p;
a === undefined && a === null || p;
a === undefined && a !== null || p;
a !== undefined && a === null || p;
a !== undefined && a !== null || p;
}
}
expect: {
function f(a, p) {
null == a || p;
void 0 === a || null !== a || p;
void 0 !== a || null === a || p;
void 0 !== a || null !== a || p;
void 0 === a && null === a || p;
void 0 === a && null !== a || p;
void 0 !== a && null === a || p;
null != a || p;
}
}
}
issue_2857_3: {
options = {
comparisons: true,
}
input: {
function f(a, p) {
a === undefined || a === null && p;
a === undefined || a !== null && p;
a !== undefined || a === null && p;
a !== undefined || a !== null && p;
a === undefined && a === null && p;
a === undefined && a !== null && p;
a !== undefined && a === null && p;
a !== undefined && a !== null && p;
}
}
expect: {
function f(a, p) {
void 0 === a || null === a && p;
void 0 === a || null !== a && p;
void 0 !== a || null === a && p;
void 0 !== a || null !== a && p;
void 0 === a && null === a && p;
void 0 === a && null !== a && p;
void 0 !== a && null === a && p;
null != a && p;
}
}
}
issue_2857_4: {
options = {
comparisons: true,
}
input: {
function f(a, p) {
p || a === undefined || a === null;
p || a === undefined || a !== null;
p || a !== undefined || a === null;
p || a !== undefined || a !== null;
p || a === undefined && a === null;
p || a === undefined && a !== null;
p || a !== undefined && a === null;
p || a !== undefined && a !== null;
}
}
expect: {
function f(a, p) {
p || null == a;
p || void 0 === a || null !== a;
p || void 0 !== a || null === a;
p || void 0 !== a || null !== a;
p || void 0 === a && null === a;
p || void 0 === a && null !== a;
p || void 0 !== a && null === a;
p || null != a;
}
}
}
issue_2857_5: {
options = {
comparisons: true,
}
input: {
function f(a, p) {
p && a === undefined || a === null;
p && a === undefined || a !== null;
p && a !== undefined || a === null;
p && a !== undefined || a !== null;
p && a === undefined && a === null;
p && a === undefined && a !== null;
p && a !== undefined && a === null;
p && a !== undefined && a !== null;
}
}
expect: {
function f(a, p) {
p && void 0 === a || null === a;
p && void 0 === a || null !== a;
p && void 0 !== a || null === a;
p && void 0 !== a || null !== a;
p && void 0 === a && null === a;
p && void 0 === a && null !== a;
p && void 0 !== a && null === a;
p && null != a;
}
}
}
issue_2857_6: {
options = {
comparisons: true,
pure_getters: "strict",
reduce_vars: true,
}
input: {
function f(a) {
if (({}).b === undefined || {}.b === null)
return a.b !== undefined && a.b !== null;
}
console.log(f({
a: [ null ],
get b() {
return this.a.shift();
}
}));
}
expect: {
function f(a) {
if (null == {}.b)
return void 0 !== a.b && null !== a.b;
}
console.log(f({
a: [ null ],
get b() {
return this.a.shift();
}
}));
}
expect_stdout: "true"
}
is_boolean_unsafe: {
options = {
comparisons: true,
unsafe: true,
}
input: {
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
}
expect: {
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
}
expect_stdout: "true"
}
is_number_unsafe: {
options = {
comparisons: true,
unsafe: true,
}
input: {
console.log(Math.acos(42) !== "foo".charCodeAt(4));
}
expect: {
console.log(Math.acos(42) != "foo".charCodeAt(4));
}
expect_stdout: "true"
}
is_boolean_var: {
options = {
comparisons: true,
reduce_vars: true,
}
input: {
console.log(function(a, b) {
for (var i = 0, c = !b; i < a.length; i++)
if (!a[i] === c)
return i;
}([ false, true ], 42));
}
expect: {
console.log(function(a, b) {
for (var i = 0, c = !b; i < a.length; i++)
if (!a[i] == c)
return i;
}([ false, true ], 42));
}
expect_stdout: "1"
}
is_defined: {
options = {
comparisons: true,
}
input: {
console.log(function a() {
return void 0 === a;
}());
}
expect: {
console.log(function a() {
return a, false;
}());
}
expect_stdout: "false"
expect_warnings: [
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
]
}
unsafe_indexOf: {
options = {
booleans: true,
comparisons: true,
unsafe: true,
}
input: {
var a = Object.keys({ foo: 42 });
if (a.indexOf("bar") < 0) console.log("PASS");
if (0 > a.indexOf("bar")) console.log("PASS");
if (a.indexOf("foo") >= 0) console.log("PASS");
if (0 <= a.indexOf("foo")) console.log("PASS");
if (a.indexOf("foo") > -1) console.log("PASS");
if (-1 < a.indexOf("foo")) console.log("PASS");
if (a.indexOf("bar") == -1) console.log("PASS");
if (-1 == a.indexOf("bar")) console.log("PASS");
if (a.indexOf("bar") === -1) console.log("PASS");
if (-1 === a.indexOf("bar")) console.log("PASS");
if (a.indexOf("foo") != -1) console.log("PASS");
if (-1 != a.indexOf("foo")) console.log("PASS");
if (a.indexOf("foo") !== -1) console.log("PASS");
if (-1 !== a.indexOf("foo")) console.log("PASS");
}
expect: {
var a = Object.keys({ foo: 42 });
if (!~a.indexOf("bar")) console.log("PASS");
if (!~a.indexOf("bar")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (!~a.indexOf("bar")) console.log("PASS");
if (!~a.indexOf("bar")) console.log("PASS");
if (!~a.indexOf("bar")) console.log("PASS");
if (!~a.indexOf("bar")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
if (~a.indexOf("foo")) console.log("PASS");
}
expect_stdout: [
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
"PASS",
]
}
issue_3413: {
options = {
comparisons: true,
evaluate: true,
side_effects: true,
}
input: {
var b;
void 0 !== ("" < b || void 0) || console.log("PASS");
}
expect: {
var b;
void 0 === ("" < b || void 0) && console.log("PASS");
}
expect_stdout: "PASS"
}
nullish_assign: {
options = {
comparisons: true,
}
input: {
var a;
void 0 !== (a = "PASS".split("")) && null !== a && console.log(a.join("-"));
}
expect: {
var a;
null != (a = "PASS".split("")) && console.log(a.join("-"));
}
expect_stdout: "P-A-S-S"
}
nullish_chain: {
options = {
comparisons: true,
}
input: {
var a;
A || B || void 0 === a || null === a || C;
}
expect: {
var a;
A || B || null == a || C;
}
}

View File

@@ -1,7 +1,7 @@
concat_1: {
options = {
evaluate: true,
}
evaluate: true
};
input: {
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
var b = "foo" + 1 + x() + 2 + "boo";
@@ -21,14 +21,12 @@ concat_1: {
var c = 1 + x() + 2 + "boo";
var d = 1 + x() + 2 + 3 + "boo";
var e = 1 + x() + 2 + "X3boo";
var f = "\x00360\x008\0";
var f = "\x00360\08\0";
}
}
concat_2: {
options = {
strings: true,
}
options = {};
input: {
console.log(
1 + (2 + 3),
@@ -57,9 +55,7 @@ concat_2: {
}
concat_3: {
options = {
strings: true,
}
options = {};
input: {
console.log(
1 + 2 + (3 + 4 + 5),
@@ -88,9 +84,7 @@ concat_3: {
}
concat_4: {
options = {
strings: true,
}
options = {};
input: {
console.log(
1 + "2" + (3 + 4 + 5),
@@ -119,9 +113,7 @@ concat_4: {
}
concat_5: {
options = {
strings: true,
}
options = {};
input: {
console.log(
"1" + 2 + (3 + 4 + 5),
@@ -150,9 +142,7 @@ concat_5: {
}
concat_6: {
options = {
strings: true,
}
options = {};
input: {
console.log(
"1" + "2" + (3 + 4 + 5),
@@ -181,9 +171,6 @@ concat_6: {
}
concat_7: {
options = {
strings: true,
}
input: {
console.log(
"" + 1,
@@ -210,9 +197,6 @@ concat_7: {
}
concat_8: {
options = {
strings: true,
}
input: {
console.log(
1 + "",
@@ -237,70 +221,3 @@ concat_8: {
}
expect_stdout: true
}
concat_9: {
options = {
booleans: true,
evaluate: true,
reduce_vars: true,
strings: true,
toplevel: true,
}
input: {
var a = "foo";
console.log(
12 + (34 + a),
null + (34 + a),
12 + (null + a),
false + (34 + a),
12 + (false + a),
"bar" + (34 + a),
12 + ("bar" + a)
);
}
expect: {
var a = "foo";
console.log(
"1234" + a,
"null34" + a,
"12null" + a,
!1 + (34 + a),
12 + (!1 + a),
"bar34" + a,
"12bar" + a
);
}
expect_stdout: true
}
issue_3689: {
options = {
strings: true,
}
input: {
console.log(function(a) {
return a + ("" + (a[0] = 0));
}([]));
}
expect: {
console.log(function(a) {
return a + ("" + (a[0] = 0));
}([]));
}
expect_stdout: "00"
}
issue_5145: {
options = {
strings: true,
}
input: {
var a = [];
console.log("" + a + ((a[0] = 4) + "2"));
}
expect: {
var a = [];
console.log("" + a + (a[0] = 4) + "2");
}
expect_stdout: "42"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
keep_debugger: {
options = {
drop_debugger: false,
}
drop_debugger: false
};
input: {
debugger;
}
@@ -12,8 +12,8 @@ keep_debugger: {
drop_debugger: {
options = {
drop_debugger: true,
}
drop_debugger: true
};
input: {
debugger;
if (foo) debugger;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,332 @@
destructuring_arrays: {
input: {
{const [aa, bb] = cc;}
{const [aa, [bb, cc]] = dd;}
{let [aa, bb] = cc;}
{let [aa, [bb, cc]] = dd;}
var [aa, bb] = cc;
var [aa, [bb, cc]] = dd;
var [,[,,,,,],,,zz,] = xx; // Trailing comma
var [,,zzz,,] = xxx; // Trailing comma after hole
}
expect: {
{const [aa, bb] = cc;}
{const [aa, [bb, cc]] = dd;}
{let [aa, bb] = cc;}
{let [aa, [bb, cc]] = dd;}
var [aa, bb] = cc;
var [aa, [bb, cc]] = dd;
var [,[,,,,,],,,zz] = xx;
var [,,zzz,,] = xxx;
}
}
destructuring_arrays_holes: {
input: {
var [,,,,] = a;
var [,,b,] = c;
var [d,,] = e;
}
expect_exact: "var[,,,,]=a;var[,,b]=c;var[d,,]=e;"
}
destructuring_objects: {
input: {
{const {aa, bb} = {aa:1, bb:2};}
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
{let {aa, bb} = {aa:1, bb:2};}
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
var {aa, bb} = {aa:1, bb:2};
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
}
expect: {
{const {aa, bb} = {aa:1, bb:2};}
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
{let {aa, bb} = {aa:1, bb:2};}
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
var {aa, bb} = {aa:1, bb:2};
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
}
}
destructuring_objects_trailing_elision: {
beautify = {
ecma: 6
}
input: {
var {cc,} = foo;
}
expect_exact: "var{cc}=foo;"
}
nested_destructuring_objects: {
beautify = {
ecma: 6
}
input: {
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
}
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
}
destructuring_constdef_in_loops: {
beautify = {
ecma: 6
}
input: {
for (const [x,y] in pairs);
for (const [a] = 0;;);
for (const {c} of cees);
}
expect_exact: "for(const[x,y]in pairs);for(const[a]=0;;);for(const{c}of cees);"
}
destructuring_letdef_in_loops: {
beautify = {
ecma: 6
}
input: {
for (let [x,y] in pairs);
for (let [a] = 0;;);
for (let {c} of cees);
}
expect_exact: "for(let[x,y]in pairs);for(let[a]=0;;);for(let{c}of cees);"
}
destructuring_vardef_in_loops: {
beautify = {
ecma: 6
}
input: {
for (var [x,y] in pairs);
for (var [a] = 0;;);
for (var {c} of cees);
}
expect_exact: "for(var[x,y]in pairs);for(var[a]=0;;);for(var{c}of cees);"
}
destructuring_expressions: {
beautify = {
ecma: 6
}
input: {
({a, b});
[{a}];
f({x});
}
expect_exact: "({a,b});[{a}];f({x});"
}
destructuring_remove_unused_1: {
options = {
unused: true
}
input: {
function a() {
var unused = "foo";
var a = [1];
var [b] = a;
f(b);
}
function b() {
var unused = "foo";
var a = {b: 1};
var {b} = a;
f(b);
}
function c() {
var unused = "foo";
var a = [[1]];
var [[b]] = a;
f(b);
}
function d() {
var unused = "foo";
var a = {b: {b:1}};
var {b:{b}} = a;
f(b);
}
function e() {
var unused = "foo";
var a = [1, 2, 3, 4, 5];
var x = [[1, 2, 3]];
var y = {h: 1};
var [b, ...c] = a;
var [...[e, f]] = x;
var [...{g: h}] = y;
f(b, c, e, f, g);
}
}
expect: {
function a() {
var a = [1];
var [b] = a;
f(b);
}
function b() {
var a = {b: 1};
var {b} = a;
f(b);
}
function c() {
var a = [[1]];
var [[b]] = a;
f(b);
}
function d() {
var a = {b: {b:1}};
var {b:{b}} = a;
f(b);
}
function e() {
var a = [1, 2, 3, 4, 5];
var x = [[1, 2, 3]];
var y = {h: 1};
var [b, ...c] = a;
var [...[e, f]] = x;
var [...{g: h}] = y;
f(b, c, e, f, g);
}
}
}
destructuring_remove_unused_2: {
options = {
unused: true
}
input: {
function a() {
var unused = "foo";
var a = [,,1];
var [b] = a;
f(b);
}
function b() {
var unused = "foo";
var a = [{a: [1]}];
var [{b: a}] = a;
f(b);
}
}
expect: {
function a() {
var a = [,,1];
var [b] = a;
f(b);
}
function b() {
var a = [{a: [1]}];
var [{b: a}] = a;
f(b);
}
}
}
object_destructuring_may_need_parentheses: {
beautify = {
ecma: 6
}
input: {
({a, b} = {a: 1, b: 2});
}
expect_exact: "({a,b}={a:1,b:2});"
}
destructuring_with_undefined_as_default_assignment: {
options = {
evaluate: true
}
input: {
[foo = undefined] = bar;
[foo = void 0] = bar;
}
expect: {
[foo] = bar;
[foo] = bar;
}
}
destructuring_dont_evaluate_with_undefined_as_default_assignment: {
options = {
evaluate: false
}
input: {
[foo = undefined] = bar;
}
expect: {
[foo = void 0] = bar;
}
}
reduce_vars: {
options = {
reduce_vars: true,
}
input: {
{const [aa, [bb, cc]] = dd;}
{let [aa, [bb, cc]] = dd;}
var [aa, [bb, cc]] = dd;
[aa, [bb, cc]] = dd;
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
[{a},b] = c;
for (const [x,y] in pairs);
for (let [x,y] in pairs);
for (var [x,y] in pairs);
for ([x,y] in pairs);
}
expect: {
{const [aa, [bb, cc]] = dd;}
{let [aa, [bb, cc]] = dd;}
var [aa, [bb, cc]] = dd;
[aa, [bb, cc]] = dd;
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
[{a},b] = c;
for (const [x,y] in pairs);
for (let [x,y] in pairs);
for (var [x,y] in pairs);
for ([x,y] in pairs);
}
}
unused: {
options = {
unused: true,
}
input: {
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
console.log(a);
}
expect: {
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
console.log(a);
}
}
issue_1886: {
options = {
collapse_vars: true,
}
input: {
let [a] = [1];
console.log(a);
}
expect: {
let [a] = [1];
console.log(a);
}
expect_exact: "1"
}

View File

@@ -1,160 +1,10 @@
simple_statement_is_not_a_directive: {
class_directives_compression: {
input: {
"use strict"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
(function() {
"directive"
""
"use strict"
"hello world"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
})();
}
expect: {
"use strict".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
(function() {
"directive";
"";
"use strict";
"hello world".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
})();
}
expect_stdout: [
"use",
"strict",
"false",
"hello",
"world",
"true",
]
}
drop_lone_use_strict: {
options = {
directives: true,
unused: true,
}
input: {
function f1() {
"use strict";
}
function f2() {
"use strict";
function f3() {
class foo {
foo() {
"use strict";
}
}
(function f4() {
"use strict";
})();
}
expect: {
function f1() {
}
function f2() {
}
(function() {})();
}
}
issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}
valid_after_invalid_1: {
input: {
console.log(typeof function() {
"use\x20strict";
"use strict";
return this;
}());
}
expect: {
console.log(typeof function() {
"use\x20strict";
"use strict";
return this;
}());
}
expect_stdout: "undefined"
}
valid_after_invalid_2: {
options = {
directives: true,
}
input: {
console.log(typeof function() {
"use\x20strict";
"use strict";
return this;
}());
}
expect: {
console.log(typeof function() {
"use strict";
return this;
}());
}
expect_stdout: "undefined"
}
issue_5368_1: {
options = {
directives: true,
expression: true,
}
input: {
"foo";
}
expect: {
"foo";
}
}
issue_5368_2: {
options = {
directives: true,
expression: true,
}
input: {
"foo";
(function() {
"bar";
})();
}
expect: {
(function() {})();
}
expect_exact: "class foo{foo(){}}"
}

View File

@@ -1,5 +1,5 @@
drop_console_1: {
options = {}
options = {};
input: {
console.log('foo');
console.log.apply(console, arguments);
@@ -11,9 +11,7 @@ drop_console_1: {
}
drop_console_2: {
options = {
drop_console: true,
}
options = { drop_console: true };
input: {
console.log('foo');
console.log.apply(console, arguments);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
expand_arguments: {
input: {
func(a, ...rest);
func(...all);
}
expect_exact: "func(a,...rest);func(...all);"
}
expand_expression_arguments: {
input: {
f(...a.b);
f(...a.b());
f(...(a));
f(...(a.b));
f(...a[i]);
}
expect_exact: "f(...a.b);f(...a.b());f(...a);f(...a.b);f(...a[i]);"
}
expand_parameters: {
input: {
(function (a, ...b){});
(function (...args){});
}
expect_exact: "(function(a,...b){});(function(...args){});"
}

View File

@@ -1,147 +0,0 @@
precedence_1: {
input: {
console.log(-4 ** 3 ** 2);
}
expect_exact: "console.log((-4)**3**2);"
expect_stdout: "-262144"
node_version: ">=8"
}
precedence_2: {
input: {
console.log(-4 ** (3 ** 2));
}
expect_exact: "console.log((-4)**3**2);"
expect_stdout: "-262144"
node_version: ">=8"
}
precedence_3: {
input: {
console.log(-(4 ** 3) ** 2);
}
expect_exact: "console.log((-(4**3))**2);"
expect_stdout: "4096"
node_version: ">=8"
}
precedence_4: {
input: {
console.log((-4 ** 3) ** 2);
}
expect_exact: "console.log(((-4)**3)**2);"
expect_stdout: "4096"
node_version: ">=8"
}
await: {
input: {
(async a => a * await a ** ++a % a)(2).then(console.log);
}
expect_exact: "(async a=>a*(await a)**++a%a)(2).then(console.log);"
expect_stdout: "1"
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.4.0"
}
evaluate: {
options = {
evaluate: true,
}
input: {
console.log(1 + 2 ** 3 - 4);
}
expect: {
console.log(5);
}
expect_stdout: "5"
node_version: ">=8"
}
issue_4664: {
options = {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
new function(a) {
console.log(typeof f, a, typeof this);
}((A = 0, (NaN ^ 1) * 2 ** 30), 0);
}
f();
}
expect: {
(function f() {
new function(a) {
console.log(typeof f, 2 ** 30, typeof this);
}(A = 0);
})();
}
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"
}

View File

@@ -1,498 +0,0 @@
refs: {
input: {
export {};
export { 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: {
input: {
export const a = 1;
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,e:[]}=f;"
}
defuns: {
input: {
export class A {}
export function e() {}
export function* f(a) {}
export async function g(b, c) {}
export async function* h({}, ...[]) {}
}
expect_exact: "export class A{}export function e(){}export function*f(a){}export async function g(b,c){}export async function*h({},...[]){}"
}
defaults: {
input: {
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 ]) {};
}
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: {
input: {
export default function() {
console.log("FAIL");
}(console.log("PASS"));
}
expect_exact: 'export default function(){console.log("FAIL")}console.log("PASS");'
}
defaults_parentheses_2: {
input: {
export default (async function() {
console.log("PASS");
})();
}
expect_exact: 'export default(async function(){console.log("PASS")})();'
}
defaults_parentheses_3: {
input: {
export default (42, "PASS");
}
expect_exact: 'export default(42,"PASS");'
}
defaults_parentheses_4: {
input: {
export default (function f() {});
}
expect_exact: "export default(function f(){});"
}
defaults_parentheses_5: {
input: {
export default (function(a) {
console.log(a[0]);
}`PASS`);
}
expect_exact: "export default(function(a){console.log(a[0])})`PASS`;"
}
defaults_parentheses_6: {
options = {
conditionals: true,
}
input: {
export default !function() {
while (!console);
}() ? "PASS" : "FAIL";
}
expect_exact: 'export default(function(){while(!console);})()?"FAIL":"PASS";'
}
defaults_regexp: {
input: {
export default /foo/;
}
expect_exact: "export default/foo/;"
}
foreign: {
input: {
export * from "foo";
export {} from "bar";
export * as a from "baz";
export { default } from "moo";
export { b, c as case, default as delete, d } from "moz";
}
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
}
same_quotes: {
beautify = {
beautify: true,
quote_style: 3,
}
input: {
export * from 'foo';
export {} from "bar";
}
expect_exact: [
"export * from 'foo';",
"",
'export {} from "bar";',
]
}
drop_unused: {
options = {
toplevel: true,
unused: true,
}
input: {
export default 42;
export default (x, y) => x * x;
export default class A extends B { get p() { h() } }
export default function*(a, b) {}
export default async function f({ c }, ...[ d ]) {}
export var e;
export function g(x, [ y ], ...z) {}
function h() {}
}
expect: {
export default 42;
export default (x, y) => x * x;
export default class extends B { get p() { h() } }
export default function*(a, b) {}
export default async function({}) {}
export var e;
export function g(x, []) {}
function h() {}
}
}
mangle: {
rename = false
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let b, { foo: c } = a;
export function f(d, { [b]: e }) {
d(e, f);
}
export default a;
export default async function g(x, ...{ [c]: y }) {
(await x)(g, y);
}
}
expect: {
const t = 42;
export let b, { foo: c } = t;
export function f(t, { [b]: o }) {
t(o, f);
}
export default t;
export default async function e(t, ...{ [c]: o}) {
(await t)(e, o);
}
}
}
mangle_rename: {
rename = true
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let b, { foo: c } = a;
export function f(d, { [b]: e }) {
d(e, f);
}
export default a;
export default async function g(x, ...{ [c]: y }) {
(await x)(g, y);
}
}
expect: {
const t = 42;
export let b, { foo: c } = t;
export function f(t, { [b]: o }) {
t(o, f);
}
export default t;
export default async function e(t, ...{ [c]: o}) {
(await t)(e, o);
}
}
}
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,
reduce_vars: true,
toplevel: true,
unused: true,
}
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let bbb, { foo: ccc } = a;
export function fff(d, { [bbb]: e }) {
d(e, fff);
}
export default a;
export default async function g(x, ...{ [ccc]: y }) {
(await x)(g, y);
}
}
expect: {
let e, a = 42["foo"];
function f(t, { [e]: o }) {
t(o, f);
}
export default 42;
export default async function n(t, ...{ [a]: o }) {
(await t)(n, o);
};
export { e as bbb, a as ccc, f as fff };
}
}
hoist_vars: {
options = {
hoist_vars: true,
}
input: {
var a;
export var b = 42;
}
expect: {
var a;
export var b = 42;
}
}
keep_return_values: {
options = {
booleans: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
export default function() {
return [];
}
export default function f() {
return null;
}
}
expect: {
export default function() {
return [];
}
export default function f() {
return null;
}
}
}
in_use: {
options = {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export function f() {}
f.prototype.p = 42;
}
expect: {
export function f() {}
f.prototype.p = 42;
}
}
in_use_default: {
options = {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default function f() {}
f.prototype.p = 42;
}
expect: {
export default function f() {}
f.prototype.p = 42;
}
}
single_use: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export function f() {
console.log("PASS");
}
f();
}
expect: {
export function f() {
console.log("PASS");
}
f();
}
}
single_use_default: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default function f() {
console.log("PASS");
}
f();
}
expect: {
export default function f() {
console.log("PASS");
}
f();
}
}
single_use_class: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export class A {}
A.prototype.p = "PASS";
}
expect: {
export class A {}
A.prototype.p = "PASS";
}
}
single_use_class_default: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default class A {}
A.prototype.p = "PASS";
}
expect: {
export default class A {}
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";
}
}

View File

@@ -0,0 +1,52 @@
pow: {
input: {
var a = 2 ** 7;
var b = 3;
b **= 2;
}
expect: {
var a = 2 ** 7;
var b = 3;
b **= 2;
}
}
pow_with_number_constants: {
input: {
var a = 5 ** NaN;
var b = 42 ** +0;
var c = 42 ** -0;
var d = NaN ** 1;
var e = 2 ** Infinity;
var f = 2 ** -Infinity;
}
expect: {
var a = 5 ** NaN;
var b = 42 ** +0;
var c = 42 ** -0;
var d = NaN ** 1;
var e = 2 ** (1/0);
var f = 2 ** (-1/0);
}
}
pow_with_parentheses: {
input: {
var g = (-7) ** (0.5);
var h = 2324334 ** 34343443;
var i = (-2324334) ** 34343443;
var j = 2 ** (-3);
var k = 2.0 ** -3;
var l = 2.0 ** (5 - 7);
}
expect_exact: "var g=(-7)**.5;var h=2324334**34343443;var i=(-2324334)**34343443;var j=2**-3;var k=2**-3;var l=2**(5-7);"
}
pow_with_unary_between_brackets: {
input: {
var a = (-(+5)) ** 3;
}
expect: {
var a = (-+5)**3;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@ must_replace: {
options = {
global_defs: {
D: "foo bar",
},
}
}
input: {
console.log(D);
@@ -12,20 +12,6 @@ must_replace: {
}
}
repeated_nodes: {
options = {
global_defs: {
"@N": "rand()",
},
}
input: {
console.log(N, N);
}
expect: {
console.log(rand(), rand());
}
}
keyword: {
options = {
global_defs: {
@@ -51,7 +37,6 @@ object: {
VALUE: 42,
},
},
side_effects: true,
unsafe: true,
}
input: {
@@ -135,7 +120,7 @@ mixed: {
properties: true,
}
input: {
var FOO = { BAR: 0 };
const FOO = { BAR: 0 };
console.log(FOO.BAR);
console.log(++CONFIG.DEBUG);
console.log(++CONFIG.VALUE);
@@ -145,7 +130,7 @@ mixed: {
console.log(CONFIG);
}
expect: {
var FOO = { BAR: 0 };
const FOO = { BAR: 0 };
console.log("moo");
console.log(++CONFIG.DEBUG);
console.log(++CONFIG.VALUE);
@@ -155,8 +140,9 @@ mixed: {
console.log(CONFIG);
}
expect_warnings: [
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
]
}
@@ -174,59 +160,3 @@ issue_1801: {
console.log(!0);
}
}
issue_1986: {
options = {
global_defs: {
"@alert": "console.log",
},
}
input: {
alert(42);
}
expect: {
console.log(42);
}
}
issue_2167: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
global_defs: {
"@isDevMode": "function(){}",
},
passes: 2,
side_effects: true,
}
input: {
if (isDevMode()) {
greetOverlord();
}
doWork();
}
expect: {
doWork();
}
}
issue_3217: {
options = {
collapse_vars: true,
global_defs: {
"@o": "{fn:function(){var a=42;console.log(a)}}",
},
inline: true,
properties: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
o.fn();
}
expect: {
console.log(42);
}
}

585
test/compress/harmony.js Normal file
View File

@@ -0,0 +1,585 @@
arrow_function_parens: {
input: {
something && (() => {});
}
expect_exact: "something&&(()=>{});"
}
arrow_function_parens_2: {
input: {
(() => null)();
}
expect_exact: "(()=>null)();"
}
typeof_arrow_functions: {
options = {
evaluate: true
}
input: {
var foo = typeof (x) => null;
}
expect_exact: "var foo=\"function\";"
}
classes: {
input: {
class SomeClass {
constructor() {
};
foo() {};
};
class NoSemi {
constructor(...args) {
}
foo() {}
};
class ChildClass extends SomeClass {};
var asExpression = class AsExpression {};
var nameless = class {};
}
expect_exact: "class SomeClass{constructor(){}foo(){}}class NoSemi{constructor(...args){}foo(){}}class ChildClass extends SomeClass{}var asExpression=class AsExpression{};var nameless=class{};"
}
class_statics: {
input: {
x = class {
static staticMethod() {}
static get foo() {}
static set bar() {}
static() { /* "static" can be a method name! */ }
get() { /* "get" can be a method name! */ }
set() { /* "set" can be a method name! */ }
}
}
expect_exact: "x=class{static staticMethod(){}static get foo(){}static set bar(){}static(){}get(){}set(){}};"
}
class_name_can_be_mangled: {
mangle = { };
input: {
function x() {
class Foo {
}
var class1 = Foo
var class2 = class Bar {}
}
}
expect: {
function x() {
class a { }
var n = a
var r = class a {}
}
}
}
class_name_can_be_preserved: {
mangle = {
keep_classnames: true
}
input: {
function x() {
(class Baz { });
class Foo {};
}
}
expect: {
function x() {
(class Baz { });
class Foo {};
}
}
}
classes_can_have_generators: {
input: {
class Foo {
*bar() {}
static *baz() {}
}
}
expect: {
class Foo {
*bar() {}
static *baz() {}
}
}
}
classes_can_have_computed_generators: {
input: {
class C4 {
*['constructor']() {}
}
}
expect: {
class C4 {
*['constructor']() {}
}
}
}
classes_can_have_computed_static: {
input: {
class C4 {
static ['constructor']() {}
}
}
expect: {
class C4 {
static ['constructor']() {}
}
}
}
class_methods_and_getters_with_keep_quoted_props_enabled: {
beautify = {
quote_style: 3,
keep_quoted_props: true,
}
input: {
class clss {
a() {}
"b"() {}
get c() { return "c"}
get "d"() { return "d"}
set e(a) { doSomething(a); }
set 'f'(a) { doSomething(b); }
static g() {}
static "h"() {}
}
}
expect_exact: 'class clss{a(){}"b"(){}get c(){return"c"}get"d"(){return"d"}set e(a){doSomething(a)}set\'f\'(a){doSomething(b)}static g(){}static"h"(){}}'
}
classes_with_expression_as_expand: {
input: {
class D extends (calls++, C) {}
}
expect_exact: "class D extends(calls++,C){}"
}
new_target: {
input: {
new.target;
new.target.name;
}
expect_exact: "new.target;new.target.name;"
}
number_literals: {
input: {
0b1001;
0B1001;
0o11;
0O11;
}
expect: {
9;
9;
9;
9;
}
}
import_statement: {
input: {
import "mod-name";
import Foo from "bar";
import { Bar, Baz } from 'lel';
import Bar, { Foo } from 'lel';
import { Bar as kex, Baz as food } from 'lel';
}
expect_exact: 'import"mod-name";import Foo from"bar";import{Bar,Baz}from"lel";import Bar,{Foo}from"lel";import{Bar as kex,Baz as food}from"lel";'
}
import_all_statement: {
input: {
import * from 'lel';
import * as Lel from 'lel';
}
expect_exact: 'import*from"lel";import*as Lel from"lel";'
}
export_statement: {
options = {
evaluate: true,
}
input: {
export default 1 + 2;
export var foo = 4;
export let foo = 6;
export const foo = 6;
export function foo() {};
export class foo { };
}
expect_exact: "export default 3;export var foo=4;export let foo=6;export const foo=6;export function foo(){};export class foo{};"
}
export_default_object_expression: {
options = {
evaluate: true,
}
input: {
export default {
foo: 1 + 2,
bar() { return 4; },
get baz() { return this.foo; },
};
}
expect_exact: "export default{foo:3,bar(){return 4},get baz(){return this.foo}};"
}
export_default_array: {
options = {
evaluate: true,
}
input: {
export default [ 1 + 2, foo ];
}
expect_exact: "export default[3,foo];"
}
export_default_anon_function: {
options = {
evaluate: true,
}
input: {
export default function(){
console.log(1 + 2);
}
}
expect_exact: "export default function(){console.log(3)};"
}
export_default_anon_class: {
options = {
evaluate: true,
}
input: {
export default class {
foo() { console.log(1 + 2); }
}
}
expect_exact: "export default class{foo(){console.log(3)}};"
}
export_module_statement: {
input: {
export * from "a.js";
export {A} from "a.js";
export {A, B} from "a.js";
export {C};
}
expect_exact: 'export*from"a.js";export{A}from"a.js";export{A,B}from"a.js";export{C};'
}
import_statement_mangling: {
mangle = { toplevel: true };
input: {
import Foo from "foo";
import Bar, {Food} from "lel";
import {What as Whatever} from "lel";
Foo();
Bar();
Food();
Whatever();
}
expect: {
import l from "foo";
import e, {Food as o} from "lel";
import {What as f} from "lel";
l();
e();
o();
f();
}
}
export_statement_mangling: {
mangle = { };
input: {
export var foo = 6;
export function bar() { }
export class Baz { }
bar(foo, Baz)
}
expect: {
export var foo = 6;
export function bar() { }
export class Baz { }
bar(foo, Baz)
}
}
// https://github.com/mishoo/UglifyJS2/issues/1021
regression_for_of_const: {
input: {
for (const x of y) {}
for (const x in y) {}
}
expect: {
for (const x of y);for (const x in y);
}
}
// Fabio: My patches accidentally caused a crash whenever
// there's an extraneous set of parens around an object.
regression_cannot_destructure: {
input: {
var x = ({ x : 3 });
x(({ x: 3 }));
}
expect_exact: "var x={x:3};x({x:3});";
}
regression_cannot_use_of: {
input: {
function of() {
}
var of = "is a valid variable name";
of = { of: "is ok" };
x.of;
of: foo()
}
expect: {
function of(){}
var of="is a valid variable name";
of={of:"is ok"};
x.of;
foo(); /* Label statement missing? No prob. */
}
}
fat_arrow_as_param: {
input: {
foo(x => x);
foo(x => x, y => y);
foo(x => (x, x));
foo(x => (x, x), y => (y, y));
}
expect_exact: "foo(x=>x);foo(x=>x,y=>y);foo(x=>(x,x));foo(x=>(x,x),y=>(y,y));"
}
default_assign: {
options = {
keep_fargs: false,
unused: true,
}
input: {
function f(a, b = 3) {
console.log(a);
}
g = ([[] = 123]) => {};
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
function i([[x, y, z] = [4, 5, 6]] = []) {
console.log(b);
};
}
expect: {
function f(a) {
console.log(a);
}
g = ([[] = 123]) => {};
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
function i([[x, y, z] = [4, 5, 6]] = []) {
console.log(b);
};
}
}
expansion: {
options = {
keep_fargs: false,
unused: true,
}
input: {
function f(a, ...b) {
console.log(a);
}
}
expect: {
function f(a) {
console.log(a);
}
}
}
issue_1613: {
mangle = { toplevel: true };
input: {
const name = 1;
const foo = {
name
};
}
expect_exact: "const n=1;const c={name:n};"
}
format_methods: {
beautify = {
beautify: true,
}
input: {
class A extends B {constructor(a){x()} static s(b,c){y()} run(d,e,f){z()}}
}
expect_exact: [
"class A extends B {",
" constructor(a) {",
" x();",
" }",
" static s(b, c) {",
" y();",
" }",
" run(d, e, f) {",
" z();",
" }",
"}",
]
}
issue_1898: {
options = {
}
mangle = {
}
input: {
class Foo {
bar() {
for (const x of [ 6, 5 ]) {
for (let y of [ 4, 3 ]) {
for (var z of [ 2, 1 ]) {
console.log(x, y, z);
}
}
}
}
}
new Foo().bar();
}
expect: {
class Foo {
bar() {
for (const n of [ 6, 5 ])
for (let r of [ 4, 3 ])
for (var o of [ 2, 1 ])
console.log(n, r, o);
}
}
new Foo().bar();
}
}
issue_1753: {
mangle = { safari10: true };
input: {
class SomeClass {
constructor(props) {
let pickedSets = [];
for (let i = 0; i < 6; i++) {
pickedSets.push({
mainDrawNumbers: [],
extraDrawNumbers: []
});
}
}
}
}
expect: {
class SomeClass {
constructor(r) {
let a = [];
for (let s = 0; s < 6; s++)
a.push({
mainDrawNumbers: [],
extraDrawNumbers: []
});
}
}
}
}
issue_1753_disable: {
mangle = { safari10: false }
input: {
class SomeClass {
constructor(props) {
let pickedSets = [];
for (let i = 0; i < 6; i++) {
pickedSets.push({
mainDrawNumbers: [],
extraDrawNumbers: []
});
}
}
}
}
expect: {
class SomeClass {
constructor(r) {
let a = [];
for (let r = 0; r < 6; r++)
a.push({
mainDrawNumbers: [],
extraDrawNumbers: []
});
}
}
}
}
class_extends: {
options = {
evaluate: true,
}
input: {
function f() {
class foo extends bar {}
class pro extends some.prop {}
class arr extends stuff[1 - 1] {}
class bin extends (a || b) {}
class seq extends (a, b) {}
class ter extends (a ? b : c) {}
class uni extends (!0) {}
}
}
expect_exact: "function f(){class foo extends bar{}class pro extends some.prop{}class arr extends stuff[0]{}class bin extends(a||b){}class seq extends(a,b){}class ter extends(a?b:c){}class uni extends(!0){}}"
}
class_extends_class: {
options = {
}
input: {
class anon extends class {} {}
class named extends class base {} {}
}
expect_exact: "class anon extends class{}{}class named extends class base{}{}"
}
class_extends_function: {
options = {
}
input: {
class anon extends function(){} {}
class named extends function base(){} {}
}
expect_exact: "class anon extends function(){}{}class named extends function base(){}{}"
}
class_extends_regex: {
options = {
}
input: {
function f() {
class rx1 extends (/rx/) {}
// class rx2 extends /rx/ {} // FIXME - parse error
}
}
expect_exact: "function f(){class rx1 extends(/rx/){}}"
}

85
test/compress/hoist.js Normal file
View File

@@ -0,0 +1,85 @@
hoist_vars: {
options = {
hoist_vars: true
}
input: {
function a() {
bar();
var var1;
var var2;
}
function b(anArg) {
bar();
var var1;
var anArg;
}
}
expect: {
function a() {
var var1, var2; // Vars go up and are joined
bar();
}
function b(anArg) {
var var1;
bar();
// But vars named like arguments go away!
}
}
}
hoist_funs: {
options = {
hoist_funs: true
}
input: {
function a() {
bar();
function foo() {}
}
}
expect: {
function a() {
function foo() {} // Funs go up
bar();
}
}
}
hoist_no_destructurings: {
options = {
hoist_vars: true,
hoist_funs: true
}
input: {
function a([anArg]) {
bar();
var var1;
var anArg; // Because anArg is already declared, this goes away!
}
}
expect: {
function a([anArg]) {
var var1;
bar();
}
}
}
dont_hoist_var_destructurings: {
options = {
hoist_vars: true,
hoist_funs: true
}
input: {
function x() {
// If foo is null or undefined, this should be an exception
var {x,y} = foo;
}
}
expect: {
function x() {
var {x,y} = foo;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -88,414 +88,3 @@ sequences_funs: {
}
}
}
catch_var: {
options = {
dead_code: true,
hoist_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
try {
a;
} catch (a) {
var a = 0;
a;
}
console.log(a);
}
expect: {
var a = "PASS";
console.log(a);
}
expect_stdout: "PASS"
}
issue_2295: {
options = {
collapse_vars: true,
hoist_vars: true,
}
input: {
function foo(o) {
var a = o.a;
if (a) return a;
var a = 1;
}
}
expect: {
function foo(o) {
var a = o.a;
if (a) return a;
a = 1;
}
}
}
issue_4487_1: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
var a = function f() {
var f = console.log(typeof f);
};
a();
}
expect_stdout: "undefined"
}
issue_4487_2: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
function a() {
var f = console.log(typeof f);
}
a();
}
expect_stdout: "undefined"
}
issue_4487_3: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
passes: 3,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
(function a() {
console.log(typeof void 0);
})();
}
expect_stdout: "undefined"
}
issue_4489: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = 0;
var o = !0 || null;
for (var k in o);
console.log(k);
}
expect: {
!(A = 0);
for (var k in true);
console.log(k);
}
expect_stdout: "undefined"
}
issue_4517: {
options = {
collapse_vars: true,
hoist_vars: true,
join_vars: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var a = 2;
A = a;
var b = typeof !1;
return A + b;
}());
}
expect: {
console.log(function() {
var a = 2;
return (A = a) + typeof !1;
}());
}
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(1 << 30);
})();
})();
}
expect_stdout: "1073741824"
}
issue_4839: {
options = {
evaluate: true,
hoist_vars: true,
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var log = console.log, o = function(a, b) {
return b && b;
}("foo");
for (var k in o)
throw "FAIL";
log("PASS");
}
expect: {
var k, log = console.log;
for (k in void 0)
throw "FAIL";
log("PASS");
}
expect_stdout: "PASS"
}
issue_4859: {
options = {
evaluate: true,
hoist_vars: true,
keep_infinity: true,
merge_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a) {
var b = (a = 2, 1 / 0), c = 3;
var d = a + b;
console.log(d);
return f;
}
f();
}
expect: {
(function f(a) {
console.log(2 + 1 / 0);
return f;
})();
}
expect_stdout: "Infinity"
}
issue_4893_1: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
function g() {}
var a = null;
var b = null;
var c = null;
b.p += a = 42;
f;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect: {
try{
(function f() {
null.p += 42;
f;
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4893_2: {
options = {
collapse_vars: true,
hoist_vars: true,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
function g() {}
var a = null;
var b = null;
var c = null;
b.p += a = 42;
f;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect: {
try{
(function() {
var b;
b = null;
b.p += 42;
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4898: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
loops: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
do {
var b = [ console.log("PASS") ];
var c = b;
} while (c.p = 0);
}
expect: {
var b;
b = [ console.log("PASS") ];
b.p = 0;
}
expect_stdout: "PASS"
}
issue_5187: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a = 42;
do {
var b = { 0: a++ };
} while (console.log(b[b ^= 0]));
}
f();
}
expect: {
(function() {
var b, a = 42;
do {
b = { 0: a++ };
} while (console.log(b[b ^= 0]));
})();
}
expect_stdout: "42"
}
issue_5195: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a;
do {
var b = { p: a };
} while (console.log(b += ""));
}
f();
}
expect: {
(function() {
var a, b;
do {
b = { p: a };
} while (console.log(b += ""));
})();
}
expect_stdout: "[object Object]"
}

View File

@@ -1,107 +1,64 @@
html_comment_in_expression: {
input: {
(function(a, b) {
console.log(a < !--b && a-- > b, a, b);
})(1, 2);
function f(a, b, x, y) { return a < !--b && x-- > y; }
}
expect_exact: "(function(a,b){console.log(a<! --b&&a-- >b,a,b)})(1,2);"
expect_stdout: "false 1 1"
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
}
html_comment_in_less_than: {
input: {
(function(a, b, c) {
console.log(
a < !--b,
a < !--b + c,
a + b < !--c,
a, b, c
);
})(1, 2, 3);
function f(a, b) { return a < !--b; }
}
expect_exact: "(function(a,b,c){console.log(a<! --b,a<! --b+c,a+b<! --c,a,b,c)})(1,2,3);"
expect_stdout: "false true false 1 0 2"
expect_exact: "function f(a,b){return a< !--b}";
}
html_comment_in_left_shift: {
input: {
(function(a, b, c) {
console.log(
a << !--b,
a << !--b + c,
a + b << !--c,
a, b, c
);
})(1, 2, 3);
function f(a, b) { return a << !--b; }
}
expect_exact: "(function(a,b,c){console.log(a<<! --b,a<<! --b+c,a+b<<! --c,a,b,c)})(1,2,3);"
expect_stdout: "1 16 1 1 0 2"
}
html_comment_in_greater_than: {
input: {
(function(a, b, c) {
console.log(
a-- > b,
a-- > b + c,
a + b-- > c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "(function(a,b,c){console.log(a-- >b,a-- >b+c,a+b-- >c,a,b,c)})(1,2,3);"
expect_stdout: "false false false -1 1 3"
}
html_comment_in_greater_than_or_equal: {
input: {
(function(a, b, c) {
console.log(
a-- >= b,
a-- >= b + c,
a + b-- >= c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "(function(a,b,c){console.log(a-- >=b,a-- >=b+c,a+b-- >=c,a,b,c)})(1,2,3);"
expect_stdout: "false false false -1 1 3"
expect_exact: "function f(a,b){return a<< !--b}";
}
html_comment_in_right_shift: {
input: {
(function(a, b, c) {
console.log(
a-- >> b,
a-- >> b + c,
a + b-- >> c,
a, b, c
);
})(1, 2, 3);
function f(a, b) { return a-- >> b; }
}
expect_exact: "(function(a,b,c){console.log(a-- >>b,a-- >>b+c,a+b-- >>c,a,b,c)})(1,2,3);"
expect_stdout: "0 0 0 -1 1 3"
expect_exact: "function f(a,b){return a-- >>b}";
}
html_comment_in_zero_fill_right_shift: {
input: {
(function(a, b, c) {
console.log(
a-- >>> b,
a-- >>> b + c,
a + b-- >>> c,
a, b, c
);
})(1, 2, 3);
function f(a, b) { return a-- >>> b; }
}
expect_exact: "(function(a,b,c){console.log(a-- >>>b,a-- >>>b+c,a+b-- >>>c,a,b,c)})(1,2,3);"
expect_stdout: "0 0 0 -1 1 3"
expect_exact: "function f(a,b){return a-- >>>b}";
}
html_comment_in_greater_than: {
input: {
function f(a, b) { return a-- > b; }
}
expect_exact: "function f(a,b){return a-- >b}";
}
html_comment_in_greater_than_or_equal: {
input: {
function f(a, b) { return a-- >= b; }
}
expect_exact: "function f(a,b){return a-- >=b}";
}
html_comment_in_string_literal: {
input: {
console.log("<!--HTML-->comment in<!--string literal-->".length);
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
}
expect_exact: 'console.log("\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e".length);'
expect_stdout: "42"
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
}
html_comment_after_multiline_comment: {
input: {
var foo; /*
*/--> var bar;
var foobar;
}
expect_exact: "var foo;var foobar;"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
if_return_1: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x) {
@@ -24,15 +24,15 @@ if_return_1: {
if_return_2: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x, y) {
@@ -49,15 +49,15 @@ if_return_2: {
if_return_3: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x) {
@@ -75,15 +75,15 @@ if_return_3: {
if_return_4: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x, y) {
@@ -100,15 +100,15 @@ if_return_4: {
if_return_5: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f() {
@@ -126,15 +126,15 @@ if_return_5: {
if_return_6: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x) {
@@ -150,15 +150,15 @@ if_return_6: {
if_return_7: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function f(x) {
@@ -176,10 +176,10 @@ if_return_7: {
if_return_8: {
options = {
conditionals: true,
if_return: true,
sequences: true,
side_effects: true,
if_return: true,
sequences: true,
conditionals: true,
side_effects : true,
}
input: {
function f(e) {
@@ -220,15 +220,15 @@ if_return_8: {
issue_1089: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
}
input: {
function x() {
@@ -243,7 +243,7 @@ issue_1089: {
expect: {
function x() {
var f = document.getElementById("fname");
if (12345 < f.files[0].size)
if (f.files[0].size > 12345)
return alert("alert"), f.focus(), !1;
}
}
@@ -251,9 +251,9 @@ issue_1089: {
issue_1437: {
options = {
conditionals: false,
if_return: true,
sequences: true,
if_return : true,
sequences : true,
conditionals : false
}
input: {
function x() {
@@ -281,9 +281,9 @@ issue_1437: {
issue_1437_conditionals: {
options = {
conditionals: true,
if_return: true,
sequences: true,
conditionals : true,
if_return : true,
sequences : true
}
input: {
function x() {
@@ -302,551 +302,3 @@ issue_1437_conditionals: {
}
}
}
issue_512: {
options = {
conditionals: true,
if_return: true,
sequences: true,
side_effects: true,
}
input: {
function a() {
if (b()) {
c();
return;
}
throw e;
}
}
expect: {
function a() {
if (!b()) throw e;
c();
}
}
}
if_var_return_1: {
options = {
conditionals: true,
if_return: true,
join_vars: true,
sequences: true,
}
input: {
function f() {
var a;
return;
var b;
}
function g() {
var a;
if (u()) {
var b;
return v();
var c;
}
var d;
if (w()) {
var e;
return x();
var f;
} else {
var g;
y();
var h;
}
var i;
z();
var j;
}
}
expect: {
function f() {
var a, b;
}
function g() {
var a, b, c, d, e, f, g, h, i, j;
return u() ? v() : w() ? x() : (y(), z(), void 0);
}
}
}
if_var_return_2: {
options = {
conditionals: true,
if_return: true,
sequences: true,
}
input: {
(function() {
var a = w();
if (x())
return y();
z();
})();
}
expect: {
(function() {
var a = w();
return x() ? y() : (z(), void 0);
})();
}
}
if_var_retrn_3: {
options = {
conditionals: true,
if_return: true,
sequences: true,
}
input: {
f(function() {
var a = w();
if (x())
return y(a);
z();
});
}
expect: {
f(function() {
var a = w();
if (x())
return y(a);
z();
});
}
}
if_var_return_4: {
options = {
conditionals: true,
if_return: true,
sequences: true,
}
input: {
function f() {
if (u())
return v();
var a = w();
if (x())
return y();
z();
}
}
expect: {
function f() {
return u() ? v() : (a = w(), x() ? y() : (z(), void 0));
var a;
}
}
}
if_if_return_return: {
options = {
conditionals: true,
if_return: true,
}
input: {
function f(a, b) {
if (a) {
if (b)
return b;
return;
}
g();
}
}
expect: {
function f(a, b) {
if (a)
return b || void 0;
g();
}
}
}
if_body_return_1: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}
if_body_return_2: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (0 + a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (0 + a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}
if_body_return_3: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (1 == a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (1 != a) return true;
if (b) throw new Error(c);
return 42;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}
issue_3600_1: {
options = {
if_return: true,
inline: 3,
side_effects: true,
unused: true,
}
input: {
var c = 0;
(function() {
if ([ ][c++]); else return;
return void function() {
var b = --b, a = c = 42;
return c;
}();
})();
console.log(c);
}
expect: {
var c = 0;
(function() {
if ([][c++]) b = --b, c = 42;
var b;
})();
console.log(c);
}
expect_stdout: "1"
}
issue_3600_2: {
options = {
if_return: true,
inline: true,
side_effects: true,
unused: true,
}
input: {
var c = 0;
(function() {
if ([ ][c++]); else return;
return void function() {
var b = --b, a = c = 42;
return c;
}();
})();
console.log(c);
}
expect: {
var c = 0;
(function() {
if ([][c++])
b = --b,
c = 42;
var b;
})();
console.log(c);
}
expect_stdout: "1"
}
iife_if_return_simple: {
options = {
conditionals: true,
if_return: true,
inline: true,
sequences: true,
side_effects: true,
}
input: {
(function() {
if (console)
return console.log("PASS");
console.log("FAIL");
})();
}
expect: {
console ? console.log("PASS") : console.log("FAIL");
}
expect_stdout: "PASS"
}
nested_if_break: {
options = {
conditionals: true,
if_return: true,
side_effects: true,
}
input: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i) {
if (0 === i) break L1;
console.log(i);
}
}
expect: {
for (var i = 0; i < 3; i++)
L1: "number" == typeof i && 0 !== i && console.log(i);
}
expect_stdout: [
"1",
"2",
]
}
nested_if_continue: {
options = {
conditionals: true,
if_return: true,
join_vars: true,
loops: true,
}
input: {
function f(n) {
var i = 0;
do {
if ("number" == typeof n) {
if (0 === n) {
console.log("even", i);
continue;
}
if (1 === n) {
console.log("odd", i);
continue;
}
i++;
}
} while (0 <= (n -= 2));
}
f(37);
f(42);
}
expect: {
function f(n) {
for (var i = 0;
"number" == typeof n
&& (0 === n
? console.log("even", i)
: 1 === n
? console.log("odd", i)
: i++),
0 <= (n -= 2););
}
f(37);
f(42);
}
expect_stdout: [
"odd 18",
"even 21",
]
}
nested_if_return: {
options = {
conditionals: true,
if_return: true,
}
input: {
function f() {
if (A) {
if (B)
return B;
if (C)
return D;
if (E)
return F;
if (G)
return H;
if (I) {
if (J)
return K;
return;
}
if (L) {
if (M)
return;
return N;
}
}
}
}
expect: {
function f() {
if (A)
return B || (C ? D : E ? F : G ? H : I ? J ? K : void 0 : L && !M ? N : void 0);
}
}
}
issue_866_1: {
options = {
conditionals: true,
if_return: true,
sequences: false,
};
input: {
function f(a) {
if (a)
return "";
console.log(a);
}
}
expect: {
function f(a) {
if (a)
return "";
console.log(a);
}
}
}
issue_866_2: {
options = {
conditionals: true,
if_return: true,
sequences: true,
}
input: {
(function() {
if (a)
if (b)
c;
else
return d;
})();
}
expect: {
(function() {
if (a) {
if (!b)
return d;
c;
}
})();
}
}

View File

@@ -1,229 +0,0 @@
nought: {
input: {
import "foo";
}
expect_exact: 'import"foo";'
}
default_only: {
input: {
import foo from "bar";
}
expect_exact: 'import foo from"bar";'
}
all_only: {
input: {
import * as foo from "bar";
}
expect_exact: 'import*as foo from"bar";'
}
keys_only: {
input: {
import { as as foo, bar, delete as baz } from "moo";
}
expect_exact: 'import{as as foo,bar,delete as baz}from"moo";'
}
default_all: {
input: {
import foo, * as bar from "baz";
}
expect_exact: 'import foo,*as bar from"baz";'
}
default_keys: {
input: {
import foo, { bar } from "baz";
}
expect_exact: 'import foo,{bar}from"baz";'
}
dynamic: {
input: {
(async a => await import(a))("foo").then(bar);
}
expect_exact: '(async a=>await import(a))("foo").then(bar);'
}
dynamic_nought: {
input: {
import(foo);
}
expect_exact: "import(foo);"
}
import_meta_1: {
input: {
console.log(import.meta, import.meta.url);
}
expect_exact: "console.log(import.meta,import.meta.url);"
}
import_meta_2: {
input: {
import.meta.url.split("/").forEach(function(part, index) {
console.log(index, part);
});
}
expect_exact: 'import.meta.url.split("/").forEach(function(part,index){console.log(index,part)});'
}
same_quotes: {
beautify = {
beautify: true,
quote_style: 3,
}
input: {
import 'foo';
import "bar";
}
expect_exact: [
"import 'foo';",
"",
'import "bar";',
]
}
drop_unused: {
options = {
imports: true,
toplevel: true,
unused: true,
}
input: {
import a, * as b from "foo";
import { c } from "bar";
import { d, _ as e } from "baz";
console.log(d);
}
expect: {
import "foo";
import "bar";
import { d as d } from "baz";
console.log(d);
}
}
drop_side_effect_free: {
options = {
imports: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
import foo from "bar";
var a = foo;
}
expect: {
import "bar";
}
}
mangle: {
rename = false
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
consoe.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
consoe.log(r);
import * as r from "moz";
}
}
rename_mangle: {
rename = true
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
consoe.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
consoe.log(r);
import * as r from "moz";
}
}
keep_ref: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
import foo from "bar";
foo();
}
expect: {
import foo from "bar";
foo();
}
}
forbid_merge: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
import A from "foo";
export default class extends A {}
var f = () => () => {};
f();
f();
}
expect: {
import A from "foo";
export default class extends A {}
var f = () => () => {};
f();
f();
}
}
issue_4708_1: {
options = {
imports: true,
toplevel: true,
unused: true,
}
input: {
var a;
import a from "foo";
}
expect: {
var a;
import a from "foo";
}
}
issue_4708_2: {
options = {
imports: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a;
console.log(a);
import a from "foo";
}
expect: {
var a;
console.log(a);
import a from "foo";
}
}

View File

@@ -1,100 +0,0 @@
numeric: {
beautify = {
beautify: true,
indent_start: 1,
indent_level: 3,
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
" switch (42) {",
" case null:",
' console.log("FAIL");',
" }",
"",
' console.log("PASS");',
]
expect_stdout: "PASS"
}
spaces: {
beautify = {
beautify: true,
indent_start: " ",
indent_level: " ",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
" switch (42) {",
" case null:",
' console.log("FAIL");',
" }",
"",
' console.log("PASS");',
]
expect_stdout: "PASS"
}
tabs: {
beautify = {
beautify: true,
indent_start: "\t",
indent_level: "\t",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
"\tswitch (42) {",
"\tcase null:",
'\t\tconsole.log("FAIL");',
"\t}",
"",
'\tconsole.log("PASS");',
]
expect_stdout: "PASS"
}
mixed: {
beautify = {
beautify: true,
indent_start: "\n",
indent_level: " \t",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
"",
"switch (42) {",
"",
" case null:",
"",
' \tconsole.log("FAIL");',
"",
"}",
"",
"",
'console.log("PASS");',
]
expect_stdout: "PASS"
}

View File

@@ -0,0 +1,8 @@
parenthesis_strings_in_parenthesis: {
input: {
var foo = ('(');
a(')');
}
expect_exact: 'var foo="(";a(")");'
}

View File

@@ -1,17 +1,8 @@
non_hoisted_function_after_return: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, cascade: true, side_effects: true
}
input: {
function foo(x) {
@@ -30,35 +21,25 @@ non_hoisted_function_after_return: {
}
expect: {
function foo(x) {
return (x ? bar : baz)();
return x ? bar() : baz();
function bar() { return 7 }
function baz() { return 8 }
}
}
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]",
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
]
}
non_hoisted_function_after_return_2a: {
options = {
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, cascade: true, side_effects: true,
collapse_vars: false, passes: 2, warnings: "verbose"
}
input: {
function foo(x) {
@@ -84,34 +65,26 @@ non_hoisted_function_after_return_2a: {
}
}
expect_warnings: [
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:4,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
"INFO: pass 0: last_count: Infinity, count: 35",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
"INFO: pass 1: last_count: 35, count: 18",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:51,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
]
}
non_hoisted_function_after_return_2b: {
options = {
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, cascade: true, side_effects: true,
collapse_vars: false
}
input: {
function foo(x) {
@@ -135,164 +108,11 @@ non_hoisted_function_after_return_2b: {
}
}
expect_warnings: [
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:8,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
]
}
non_hoisted_function_after_return_strict: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
function foo(x) {
if (x) {
return bar();
not_called1();
} else {
return baz();
not_called2();
}
function bar() { return 7; }
return not_reached;
function UnusedFunction() {}
function baz() { return 8; }
}
console.log(foo(0), foo(1));
}
expect: {
"use strict";
function foo(x) {
return (x ? bar : baz)();
function bar() { return 7 }
function baz() { return 8 }
}
console.log(foo(0), foo(1));
}
expect_stdout: "8 7"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:11,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:12,21]",
]
}
non_hoisted_function_after_return_2a_strict: {
options = {
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
}
input: {
"use strict";
function foo(x) {
if (x) {
return bar(1);
var a = not_called(1);
} else {
return bar(2);
var b = not_called(2);
}
var c = bar(3);
function bar(x) { return 7 - x; }
function nope() {}
return b || c;
}
console.log(foo(0), foo(1));
}
expect: {
"use strict";
function foo(x) {
return bar(x ? 1 : 2);
function bar(x) {
return 7 - x;
}
}
console.log(foo(0), foo(1));
}
expect_stdout: "5 6"
expect_warnings: [
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:5,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:8,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
"INFO: pass 0: last_count: Infinity, count: 46",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
"INFO: pass 1: last_count: 46, count: 29",
]
}
non_hoisted_function_after_return_2b_strict: {
options = {
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
function foo(x) {
if (x) {
return bar(1);
} else {
return bar(2);
var b;
}
var c = bar(3);
function bar(x) {
return 7 - x;
}
return b || c;
}
console.log(foo(0), foo(1));
}
expect: {
"use strict";
function foo(x) {
return bar(x ? 1 : 2);
function bar(x) { return 7 - x; }
}
console.log(foo(0), foo(1));
}
expect_stdout: "5 6"
expect_warnings: [
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
// duplicate warnings no longer emitted
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
]
}

View File

@@ -1,9 +1,21 @@
const_declaration: {
options = {
evaluate: true
};
input: {
const goog = goog || {};
}
expect: {
const goog = goog || {};
}
}
const_pragma: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
}
};
input: {
/** @const */ var goog = goog || {};
@@ -17,9 +29,8 @@ const_pragma: {
not_const: {
options = {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
}
};
input: {
var goog = goog || {};

View File

@@ -0,0 +1,30 @@
issue_1043: {
options = {
side_effects: true
};
input: {
function* range(start = 0, end = null, step = 1) {
if (end == null) {
end = start;
start = 0;
}
for (let i = start; i < end; i += step) {
yield i;
}
}
}
expect: {
function* range(start = 0, end = null, step = 1) {
if (null == end) {
end = start;
start = 0;
}
for (let i = start; i < end; i += step)
yield i;
}
}
}

View File

@@ -0,0 +1,9 @@
issue_1044: {
options = { evaluate: true, conditionals: true };
input: {
const mixed = Base ? class extends Base {} : class {}
}
expect: {
const mixed = Base ? class extends Base {} : class {}
}
}

View File

@@ -1,169 +1,96 @@
multiple_functions: {
options = {
hoist_funs: false,
if_return: true,
}
options = { if_return: true, hoist_funs: false };
input: {
(function() {
if (!window)
( function() {
if ( !window ) {
return;
}
function f() {}
function g() {}
})();
} )();
}
expect: {
(function() {
// NOTE: other compression steps will reduce this
// down to just `window`.
if (!window);
( function() {
function f() {}
function g() {}
})();
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( window );
} )();
}
}
single_function: {
options = {
hoist_funs: false,
if_return: true,
}
options = { if_return: true, hoist_funs: false };
input: {
(function() {
if (!window)
( function() {
if ( !window ) {
return;
}
function f() {}
})();
} )();
}
expect: {
(function() {
if (!window);
( function() {
function f() {}
})();
if ( window );
} )();
}
}
deeply_nested: {
options = {
hoist_funs: false,
if_return: true,
}
options = { if_return: true, hoist_funs: false };
input: {
(function() {
if (!window)
( function() {
if ( !window ) {
return;
}
function f() {}
function g() {}
if (!document)
if ( !document ) {
return;
}
function h() {}
})();
} )();
}
expect: {
(function() {
// NOTE: other compression steps will reduce this
// down to just `window`.
if (!window);
else if (!document);
( function() {
function f() {}
function g() {}
function h() {}
})();
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( window )
if (document);
} )();
}
}
not_hoisted_when_already_nested: {
options = {
hoist_funs: false,
if_return: true,
}
options = { if_return: true, hoist_funs: false };
input: {
(function() {
if (!window)
( function() {
if ( !window ) {
return;
if (foo) function f() {}
})();
}
expect: {
(function() {
if (!window);
else if (foo)
function f() {}
})();
}
}
}
defun_if_return: {
options = {
hoist_funs: false,
if_return: true,
}
input: {
function e() {
function f() {}
if (!window)
return;
else
function g() {}
function h() {}
}
}
expect: {
function e() {
function f() {}
if (!window);
else
function g() {}
function h() {}
}
}
}
if ( foo ) function f() {}
defun_hoist_funs: {
options = {
hoist_funs: true,
if_return: true,
}
input: {
function e() {
function f() {}
if (!window)
return;
else
function g() {}
function h() {}
}
} )();
}
expect: {
function e() {
function f() {}
function g() {}
function h() {}
if (!window);
}
}
}
defun_else_if_return: {
options = {
hoist_funs: false,
if_return: true,
}
input: {
function e() {
function f() {}
if (window)
function g() {}
else
return;
function h() {}
}
}
expect: {
function e() {
function f() {}
if (window)
function g() {}
function h() {}
}
( function() {
if ( window )
if ( foo ) function f() {}
} )();
}
}

View File

@@ -1,6 +1,6 @@
with_in_global_scope: {
options = {
unused: true,
unused: true
}
input: {
var o = 42;
@@ -18,7 +18,7 @@ with_in_global_scope: {
}
with_in_function_scope: {
options = {
unused: true,
unused: true
}
input: {
function foo() {
@@ -40,7 +40,7 @@ with_in_function_scope: {
}
compress_with_with_in_other_scope: {
options = {
unused: true,
unused: true
}
input: {
function foo() {
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
}
with_using_existing_variable_outside_scope: {
options = {
unused: true,
unused: true
}
input: {
function f() {
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
}
check_drop_unused_in_peer_function: {
options = {
unused: true,
unused: true
}
input: {
function outer() {
@@ -148,57 +148,52 @@ check_drop_unused_in_peer_function: {
Infinity_not_in_with_scope: {
options = {
unused: true,
unused: true
}
input: {
var o = { Infinity: "FAIL" };
var o = { Infinity: 'oInfinity' };
var vInfinity = "Infinity";
vInfinity = Infinity;
console.log(vInfinity);
}
expect: {
var o = { Infinity: "FAIL" };
var vInfinity = "Infinity";
vInfinity = 1/0;
console.log(vInfinity);
var o = { Infinity: 'oInfinity' }
var vInfinity = "Infinity"
vInfinity = 1/0
}
expect_stdout: "Infinity"
}
Infinity_in_with_scope: {
options = {
unused: true,
unused: true
}
input: {
var o = { Infinity: "PASS" };
var o = { Infinity: 'oInfinity' };
var vInfinity = "Infinity";
with (o) { vInfinity = Infinity; }
console.log(vInfinity);
}
expect: {
var o = { Infinity: "PASS" };
var vInfinity = "Infinity";
with (o) vInfinity = Infinity;
console.log(vInfinity);
var o = { Infinity: 'oInfinity' }
var vInfinity = "Infinity"
with (o) vInfinity = Infinity
}
expect_stdout: "PASS"
}
assorted_Infinity_NaN_undefined_in_with_scope: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
unused: true,
evaluate: true,
dead_code: true,
conditionals: true,
comparisons: true,
booleans: true,
hoist_funs: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
sequences: false,
keep_infinity: false,
sequences: false,
side_effects: true,
unused: true,
}
input: {
var f = console.log;
@@ -248,19 +243,20 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
unused: true,
evaluate: true,
dead_code: true,
conditionals: true,
comparisons: true,
booleans: true,
hoist_funs: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
sequences: false,
keep_infinity: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
var f = console.log;

View File

@@ -1,78 +1,58 @@
keep_name_of_getter: {
options = {
unused: true,
}
input: {
a = {
get foo() {},
};
}
expect: {
a = {
get foo() {},
};
}
options = { unused: true };
input: { a = { get foo () {} } }
expect: { a = { get foo () {} } }
}
keep_name_of_setter: {
options = {
unused: true,
}
input: {
a = {
set foo(v) {},
};
}
expect: {
a = {
set foo(v) {},
};
}
options = { unused: true };
input: { a = { set foo () {} } }
expect: { a = { set foo () {} } }
}
setter_with_operator_keys: {
input: {
var tokenCodes = {
get instanceof() {
var tokenCodes = {
get instanceof(){
return test0;
},
set instanceof(value) {
set instanceof(value){
test0 = value;
},
set typeof(value) {
set typeof(value){
test1 = value;
},
get typeof() {
get typeof(){
return test1;
},
set else(value) {
set else(value){
test2 = value;
},
get else() {
get else(){
return test2;
},
}
};
}
expect: {
var tokenCodes = {
get instanceof() {
var tokenCodes = {
get instanceof(){
return test0;
},
set instanceof(value) {
set instanceof(value){
test0 = value;
},
set typeof(value) {
set typeof(value){
test1 = value;
},
get typeof() {
get typeof(){
return test1;
},
set else(value) {
set else(value){
test2 = value;
},
get else() {
get else(){
return test2;
},
}
};
}
}
}

View File

@@ -1,10 +1,10 @@
mangle_keep_fnames_false: {
options = {
keep_fargs: true,
keep_fnames: true,
keep_fnames : true,
keep_fargs : true,
}
mangle = {
keep_fnames: false,
keep_fnames : false,
}
input: {
"use strict";
@@ -26,11 +26,11 @@ mangle_keep_fnames_false: {
mangle_keep_fnames_true: {
options = {
keep_fargs: true,
keep_fnames: true,
keep_fnames : true,
keep_fargs : true,
}
mangle = {
keep_fnames: true,
keep_fnames : true,
}
input: {
"use strict";

View File

@@ -0,0 +1,76 @@
issue_1212_debug_false: {
options = {
global_defs : { DEBUG: false },
sequences : true,
properties : true,
dead_code : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
loops : true,
unused : true,
hoist_funs : true,
keep_fargs : true,
if_return : true,
join_vars : true,
cascade : true,
side_effects : true,
}
input: {
class foo {
bar() {
if (DEBUG)
console.log("DEV");
else
console.log("PROD");
}
}
new foo().bar();
}
expect: {
class foo{
bar() { console.log("PROD") }
}
(new foo).bar();
}
}
issue_1212_debug_true: {
options = {
global_defs : { DEBUG: true },
sequences : true,
properties : true,
dead_code : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
loops : true,
unused : true,
hoist_funs : true,
keep_fargs : true,
if_return : true,
join_vars : true,
cascade : true,
side_effects : true,
}
input: {
class foo {
bar() {
if (DEBUG)
console.log("DEV");
else
console.log("PROD");
}
}
new foo().bar();
}
expect: {
class foo{
bar() { console.log("DEV") }
}
(new foo).bar();
}
}

View File

@@ -1,15 +1,15 @@
pure_function_calls: {
options = {
annotations: true,
booleans: true,
comparisons: true,
conditionals: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: true,
side_effects: true,
unused: true,
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
negate_iife : true,
}
input: {
// pure top-level IIFE will be dropped
@@ -49,29 +49,29 @@ pure_function_calls: {
a.b(), f.g();
}
expect_warnings: [
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:25,31]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
]
}
pure_function_calls_toplevel: {
options = {
annotations: true,
booleans: true,
comparisons: true,
conditionals: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: true,
side_effects: true,
toplevel: true,
unused: true,
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
negate_iife : true,
toplevel : true,
}
input: {
// pure top-level IIFE will be dropped
@@ -96,13 +96,6 @@ pure_function_calls_toplevel: {
})();
})();
// pure top-level calls will be dropped regardless of the leading comments position
var MyClass = /*#__PURE__*//*@class*/(function(){
function MyClass() {}
MyClass.prototype.method = function() {};
return MyClass;
})();
// comment #__PURE__ comment
bar(), baz(), quux();
a.b(), /* @__PURE__ */ c.d.e(), f.g();
@@ -112,23 +105,20 @@ pure_function_calls_toplevel: {
a.b(), f.g();
}
expect_warnings: [
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:31,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:32,31]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,33]",
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:8,12]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,45]",
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:24,12]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
]
}
should_warn: {
options = {
annotations: true,
booleans: true,
conditionals: true,
evaluate: true,
@@ -158,29 +148,29 @@ should_warn: {
baz();
}
expect_warnings: [
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,61]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,23]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:1,23]",
"WARN: Boolean || always true [test/compress/issue-1261.js:2,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:2,23]",
"WARN: Condition always true [test/compress/issue-1261.js:2,23]",
"WARN: Condition left of || always true [test/compress/issue-1261.js:3,8]",
"WARN: Condition always true [test/compress/issue-1261.js:3,8]",
"WARN: Boolean && always false [test/compress/issue-1261.js:4,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:4,23]",
"WARN: Condition always false [test/compress/issue-1261.js:4,23]",
"WARN: Condition left of && always false [test/compress/issue-1261.js:5,8]",
"WARN: Condition always false [test/compress/issue-1261.js:5,8]",
"WARN: + in boolean context always true [test/compress/issue-1261.js:6,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:6,23]",
"WARN: Condition always true [test/compress/issue-1261.js:6,23]",
"WARN: + in boolean context always true [test/compress/issue-1261.js:7,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:7,31]",
"WARN: Condition always true [test/compress/issue-1261.js:7,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,23]",
"WARN: Condition always true [test/compress/issue-1261.js:9,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:9,24]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:10,31]",
"WARN: Condition always false [test/compress/issue-1261.js:10,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
]
}

View File

@@ -1,16 +1,17 @@
string_plus_optimization: {
options = {
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
side_effects: true,
unused: true,
}
side_effects : true,
evaluate : true,
conditionals : true,
comparisons : true,
dead_code : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
hoist_funs : true,
};
input: {
function foo(anything) {
function throwing_function() {

View File

@@ -1,8 +1,6 @@
issue_1321_no_debug: {
mangle = {
properties: {
keep_quoted: true,
},
mangle_props = {
keep_quoted: true
}
input: {
var x = {};
@@ -12,19 +10,17 @@ issue_1321_no_debug: {
}
expect: {
var x = {};
x.x = 1;
x["a"] = 2 * x.x;
console.log(x.x, x["a"]);
x.b = 1;
x["a"] = 2 * x.b;
console.log(x.b, x["a"]);
}
expect_stdout: true
}
issue_1321_debug: {
mangle = {
properties: {
debug: "",
keep_quoted: true,
},
mangle_props = {
keep_quoted: true,
debug: ""
}
input: {
var x = {};
@@ -34,18 +30,16 @@ issue_1321_debug: {
}
expect: {
var x = {};
x.x = 1;
x["_$foo$_"] = 2 * x.x;
console.log(x.x, x["_$foo$_"]);
x.a = 1;
x["_$foo$_"] = 2 * x.a;
console.log(x.a, x["_$foo$_"]);
}
expect_stdout: true
}
issue_1321_with_quoted: {
mangle = {
properties: {
keep_quoted: false,
},
mangle_props = {
keep_quoted: false
}
input: {
var x = {};
@@ -55,9 +49,9 @@ issue_1321_with_quoted: {
}
expect: {
var x = {};
x.x = 1;
x["o"] = 2 * x.x;
console.log(x.x, x["o"]);
x.a = 1;
x["b"] = 2 * x.a;
console.log(x.a, x["b"]);
}
expect_stdout: true
}

View File

@@ -15,7 +15,7 @@
tranformation_sort_order_equal: {
options = {
comparisons: true,
}
};
input: { (a = parseInt('100')) == a }
expect: { (a = parseInt('100')) == a }
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
tranformation_sort_order_unequal: {
options = {
comparisons: true,
}
};
input: { (a = parseInt('100')) != a }
expect: { (a = parseInt('100')) != a }
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
tranformation_sort_order_lesser_or_equal: {
options = {
comparisons: true,
}
};
input: { (a = parseInt('100')) <= a }
expect: { (a = parseInt('100')) <= a }
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
tranformation_sort_order_greater_or_equal: {
options = {
comparisons: true,
}
};
input: { (a = parseInt('100')) >= a }
expect: { (a = parseInt('100')) >= a }

View File

@@ -1,6 +1,6 @@
level_zero: {
options = {
keep_fnames: true,
keep_fnames: true
}
mangle = {
keep_fnames: true
@@ -29,7 +29,7 @@ level_zero: {
level_one: {
options = {
keep_fnames: true,
keep_fnames: true
}
mangle = {
keep_fnames: true
@@ -58,7 +58,7 @@ level_one: {
level_two: {
options = {
keep_fnames: true,
keep_fnames: true
}
mangle = {
keep_fnames: true
@@ -97,7 +97,7 @@ level_two: {
level_three: {
options = {
keep_fnames: true,
keep_fnames: true
}
mangle = {
keep_fnames: true

View File

@@ -4,7 +4,7 @@ unsafe_undefined: {
options = {
conditionals: true,
if_return: true,
unsafe_undefined: true,
unsafe: true
}
mangle = {}
input: {
@@ -30,7 +30,7 @@ keep_fnames: {
options = {
conditionals: true,
if_return: true,
unsafe_undefined: true,
unsafe: true
}
mangle = {
keep_fnames: true

View File

@@ -1,7 +1,6 @@
typeof_eq_undefined: {
options = {
comparisons: true,
typeofs: true,
comparisons: true
}
input: {
var a = typeof b != "undefined";
@@ -24,8 +23,7 @@ typeof_eq_undefined: {
typeof_eq_undefined_ie8: {
options = {
comparisons: true,
ie: true,
typeofs: true,
ie8: true,
}
input: {
var a = typeof b != "undefined";
@@ -47,8 +45,7 @@ typeof_eq_undefined_ie8: {
undefined_redefined: {
options = {
comparisons: true,
typeofs: true,
comparisons: true
}
input: {
function f(undefined) {
@@ -61,8 +58,7 @@ undefined_redefined: {
undefined_redefined_mangle: {
options = {
comparisons: true,
typeofs: true,
comparisons: true
}
mangle = {}
input: {

View File

@@ -22,17 +22,18 @@ else_with_empty_statement: {
conditional_false_stray_else_in_loop: {
options = {
booleans: true,
comparisons: true,
conditionals: false,
dead_code: true,
evaluate: true,
hoist_vars: true,
if_return: true,
join_vars: true,
loops: true,
side_effects: true,
unused: true,
evaluate : true,
comparisons : true,
booleans : true,
unused : true,
loops : true,
side_effects : true,
dead_code : true,
hoist_vars : true,
join_vars : true,
if_return : true,
cascade : true,
conditionals : false,
}
input: {
for (var i = 1; i <= 4; ++i) {
@@ -40,9 +41,6 @@ conditional_false_stray_else_in_loop: {
console.log(i);
}
}
expect_exact: "for(var i=1;i<=4;++i)if(i<=2);else console.log(i);"
expect_stdout: [
"3",
"4",
]
expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);"
expect_stdout: true
}

291
test/compress/issue-1466.js Normal file
View File

@@ -0,0 +1,291 @@
same_variable_in_multiple_for_loop: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
for (let i = 0; i < 3; i++) {
let a = 100;
console.log(i, a);
for (let i = 0; i < 2; i++) {
console.log(i, a);
let c = 2;
console.log(c);
}
}
}
expect: {
for (let o = 0; o < 3; o++) {
let l = 100;
console.log(o, l);
for (let o = 0; o < 2; o++) {
console.log(o, l);
let c = 2;
console.log(c);
}
}
}
expect_stdout: true
}
same_variable_in_multiple_forOf: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
var test = [ "a", "b", "c" ];
for (let tmp of test) {
console.log(tmp);
let dd;
dd = [ "e", "f", "g" ];
for (let tmp of dd) {
console.log(tmp);
}
}
}
expect: {
var test = [ "a", "b", "c" ];
for (let o of test) {
console.log(o);
let e;
e = [ "e", "f", "g" ];
for (let o of e)
console.log(o);
}
}
expect_stdout: true
}
same_variable_in_multiple_forIn: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: false,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
var test = [ "a", "b", "c" ];
for (let tmp in test) {
console.log(tmp);
let dd;
dd = [ "e", "f", "g" ];
for (let tmp in test) {
console.log(tmp);
}
}
}
expect: {
var test = [ "a", "b", "c" ];
for (let o in test) {
console.log(o);
let e;
e = [ "e", "f", "g" ];
for (let o in test)
console.log(o);
}
}
expect_stdout: true
}
different_variable_in_multiple_for_loop: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
for (let i = 0; i < 3; i++) {
let a = 100;
console.log(i, a);
for (let j = 0; j < 2; j++) {
console.log(j, a);
let c = 2;
console.log(c);
}
}
}
expect: {
for (let o = 0; o < 3; o++) {
let l = 100;
console.log(o, l);
for (let o = 0; o < 2; o++) {
console.log(o, l);
let c = 2;
console.log(c);
}
}
}
expect_stdout: true
}
different_variable_in_multiple_forOf: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
var test = [ "a", "b", "c" ];
for (let tmp of test) {
console.log(tmp);
let dd;
dd = [ "e", "f", "g" ];
for (let t of dd) {
console.log(t);
}
}
}
expect: {
var test = [ "a", "b", "c" ];
for (let o of test) {
console.log(o);
let e;
e = [ "e", "f", "g" ];
for (let o of e)
console.log(o);
}
}
expect_stdout: true
}
different_variable_in_multiple_forIn: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: false,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
var test = [ "a", "b", "c" ];
for (let tmp in test) {
console.log(tmp);
let dd;
dd = [ "e", "f", "g" ];
for (let t in test) {
console.log(t);
}
}
}
expect: {
var test = [ "a", "b", "c" ];
for (let o in test) {
console.log(o);
let e;
e = [ "e", "f", "g" ];
for (let o in test)
console.log(o);
}
}
expect_stdout: true
}
more_variable_in_multiple_for: {
options = {
hoist_funs: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: false,
keep_fargs: true,
if_return: true,
join_vars: true,
cascade: true,
side_effects: true,
collapse_vars: true,
}
mangle = {}
input: {
for (let a = 9, i = 0; i < 20; i += a) {
let b = a++ + i;
console.log(a, b, i);
for (let k = b, m = b*b, i = 0; i < 10; i++) {
console.log(a, b, m, k, i);
}
}
}
expect: {
for (let o = 9, l = 0; l < 20; l += o) {
let c = o++ + l;
console.log(o, c, l);
for (let l = c, e = c * c, f = 0; f < 10; f++)
console.log(o, c, e, l, f);
}
}
expect_stdout: true
}

View File

@@ -1,9 +1,9 @@
screw_ie8: {
options = {
ie: false,
ie8: false,
}
mangle = {
ie: false,
ie8: false,
}
input: {
try { throw "foo"; } catch (x) { console.log(x); }
@@ -16,10 +16,10 @@ screw_ie8: {
support_ie8: {
options = {
ie: true,
ie8: true,
}
mangle = {
ie: true,
ie8: true,
}
input: {
try { throw "foo"; } catch (x) { console.log(x); }
@@ -61,7 +61,7 @@ unsafe_undefined: {
options = {
conditionals: true,
if_return: true,
unsafe_undefined: true,
unsafe: true,
}
mangle = {}
input: {
@@ -85,3 +85,15 @@ unsafe_undefined: {
}
expect_stdout: true
}
runtime_error: {
input: {
const a = 1;
console.log(a++);
}
expect: {
const a = 1;
console.log(a++);
}
expect_stdout: true
}

View File

@@ -2,7 +2,6 @@ chained_evaluation_1: {
options = {
collapse_vars: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
@@ -29,7 +28,6 @@ chained_evaluation_2: {
options = {
collapse_vars: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
@@ -52,30 +50,3 @@ chained_evaluation_2: {
})();
}
}
chained_evaluation_3: {
options = {
collapse_vars: true,
evaluate: 10,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a = "long piece of string";
(function() {
var b = a, c;
c = f(b);
c.bar = b;
})();
})();
}
expect: {
(function() {
(function() {
f("long piece of string").bar = "long piece of string";
})();
})();
}
}

View File

@@ -1,7 +1,8 @@
issue_1639_1: {
options = {
booleans: true,
collapse_vars: true,
cascade: true,
conditionals: true,
evaluate: true,
join_vars: true,
@@ -11,6 +12,7 @@ issue_1639_1: {
}
input: {
var a = 100, b = 10;
var L1 = 5;
while (--L1 > 0) {
if ((--b), false) {
@@ -19,21 +21,21 @@ issue_1639_1: {
}
}
}
console.log(a, b);
}
expect: {
for (var a = 100, b = 10, L1 = 5, ignore; --L1 > 0;) {
--b;
}
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
if (--b, !1) var ignore = 0;
console.log(a, b);
}
expect_stdout: "100 6"
expect_stdout: true
}
issue_1639_2: {
options = {
booleans: true,
collapse_vars: true,
cascade: true,
conditionals: true,
evaluate: true,
join_vars: true,
@@ -42,12 +44,14 @@ issue_1639_2: {
}
input: {
var a = 100, b = 10;
function f19() {
if (++a, false)
if (a)
if (++a);
}
f19();
console.log(a, b);
}
expect: {
@@ -58,13 +62,13 @@ issue_1639_2: {
f19(),
console.log(a, b);
}
expect_stdout: "101 10"
expect_stdout: true
}
issue_1639_3: {
options = {
booleans: true,
collapse_vars: true,
cascade: true,
conditionals: true,
evaluate: true,
sequences: true,
@@ -80,5 +84,5 @@ issue_1639_3: {
a++,
console.log(a, b);
}
expect_stdout: "101 10"
expect_stdout: true
}

View File

@@ -1,6 +1,7 @@
f7: {
options = {
booleans: true,
cascade: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
@@ -14,7 +15,6 @@ f7: {
negate_iife: true,
passes: 3,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
@@ -35,7 +35,11 @@ f7: {
console.log(a, b);
}
expect_exact: [
"console.log(100, 100);",
"var b = 10;",
"",
"!function() {",
" for (;b = 100, !1; ) ;",
"}(), console.log(100, b);",
]
expect_stdout: "100 100"
expect_stdout: true
}

View File

@@ -1,6 +1,5 @@
side_effects_catch: {
options = {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
@@ -35,7 +34,6 @@ side_effects_catch: {
side_effects_else: {
options = {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
@@ -64,7 +62,6 @@ side_effects_else: {
side_effects_finally: {
options = {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
@@ -101,7 +98,6 @@ side_effects_finally: {
side_effects_label: {
options = {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
@@ -134,7 +130,6 @@ side_effects_label: {
side_effects_switch: {
options = {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,

View File

@@ -1,10 +1,10 @@
mangle_catch: {
options = {
ie: false,
ie8: false,
toplevel: false,
}
mangle = {
ie: false,
ie8: false,
toplevel: false,
}
input: {
@@ -22,11 +22,11 @@ mangle_catch: {
mangle_catch_ie8: {
options = {
ie: true,
ie8: true,
toplevel: false,
}
mangle = {
ie: true,
ie8: true,
toplevel: false,
}
input: {
@@ -44,11 +44,11 @@ mangle_catch_ie8: {
mangle_catch_var: {
options = {
ie: false,
ie8: false,
toplevel: false,
}
mangle = {
ie: false,
ie8: false,
toplevel: false,
}
input: {
@@ -66,11 +66,11 @@ mangle_catch_var: {
mangle_catch_var_ie8: {
options = {
ie: true,
ie8: true,
toplevel: false,
}
mangle = {
ie: true,
ie8: true,
toplevel: false,
}
input: {
@@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
mangle_catch_toplevel: {
options = {
ie: false,
ie8: false,
toplevel: true,
}
mangle = {
ie: false,
ie8: false,
toplevel: true,
}
input: {
@@ -104,17 +104,17 @@ mangle_catch_toplevel: {
}
console.log(a);
}
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
expect_stdout: "PASS"
}
mangle_catch_ie8_toplevel: {
options = {
ie: true,
ie8: true,
toplevel: true,
}
mangle = {
ie: true,
ie8: true,
toplevel: true,
}
input: {
@@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
mangle_catch_var_toplevel: {
options = {
ie: false,
ie8: false,
toplevel: true,
}
mangle = {
ie: false,
ie8: false,
toplevel: true,
}
input: {
@@ -148,17 +148,17 @@ mangle_catch_var_toplevel: {
}
console.log(a);
}
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
expect_stdout: "PASS"
}
mangle_catch_var_ie8_toplevel: {
options = {
ie: true,
ie8: true,
toplevel: true,
}
mangle = {
ie: true,
ie8: true,
toplevel: true,
}
input: {
@@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
mangle_catch_redef_1: {
options = {
ie: false,
ie8: false,
toplevel: false,
}
mangle = {
ie: false,
ie8: false,
toplevel: false,
}
input: {
@@ -198,11 +198,11 @@ mangle_catch_redef_1: {
mangle_catch_redef_1_ie8: {
options = {
ie: true,
ie8: true,
toplevel: false,
}
mangle = {
ie: true,
ie8: true,
toplevel: false,
}
input: {
@@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
mangle_catch_redef_1_toplevel: {
options = {
ie: false,
ie8: false,
toplevel: true,
}
mangle = {
ie: false,
ie8: false,
toplevel: true,
}
input: {
@@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
mangle_catch_redef_1_ie8_toplevel: {
options = {
ie: true,
ie8: true,
toplevel: true,
}
mangle = {
ie: true,
ie8: true,
toplevel: true,
}
input: {
@@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
mangle_catch_redef_2: {
options = {
ie: false,
ie8: false,
toplevel: false,
}
mangle = {
ie: false,
ie8: false,
toplevel: false,
}
input: {
@@ -285,11 +285,11 @@ mangle_catch_redef_2: {
mangle_catch_redef_2_ie8: {
options = {
ie: true,
ie8: true,
toplevel: false,
}
mangle = {
ie: true,
ie8: true,
toplevel: false,
}
input: {
@@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
mangle_catch_redef_2_toplevel: {
options = {
ie: false,
ie8: false,
toplevel: true,
}
mangle = {
ie: false,
ie8: false,
toplevel: true,
}
input: {
@@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
mangle_catch_redef_2_ie8_toplevel: {
options = {
ie: true,
ie8: true,
toplevel: true,
}
mangle = {
ie: true,
ie8: true,
toplevel: true,
}
input: {
@@ -345,103 +345,3 @@ mangle_catch_redef_2_ie8_toplevel: {
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
expect_stdout: "undefined"
}
mangle_catch_redef_3: {
mangle = {
ie: false,
toplevel: false,
}
input: {
var o = "PASS";
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
}
f(), f();
})();
}
console.log(o);
}
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_toplevel: {
mangle = {
ie: false,
toplevel: true,
}
input: {
var o = "PASS";
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
}
f(), f();
})();
}
console.log(o);
}
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8: {
mangle = {
ie: true,
toplevel: false,
}
input: {
var o = "PASS";
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
}
f(), f();
})();
}
console.log(o);
}
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8_toplevel: {
mangle = {
ie: true,
toplevel: true,
}
input: {
var o = "PASS";
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
}
f(), f();
})();
}
console.log(o);
}
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -1,6 +1,27 @@
function_iife_catch: {
mangle = {
ie: false,
ie8: false,
}
input: {
function f(n) {
!function() {
try {
throw 0;
} catch (n) {
var a = 1;
console.log(n, a);
}
}();
}
f();
}
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
expect_stdout: "0 1"
}
function_iife_catch_ie8: {
mangle = {
ie8: true,
}
input: {
function f(n) {
@@ -19,58 +40,37 @@ function_iife_catch: {
expect_stdout: "0 1"
}
function_iife_catch_ie8: {
mangle = {
ie: true,
}
input: {
function f(n) {
!function() {
try {
throw 0;
} catch (n) {
var a = 1;
console.log(n, a);
}
}();
}
f();
}
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
expect_stdout: "0 1"
}
function_catch_catch: {
mangle = {
ie: false,
}
input: {
var o = 0;
function f() {
try {
throw 1;
} catch (c) {
try {
throw 2;
} catch (o) {
var o = 3;
console.log(o);
}
}
console.log(o);
}
f();
}
expect_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
expect_stdout: [
"3",
"undefined",
]
}
function_catch_catch_ie8: {
mangle = {
ie: true,
ie8: false,
}
input: {
var o = 0;
function f() {
try {
throw 1;
} catch (c) {
try {
throw 2;
} catch (o) {
var o = 3;
console.log(o);
}
}
console.log(o);
}
f();
}
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
expect_stdout: [
"3",
"undefined",
]
}
function_catch_catch_ie8: {
mangle = {
ie8: true,
}
input: {
var o = 0;

View File

@@ -7,7 +7,7 @@ case_1: {
input: {
var a = 0, b = 1;
switch (true) {
case a || true:
case a, true:
default:
b = 2;
case true:
@@ -17,7 +17,7 @@ case_1: {
expect: {
var a = 0, b = 1;
switch (true) {
case a || true:
case a, true:
b = 2;
}
console.log(a, b);

View File

@@ -1,7 +1,5 @@
mangle_props: {
mangle = {
properties: true,
}
mangle_props = {}
input: {
var obj = {
undefined: 1,
@@ -46,7 +44,7 @@ mangle_props: {
obj[1/0],
obj["Infinity"],
obj[-1/0],
obj[-(1/0)],
obj[-1/0],
obj["-Infinity"],
obj[null],
obj["null"]
@@ -56,12 +54,10 @@ mangle_props: {
}
numeric_literal: {
mangle = {
properties: true,
}
beautify = {
beautify: true,
}
mangle_props = {}
input: {
var obj = {
0: 0,
@@ -84,19 +80,19 @@ numeric_literal: {
' 0: 0,',
' "-0": 1,',
' 42: 2,',
' 42: 3,',
' "42": 3,',
' 37: 4,',
' o: 5,',
' a: 5,',
' 1e42: 6,',
' b: 7,',
' 1e42: 8',
' "1e+42": 8',
'};',
'',
'console.log(obj[-0], obj[-""], obj["-0"]);',
'',
'console.log(obj[42], obj["42"]);',
'',
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
'',
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
]
@@ -107,139 +103,3 @@ numeric_literal: {
"8 7 8",
]
}
identifier: {
mangle = {
properties: true,
}
input: {
var obj = {
abstract: 1,
boolean: 2,
byte: 3,
char: 4,
class: 5,
double: 6,
enum: 7,
export: 8,
extends: 9,
final: 10,
float: 11,
goto: 12,
implements: 13,
import: 14,
int: 15,
interface: 16,
let: 17,
long: 18,
native: 19,
package: 20,
private: 21,
protected: 22,
public: 23,
short: 24,
static: 25,
super: 26,
synchronized: 27,
this: 28,
throws: 29,
transient: 30,
volatile: 31,
yield: 32,
false: 33,
null: 34,
true: 35,
break: 36,
case: 37,
catch: 38,
const: 39,
continue: 40,
debugger: 41,
default: 42,
delete: 43,
do: 44,
else: 45,
finally: 46,
for: 47,
function: 48,
if: 49,
in: 50,
instanceof: 51,
new: 52,
return: 53,
switch: 54,
throw: 55,
try: 56,
typeof: 57,
var: 58,
void: 59,
while: 60,
with: 61,
};
}
expect: {
var obj = {
e: 1,
t: 2,
n: 3,
a: 4,
i: 5,
o: 6,
r: 7,
l: 8,
s: 9,
c: 10,
f: 11,
u: 12,
d: 13,
h: 14,
p: 15,
b: 16,
v: 17,
w: 18,
y: 19,
g: 20,
m: 21,
k: 22,
x: 23,
j: 24,
z: 25,
q: 26,
A: 27,
B: 28,
C: 29,
D: 30,
F: 31,
G: 32,
false: 33,
null: 34,
true: 35,
H: 36,
I: 37,
J: 38,
K: 39,
L: 40,
M: 41,
N: 42,
O: 43,
P: 44,
Q: 45,
R: 46,
S: 47,
T: 48,
U: 49,
V: 50,
W: 51,
X: 52,
Y: 53,
Z: 54,
$: 55,
_: 56,
ee: 57,
te: 58,
ne: 59,
ae: 60,
ie: 61,
};
}
}

View File

@@ -1,8 +1,6 @@
unary_prefix: {
options = {
evaluate: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}

View File

@@ -1,7 +1,6 @@
iife_for: {
options = {
negate_iife: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -27,7 +26,6 @@ iife_for: {
iife_for_in: {
options = {
negate_iife: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -53,7 +51,6 @@ iife_for_in: {
iife_do: {
options = {
negate_iife: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -83,7 +80,6 @@ iife_do: {
iife_while: {
options = {
negate_iife: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -125,8 +121,8 @@ label_do: {
label_while: {
options = {
dead_code: true,
evaluate: true,
dead_code: true,
loops: true,
}
input: {
@@ -134,5 +130,5 @@ label_while: {
L: while (0) continue L;
}
}
expect_exact: "function f(){L:0}"
expect_exact: "function f(){L:;}"
}

View File

@@ -0,0 +1,34 @@
compress_new_function: {
options = {
unsafe: true
}
input: {
new Function("aa, bb", 'return aa;');
}
expect: {
Function("a", "b", "return a");
}
}
compress_new_function_with_destruct: {
options = {
unsafe: true,
ecma: 6
}
beautify = {
ecma: 6
}
input: {
new Function("aa, [bb]", 'return aa;');
new Function("aa, {bb}", 'return aa;');
new Function("[[aa]], [{bb}]", 'return aa;');
}
expect: {
Function("a", "[b]", "return a");
Function("a", "{bb}", "return a");
Function("[[a]]", "[{bb}]", 'return a');
}
}

Some files were not shown because too many files have changed in this diff Show More