Process variable definitions with or without assigned values against:
- `arguments`
- named function arguments
- multiple definitions within same scope
Essentially demote variable declarations with no value assignments.
Also fixed invalid use of `AST_VarDef` over `arguments` - should use a member of `AST_SymbolDeclaration` instead.
Conditions including strict mode would make `delete` return `true` or `false`, and are too complex to be evaluated by the compressor.
Suppress assignment folding into said operator.
fixes#1685
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
`AST_Try` is an `AST_Block`, so besides try block we also need to inspect catch and finally blocks for possible side effects.
Also extend this functionality to handle `AST_If` and `AST_LabeledStatement` while we are at it.
fixes#1673
Turns out the only place in `Compressor` which can generate invalid `AST_For.init` is within `drop_unused()`, so focus the fix-up efforts.
supercedes #1652fixes#1656
- #1634 bars variables with cross-scope references in between to collapse
- but if assigned value is side-effect-free, no states can be modified, so it is safe to move
- mention performance anomaly in Node 7 and drop from CI
- remove unused npm "scripts"
- mark browserify dependency as optional
- stop `test/mozilla-ast.js` from spamming console output in later versions of Node.js
That particular version of Node.js has messed up error messages, so provide a version-specific workaround.
Also fixed an formatting issue which would cause `expect_stdout` to fail if error message contains excerpts of input.
Apply `expect_stdout` to more applicable tests.
The following is wrong:
`a == (b ? a : c)` => `b`
Because:
- `b` may not be boolean
- `a` might have side effects
- `a == a` is not always `true` (think `NaN`)
- `a == c` is not always `false`
`input` and `expect` are parsed as `AST_BlockStatement` which does not support `AST_Directive` by default.
Emulate that by transforming preceding `AST_SimpleStatement`s of `AST_String` into `AST_Directive`.
`reduce_vars` enables substitution of variables but did not clone the value's `AST_Node`.
This confuses `collapse_vars` and result in invalid AST and subsequent crash.
fixes#1609
Liberal use of `Compressor.transform()` and `AST_Node.optimize()` presents an issue for look-up operations like `TreeWalker.in_boolean_context()` and `TreeWalker.parent()`.
This is an incremental fix such that `AST_Node.optimize()` would now contain the correct stack information when called correctly.
Self-referenced function has non-fixed values assigned to its parameters.
Let `unused` & `!keep_fnames` do the scanning, then apply `reduce_vars` only to unnamed functions.
fixes#1595
As patched on `harmony`, `statement()` is the only user of `embed_tokens()` with a missing error branch.
Updated test case and match up with `harmony` to facilitate future merging.
- one-use function call => IIFE should take `eval()` & `arguments` into account
- if unused parameter cannot be eliminated, replace it with `0`
fixes#1583
those were not optimised for `unused` before, which made it necessary for `reduce_vars` to have separate steps for `keep_fnames`
docs update by @kzc
closes#1577
Function expression can be assigned to a variable and be given a name. Ensure function name is the reduced variable before clearing it out.
fixes#1573fixes#1575
- omitting trailing semi-colon in do-while breaks non-browser parser, e.g. uglify-js 1.x
- trailing semi-colon only breaks IE8 if followed by `else` or `while`
- always use braces in do-while body to workaround 2nd case with no size loss in compression
fixes#1568
`AST_Label.references` get `.initialize()` to `[]` every time after `.clone()`
So walk down the tree to pick up the cloned `AST_LoopControl` pieces and put it back together.
`unsafe` turns undefined keyword into a variable of the same name if found, but that interferes with other related optimisations.
Keep track of such transformations to ensure zero information loss in the process.
Bookmarklet for instance implicitedly assumes a "completion value" without using `return`.
The `expression` option now supports such use cases.
Optimisations on IIFEs also enhanced.
fixes#354fixes#543fixes#625fixes#628fixes#640closes#1293
Avoid variable substitution in the following cases:
- use of variable before declaration
- declaration within conditional code blocks
- declaration within loop body
fixes#1518fixes#1525
Modules like webpack and grunt-contrib-uglify still uses `ast.transform(compressor)` before `Compressor.compress(ast)` was introduced.
Workaround this compatibility issue by deactivating `reduce_vars` in such case.
Also fix use case with omitted `options` when calling `Compressor()`.
fixes#1516
A function call or IIFE with an immediately preceding comment
containing `@__PURE__` or `#__PURE__` is deemed to be a
side-effect-free pure function call and can potentially be
dropped.
Depends on `side_effects` option.
`[#@]__PURE__` hint will be removed from comment when pure
call is dropped.
fixes#1261closes#1448
- support arrays, objects & AST_Node
- support `"a.b":1` on both cli & API
- emit warning if variable is modified
- override top-level variables
fixes#1416closes#1198closes#1469
previously test cases with the same name would be skipped except for the last one
`test/run-test.js` will now report duplicated names as errors
closes#1461
- remove extra tree scanning phase for `negate_iife`
- `negate_iife` now only deals with the narrowest form, i.e. IIFE sitting directly under `AST_SimpleStatement`
- `booleans`, `conditionals` etc. will now take care the rest via more accurate accounting
- `a(); void b();` => `a(); b();`
fixes#1288closes#1451
- assign statement does not count towards variable usage by default
- only works with assignments on the same scope level as declaration
- can be disabled with `unused` set to "keep_assign"
- `toplevel` to drop unused top-level variables and/or functions
- `top_retain` to whitelist top-level exceptions
closes#1450
- remove call to evaluate() in is_constant() and let nested optimize() does its job instead
- reject RegExp in is_constant() and remove special case logic under collapse_vars
- operands to conditionals optimisation are now always evaluate()-ed
- throw error in constant_value() instead of returning undefined to catch possible bugs, similar to make_node_from_constant()
- optimise binary boolean operators under `evaluate` instead of `conditionals`
If using `inSourceMap` this fix will ensure the copying of `sourcesContent` is based on potentially normalized `sources` values (https://github.com/mozilla/source-map/blob/master/lib/source-map-consumer.js#L304-L309).
For example `normalize` (https://github.com/mozilla/source-map/blob/master/lib/util.js#L80-L123) will rewrite `./dist/mySource.js` to `dist/mySource.js` in the target `_sources` of the `SourceMapConsumer`. As a result `orig_map.sourceContentFor(source, true);` would return `null` since the orginal `source` was no longer available in the consumer. By using the keys generating from the `SourceMapConsumer.constructor` consistency is ensured.
Using the symbol declaration tracking of UglifyJS doesn't make sense here
anyway, `arguments` always comes from something in the current scope.
fixes#1299
Fixes: #1247
Fix --mangle-props and --name-cache inconsistency.
AST_Dot and AST_Sub properties are now mangled by --mangle-props
without regard to being used in an assignment statement.
Note: if --mangle-props is used then *all* javascript files used must
be uglified with the same mangle options.
Fix the ignore_quoted=true mangle option, also known as
`--mangle-props=unquoted`. If a given property is quoted anywhere
it will not be mangled in any quoted or non-quoted context.
* Escaped newlines should also produce SyntaxError
* Fix multiline comment parsing and add tests
* Adapt makePredicate to handle \u2028 and \u2029
* Move up nlb check in regex so it's checked before any escape handling
* Change error messages to conform ecma standard
* Find_eol not recornizing \u2028 and \u2029 as line terminator
* Remove \u180e as it is removed in unicode 6.3.0 from the category zs
catch identifier is mangled correctly for ES5 standards-compliant JS engines by default.
Unconditionally use the ie8 if/do-while workaround whether or not --screw-ie8 is enabled.
To support non-standard ie8 javascript use: uglifyjs --support-ie8