1529ab96 started to do this (by considering holes to be separate from
"undefined") but it still converted
[1,,] (length 2, last element hole, trailing comma)
to
[1,] (length 1, trailing comma)
Unfortunately the test suite doesn't really make this clear: the new test here
passes with or without this patch because run-tests.js beautifys the expected
output (in "make_code"), which does the incorrect transformation! If you make
some manual change to arrays.js to make the test fail and see the INPUT and
OUTPUT, then you can see that without this fix, [1,,] -> [1,], and with this fix
it stays [1,,].
Since \0 might be mistakenly interpreted as octal if followed by a
number and using literal null is in some cases interpreted as end of
string, escape null as \x00.
1b6bcca7 was a first attempt at this. That commit made Uglify stop replacing
holes with undefined, but instead it started replacing undefined with
holes. This is slightly problematic, because there is a difference between a
hole and an undefined value. More problematically, it changed [1,undefined] to
[1,] which generally doesn't even parse as a hole (just as a trailing comma), so
it didn't even preserve the length of the array!
Instead, parse holes as their own special AST node which prints invisibly.
This is useful while compressing generated code; for example compressing JS
compiled by CoffeeScript (assuming you got a source map):
uglifyjs2 --in-source-map generated.js.map \
--source-map uglified.js.map \
-o uglified.js
The above assumes you have a "generated.js.map" file which is the source
mapping between your CoffeeScript and the generated.js (compiled output from
CoffeeScript). The name of the input file is not present in this example;
it will be fetched from the source map (but it can be passed manually too).
The output will be in "uglified.js" and the output map "uglified.js.map"
will actually map to the original CoffeeScript code, rather than to
generated.js.
- a = a + x ==> a+=x
- joining consecutive var statements (hoisting is not always desirable)
- x == false ==> x == 0, x != true ==> x != 1
- x, x ==> x; x = exp(), x ==> x = exp()
- discarding useless break-s
- all symbols now have a `thedef` property which is a SymbolDef object,
instead of the `uniq` that we had before (pointing to the first occurrence
of the name as declaration).
- for undeclared symbols we still create a SymbolDef object in the toplevel
scope but mark it "undeclared"
- we can now call figure_out_scope after squeezing, which is useful in order
not to mangle names that were dropped by the squeezer