Compare commits

...

81 Commits

Author SHA1 Message Date
Alex Lam S.L
6ad8e1081f v3.6.6 2019-11-01 13:40:03 +08:00
Alex Lam S.L
815eff1f7c enhance if_return (#3560) 2019-11-01 02:08:31 +08:00
Alex Lam S.L
1e9b576ee9 fix corner case in evaluate (#3559)
fixes #3558
2019-11-01 00:01:25 +08:00
Alex Lam S.L
3797458365 enhance conditionals (#3557) 2019-10-31 09:33:46 +08:00
Alex Lam S.L
1858c2018c enhance typeofs (#3556) 2019-10-31 08:00:04 +08:00
Alex Lam S.L
ec7f071272 fix corner case in dead_code (#3553)
fixes #3552
2019-10-30 14:21:22 +08:00
Alex Lam S.L
f1eb03f2c0 enhance dead_code (#3551) 2019-10-30 06:34:54 +08:00
Alex Lam S.L
0f4cfa877a fix corner case in comments (#3550) 2019-10-30 03:49:39 +08:00
Alex Lam S.L
1d5c2becbd enhance evaluate (#3549) 2019-10-29 19:51:55 +08:00
Alex Lam S.L
22a09ea7c5 fix corner case in unsafe_math (#3548)
fixes #3547
2019-10-29 17:06:57 +08:00
Alex Lam S.L
bad664c632 compress object literals (#3546) 2019-10-29 16:53:48 +08:00
Alex Lam S.L
8a191c0a84 v3.6.5 2019-10-29 12:55:28 +08:00
Alex Lam S.L
83fb8b4ca1 fix corner case in ie8 (#3543)
fixes #3542
2019-10-28 23:54:27 +08:00
Alex Lam S.L
f38e31bd1e fix corner case in evaluate (#3540)
fixes #3539
2019-10-28 19:56:42 +08:00
Alex Lam S.L
24e8b47977 improve ufuzz resilience (#3541) 2019-10-28 18:08:51 +08:00
Alex Lam S.L
95618793a4 fix corner case in ufuzz (#3538) 2019-10-28 16:04:07 +08:00
Alex Lam S.L
2f3b460212 fix & enhance unsafe_math (#3537)
closes #3535
fixes #3536
2019-10-28 13:37:08 +08:00
Alex Lam S.L
06e135e35f migrate CI workaround (#3534) 2019-10-27 17:29:54 +08:00
Alex Lam S.L
ebbf3d4a51 improve ufuzz resilience (#3533) 2019-10-27 14:17:35 +08:00
Alex Lam S.L
a270ba6b59 fix corner cases in unsafe_math (#3532)
fixes #3531
2019-10-27 08:25:11 +08:00
Alex Lam S.L
37f35e4ac2 prevent tty truncation in test/compress (#3530) 2019-10-27 05:00:21 +08:00
Alex Lam S.L
50a578c1f6 compress arithmetic expressions further (#3529) 2019-10-27 03:07:07 +08:00
Alex Lam S.L
85237b08d4 fix corner case in collapse_vars (#3527)
fixes #3526
2019-10-26 05:41:02 +08:00
Alex Lam S.L
27b159e711 separate ufuzz job failures (#3525) 2019-10-25 02:06:29 +08:00
Alex Lam S.L
82b3eed5ef fix corner case in ie8 & mangle (#3524)
fixes #3523
2019-10-24 23:43:19 +08:00
Alex Lam S.L
0f7aa41e33 fix corner case in collapse_vars (#3521)
fixes #3520
2019-10-24 01:13:57 +08:00
Alex Lam S.L
370c8e0385 v3.6.4 2019-10-23 15:38:05 +08:00
Alex Lam S.L
4240fba9b8 fix corner cases in unused (#3519) 2019-10-23 06:46:05 +08:00
Alex Lam S.L
267bc70d33 fix corner case in unused (#3517)
fixes #3515
2019-10-23 01:58:40 +08:00
Alex Lam S.L
a53ab99378 fix corner case in side_effects (#3514)
fixes #3512
2019-10-23 01:04:00 +08:00
Alex Lam S.L
02308a7b56 fix corner case in reduce_vars (#3510)
fixes #3509
2019-10-22 20:36:05 +08:00
Alex Lam S.L
0b3705e82f fix corner cases in inline (#3507)
fixes #3506
2019-10-22 15:41:55 +08:00
Alex Lam S.L
da5a21b240 fix GitHub Actions script for fuzzing (#3504) 2019-10-21 04:30:00 +08:00
Alex Lam S.L
5bd0cf8633 enable GitHub Actions (#3503) 2019-10-21 04:11:14 +08:00
Alex Lam S.L
9199ab5846 minor tweaks (#3502) 2019-10-20 15:19:19 +08:00
Alex Lam S.L
ca6dce43fe fix corner case in collapse_vars (#3501) 2019-10-20 03:53:20 +08:00
Alex Lam S.L
543dd7d3d7 fix corner case in comments (#3500) 2019-10-20 03:21:30 +08:00
Alex Lam S.L
6b4886c908 v3.6.3 2019-10-19 14:28:11 +08:00
Alex Lam S.L
0201cb4b52 fix corner case in unused (#3499)
fixes #3497
2019-10-18 20:08:05 +08:00
Alex Lam S.L
cd072317d0 fix corner case in unused (#3496)
fixes #3495
2019-10-18 17:09:43 +08:00
Alex Lam S.L
0785a15ace fix corner case in dead_code & ie8 (#3494)
fixes #3493
2019-10-17 09:58:05 +08:00
Alex Lam S.L
b1279a46d9 fix corner case in sequences (#3491)
fixes #3490
2019-10-17 09:57:50 +08:00
Alex Lam S.L
b571619d31 handle throw of non-Errors gracefully (#3492) 2019-10-17 06:29:02 +08:00
Alex Lam S.L
7b5350b459 tweak Travis CI execution environment (#3489) 2019-10-16 15:47:06 +08:00
Alex Lam S.L
1549db70e6 fix corner case in ie8 (#3487)
fixes #3486
2019-10-16 12:18:27 +08:00
Alex Lam S.L
8ff9a3c8fb fix corner cases in ie8 (#3485)
fixes #3484
2019-10-16 06:37:40 +08:00
Alex Lam S.L
91cae51d8f fix corner case in evaluate & ie8 (#3483)
fixes #3482
2019-10-16 01:09:16 +08:00
Alex Lam S.L
8af2f5fbcf fix corner case in rename (#3481)
fixes #3480
2019-10-15 19:44:07 +08:00
Alex Lam S.L
86a8016323 fix corner case in ie8 & mangle (#3479)
fixes #3478
2019-10-15 17:14:48 +08:00
David xu
009dcdae01 avoid mangling of MutationObserver properties (#3477) 2019-10-15 16:16:43 +08:00
Alex Lam S.L
f86f615d83 fix corner case in ie8 & mangle (#3476)
fixes #3475
2019-10-15 14:18:12 +08:00
Alex Lam S.L
d3d1d11926 fix corner case in ie8 & rename (#3474)
fixes #3473
2019-10-15 07:27:02 +08:00
Alex Lam S.L
736019b767 fix corner cases in ie8 (#3472)
fixes #3471
2019-10-14 18:15:40 +08:00
Alex Lam S.L
a39bdb5840 fix corner case with collapse_vars & ie8 (#3469)
fixes #3468
2019-10-14 13:34:35 +08:00
Alex Lam S.L
e8ab0a44b2 update dependency (#3470) 2019-10-14 13:34:22 +08:00
Alex Lam S.L
c3ca293e6b v3.6.2 2019-10-12 20:19:05 +08:00
Alex Lam S.L
516b67a43b minor tweaks to CI test scripts (#3467) 2019-10-12 05:36:38 +08:00
Alex Lam S.L
eba3a37bb5 fix boolean context detection (#3466)
fixes #3465
2019-10-12 03:42:57 +08:00
Alex Lam S.L
6d57ca1a59 improve source map handling (#3464)
fixes #2947
fixes #3277
fixes #3411
2019-10-11 03:52:33 +08:00
Alex Lam S.L
3320251b4b update benchmark URLs (#3462) 2019-10-11 01:00:09 +08:00
Alex Lam S.L
33c94d3bd9 detect boolean context across IIFEs (#3461) 2019-10-10 09:37:02 +08:00
Alex Lam S.L
b18f717b46 improve readability of --help ast (#3460) 2019-10-10 04:32:32 +08:00
Alex Lam S.L
a0d4b648bb remove extraneous property (#3459)
fixes #3455
2019-10-10 01:36:58 +08:00
Alex Lam S.L
6db880e16d clean up AST_Binary optimisation logic (#3458) 2019-10-09 23:45:41 +08:00
Alex Lam S.L
a82003d6ac v3.6.1 2019-10-07 14:36:46 +08:00
Alex Lam S.L
da9f1622fc report errors correctly in ufuzz (#3456) 2019-10-07 14:36:00 +08:00
Alex Lam S.L
8a4c7077bb account for catch in constant lambda expressions (#3454) 2019-10-06 16:51:37 +08:00
Alex Lam S.L
0a63f2f2b0 workaround V8 RegExp bug (#3453)
fixes #3434
2019-10-06 11:49:39 +08:00
Alex Lam S.L
931ac66638 fix corner case in hoist_props (#3452)
fixes #3440
2019-10-06 10:29:13 +08:00
Alex Lam S.L
35338a100f handle function/variable name collisions correctly (#3451)
fixes #3439
2019-10-06 08:51:38 +08:00
David xu
d57b606e73 exclude mangling of addEventListener parameters (#3445) 2019-10-06 05:29:08 +08:00
Sampson Crowley
00ada04111 facilitate Webpack compatibility (#3435)
Verbose application of `require.resolve` instead of `[].map`
2019-10-06 05:20:47 +08:00
Alex Lam S.L
a31c477fea fix variable scope determination (#3449)
fixes #3444
2019-10-06 05:13:44 +08:00
Alex Lam S.L
bde7418ce1 update & fix dependencies (#3450) 2019-10-06 03:10:12 +08:00
Alex Lam S.L
70bb304a0a v3.6.0 2019-05-30 15:30:00 +08:00
Alex Lam S.L
9d3b1efd86 fix corner case in assignments (#3430)
fixes #3429
2019-05-30 05:01:53 +08:00
Alex Lam S.L
482e1baea3 enhance assignments & unused (#3428)
closes #3427
2019-05-29 01:21:08 +08:00
Alex Lam S.L
e4f5ba1d29 v3.5.15 2019-05-21 14:26:58 +08:00
Alex Lam S.L
b9053c7a25 fix corner case in keep_fargs (#3424)
fixes #3423
2019-05-21 12:55:34 +08:00
Alex Lam S.L
d357a7aabc v3.5.14 2019-05-20 00:13:06 +08:00
Alex Lam S.L
ae77ebe5a5 fix corner case in arguments (#3421)
fixes #3420
2019-05-19 12:59:40 +08:00
48 changed files with 5446 additions and 998 deletions

27
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: CI
on: [ push, pull_request ]
jobs:
test:
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
node: [ "0.10", 0.12, 4, 6, 8, 10, latest ]
script: [ compress, mocha, release/benchmark, release/jetstream ]
name: ${{ matrix.os }} ${{ matrix.node }} ${{ matrix.script }}
runs-on: ${{ matrix.os }}
env:
NODE: ${{ matrix.node }}
TYPE: ${{ matrix.script }}
steps:
- uses: actions/checkout@v1
- shell: bash
run: |
git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh
nvs --version
nvs add node/$NODE
nvs use node/$NODE
node --version
npm --version --no-update-notifier
npm install --no-audit --no-optional --no-save --no-update-notifier
node test/$TYPE

25
.github/workflows/ufuzz.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Fuzzing
on:
schedule:
- cron: "*/15 * * * *"
jobs:
ufuzz:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
- shell: bash
run: |
git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh
nvs --version
nvs add node
nvs use node
node --version
npm --version --no-update-notifier
npm install --no-audit --no-optional --no-save --no-update-notifier
node test/ufuzz/job 3600000

View File

@@ -1,6 +1,6 @@
cache:
directories: tmp
language: generic
language: shell
matrix:
fast_finish: true
env:

View File

@@ -478,42 +478,42 @@ if (result.error) throw result.error;
## Minify options
- `warnings` (default `false`) — pass `true` to return compressor warnings
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
- `parse` (default `{}`) — pass an object if you wish to specify some
additional [parse options](#parse-options).
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
Pass an object to specify custom [compress options](#compress-options).
- `ie8` (default `false`) -- set to `true` to support IE8.
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
of function names. Useful for code relying on `Function.prototype.name`.
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
an object to specify [mangle options](#mangle-options) (see below).
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
Pass an object to specify custom [mangle property options](#mangle-properties-options).
- `output` (default `null`) pass an object if you wish to specify
additional [output options](#output-options). The defaults are optimized
for best compression.
- `sourceMap` (default `false`) - pass an object if you wish to specify
[source map options](#source-map-options).
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
variable and function name mangling and to drop unused variables and functions.
- `nameCache` (default `null`) - pass an empty object `{}` or a previously
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
used `nameCache` object if you wish to cache mangled variable and
property names across multiple invocations of `minify()`. Note: this is
a read/write property. `minify()` will read the name cache state of this
object and update it during minification so that it may be
reused or externally persisted by the user.
- `ie8` (default `false`) - set to `true` to support IE8.
- `output` (default `null`) — pass an object if you wish to specify
additional [output options](#output-options). The defaults are optimized
for best compression.
- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling
of function names. Useful for code relying on `Function.prototype.name`.
- `parse` (default `{}`) pass an object if you wish to specify some
additional [parse options](#parse-options).
- `sourceMap` (default `false`) -- pass an object if you wish to specify
[source map options](#source-map-options).
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
variable and function name mangling and to drop unused variables and functions.
- `warnings` (default `false`) — pass `true` to return compressor warnings
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
## Minify options structure
@@ -682,6 +682,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
where the return value is discarded, to avoid the parens that the
code generator would insert.
- `objects` (default: `true`) -- compact duplicate keys in object literals.
- `passes` (default: `1`) -- The maximum number of times to run compress.
In some cases more than one pass leads to further compressed code. Keep in
mind more passes will take more time.

View File

@@ -837,11 +837,10 @@ var AST_String = DEFNODE("String", "value quote", {
}
}, AST_Constant);
var AST_Number = DEFNODE("Number", "value literal", {
var AST_Number = DEFNODE("Number", "value", {
$documentation: "A number literal",
$propdoc: {
value: "[number] the numeric value",
literal: "[string] numeric value as string (optional)"
}
}, AST_Constant);
@@ -980,6 +979,15 @@ TreeWalker.prototype = {
|| p instanceof AST_Conditional
|| p.tail_node() === self) {
self = p;
} else if (p instanceof AST_Return) {
var fn;
do {
fn = this.parent(++i);
if (!fn) return false;
} while (!(fn instanceof AST_Lambda));
if (fn.name) return false;
self = this.parent(++i);
if (!self || self.TYPE != "Call" || self.expression !== fn) return false;
} else {
return false;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,39 @@
"use strict";
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;
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");
};
}
function read_source_map(name, code) {
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(\S+)\s*$/.exec(code);
if (!match) {
AST_Node.warn("inline source map not found: " + name);
return null;
function read_source_map(name, toplevel) {
var comments = toplevel.end.comments_after;
for (var i = comments.length; --i >= 0;) {
var comment = comments[i];
if (comment.type != "comment1") break;
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
if (!match) break;
if (match[1] == "sourceMappingURL") {
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
if (!match) break;
return to_ascii(match[2]);
}
}
return to_ascii(match[2]);
AST_Node.warn("inline source map not found: " + name);
}
function parse_source_map(content) {
@@ -134,10 +154,10 @@ function minify(files, options) {
source_maps = source_map_content && Object.create(null);
for (var name in files) if (HOP(files, name)) {
options.parse.filename = name;
options.parse.toplevel = parse(files[name], options.parse);
options.parse.toplevel = toplevel = parse(files[name], options.parse);
if (source_maps) {
if (source_map_content == "inline") {
var inlined_content = read_source_map(name, files[name]);
var inlined_content = read_source_map(name, toplevel);
if (inlined_content) {
source_maps[name] = parse_source_map(inlined_content);
}
@@ -146,7 +166,6 @@ function minify(files, options) {
}
}
}
toplevel = options.parse.toplevel;
}
if (quoted_props) {
reserve_quoted_keys(toplevel, quoted_props);

View File

@@ -403,7 +403,7 @@
var def = M.definition();
return {
type: "Identifier",
name: def ? def.mangled_name || def.name : M.name
name: def && def.mangled_name || M.name
};
});

View File

@@ -91,13 +91,11 @@ function OutputStream(options) {
comment_filter = function(comment) {
return comment.type != "comment5" && comments.test(comment.value);
};
}
else if (typeof comments === "function") {
} else if (typeof comments === "function") {
comment_filter = function(comment) {
return comment.type != "comment5" && comments(this, comment);
};
}
else if (comments === "some") {
} else if (comments === "some") {
comment_filter = is_some_comments;
} else { // NOTE includes "all" option
comment_filter = return_true;
@@ -136,8 +134,7 @@ function OutputStream(options) {
function make_string(str, quote) {
var dq = 0, sq = 0;
str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
function(s, i) {
str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s, i) {
switch (s) {
case '"': ++dq; return '"';
case "'": ++sq; return "'";
@@ -453,7 +450,7 @@ function OutputStream(options) {
var self = this;
var scan = node instanceof AST_Exit && node.value;
var comments = dump(node);
if (!comments) return;
if (!comments) comments = [];
if (scan) {
var tw = new TreeWalker(function(node) {
@@ -599,7 +596,6 @@ function OutputStream(options) {
}
print(encoded);
},
encode_string : encode_string,
next_indent : next_indent,
with_indent : with_indent,
with_block : with_block,
@@ -645,8 +641,7 @@ function OutputStream(options) {
var self = this, generator = self._codegen;
if (self instanceof AST_Scope) {
active_scope = self;
}
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
} else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
use_asm = active_scope;
}
function doit() {
@@ -1045,11 +1040,9 @@ function OutputStream(options) {
return;
}
b = b.alternative;
}
else if (b instanceof AST_StatementWithBody) {
} else if (b instanceof AST_StatementWithBody) {
b = b.body;
}
else break;
} else break;
}
force_statement(self.body, output);
}
@@ -1357,7 +1350,7 @@ function OutputStream(options) {
});
DEFPRINT(AST_Symbol, function(self, output) {
var def = self.definition();
output.print_name(def ? def.mangled_name || def.name : self.name);
output.print_name(def && def.mangled_name || self.name);
});
DEFPRINT(AST_Hole, noop);
DEFPRINT(AST_This, function(self, output) {
@@ -1383,8 +1376,27 @@ function OutputStream(options) {
if (regexp.raw_source) {
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
}
str = output.to_utf8(str);
output.print(str);
output.print(output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(seq) {
switch (seq[1]) {
case "\n": return "\\n";
case "\r": return "\\r";
case "\t": return "\t";
case "\b": return "\b";
case "\f": return "\f";
case "\0": return "\0";
case "\x0B": return "\v";
case "\u2028": return "\\u2028";
case "\u2029": return "\\u2029";
default: return seq;
}
}).replace(/[\n\r\u2028\u2029]/g, function(c) {
switch (c) {
case "\n": return "\\n";
case "\r": return "\\r";
case "\u2028": return "\\u2028";
case "\u2029": return "\\u2029";
}
}));
var p = output.parent();
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
output.print(" ");

View File

@@ -234,6 +234,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
directives : {},
directive_stack : []
};
var prev_was_dot = false;
function peek() {
return S.text.charAt(S.pos);
@@ -286,16 +287,12 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
S.tokpos = S.pos;
}
var prev_was_dot = false;
function token(type, value, is_comment) {
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX[value]) ||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]) ||
(type == "punc" && PUNC_BEFORE_EXPRESSION[value]));
if (type == "punc" && value == ".") {
prev_was_dot = true;
} else if (!is_comment) {
prev_was_dot = false;
}
S.regex_allowed = type == "operator" && !UNARY_POSTFIX[value]
|| type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]
|| type == "punc" && PUNC_BEFORE_EXPRESSION[value];
if (type == "punc" && value == ".") prev_was_dot = true;
else if (!is_comment) prev_was_dot = false;
var ret = {
type : type,
value : value,
@@ -358,11 +355,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
parse_error("Legacy octal literals are not allowed in strict mode");
}
var valid = parse_js_number(num);
if (!isNaN(valid)) {
return token("num", valid);
} else {
parse_error("Invalid syntax: " + num);
}
if (!isNaN(valid)) return token("num", valid);
parse_error("Invalid syntax: " + num);
}
function read_escaped_char(in_string) {
@@ -463,8 +457,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
if (ch == "\\") escaped = backslash = true, next();
else if (is_identifier_char(ch)) name += next();
else break;
}
else {
} else {
if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
ch = read_escaped_char();
if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
@@ -538,9 +531,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
function handle_dot() {
next();
return is_digit(peek().charCodeAt(0))
? read_num(".")
: token("punc", ".");
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
}
function read_word() {
@@ -592,11 +583,10 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
switch (code) {
case 34: case 39: return read_string(ch);
case 46: return handle_dot();
case 47: {
var tok = handle_slash();
if (tok === next_token) continue;
return tok;
}
case 47:
var tok = handle_slash();
if (tok === next_token) continue;
return tok;
}
if (is_digit(code)) return read_num();
if (PUNC_CHARS[ch]) return token("punc", next());
@@ -614,12 +604,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
next_token.add_directive = function(directive) {
S.directive_stack[S.directive_stack.length - 1].push(directive);
if (S.directives[directive] === undefined) {
S.directives[directive] = 1;
} else {
S.directives[directive]++;
}
if (S.directives[directive]) S.directives[directive]++;
else S.directives[directive] = 1;
}
next_token.push_directives_stack = function() {
@@ -627,13 +613,10 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
next_token.pop_directives_stack = function() {
var directives = S.directive_stack[S.directive_stack.length - 1];
for (var i = 0; i < directives.length; i++) {
var directives = S.directive_stack.pop();
for (var i = directives.length; --i >= 0;) {
S.directives[directives[i]]--;
}
S.directive_stack.pop();
}
next_token.has_directive = function(directive) {
@@ -645,27 +628,17 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
/* -----[ Parser (constants) ]----- */
var UNARY_PREFIX = makePredicate([
"typeof",
"void",
"delete",
"--",
"++",
"!",
"~",
"-",
"+"
]);
var UNARY_PREFIX = makePredicate("typeof void delete -- ++ ! ~ - +");
var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
var UNARY_POSTFIX = makePredicate("-- ++");
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
var ASSIGNMENT = makePredicate("= += -= /= *= %= >>= <<= >>>= |= ^= &=");
var PRECEDENCE = function(a, ret) {
for (var i = 0; i < a.length; ++i) {
var b = a[i];
for (var j = 0; j < b.length; ++j) {
ret[b[j]] = i + 1;
for (var i = 0; i < a.length;) {
var b = a[i++];
for (var j = 0; j < b.length; j++) {
ret[b[j]] = i;
}
}
return ret;
@@ -682,7 +655,7 @@ var PRECEDENCE = function(a, ret) {
["*", "/", "%"]
], {});
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
var ATOMIC_START_TOKEN = makePredicate("atom num string regexp name");
/* -----[ Parser ]----- */
@@ -698,10 +671,9 @@ function parse($TEXT, options) {
}, true);
var S = {
input : (typeof $TEXT == "string"
? tokenizer($TEXT, options.filename,
options.html5_comments, options.shebang)
: $TEXT),
input : typeof $TEXT == "string"
? tokenizer($TEXT, options.filename, options.html5_comments, options.shebang)
: $TEXT,
token : null,
prev : null,
peeked : null,
@@ -757,15 +729,12 @@ function parse($TEXT, options) {
}
function unexpected(token) {
if (token == null)
token = S.token;
if (token == null) token = S.token;
token_error(token, "Unexpected token: " + token_to_string(token.type, token.value));
}
function expect_token(type, val) {
if (is(type, val)) {
return next();
}
if (is(type, val)) return next();
token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val));
}
@@ -1284,6 +1253,7 @@ function parse($TEXT, options) {
var ex = expression(true);
var len = start.comments_before.length;
[].unshift.apply(ex.start.comments_before, start.comments_before);
start.comments_before.length = 0;
start.comments_before = ex.start.comments_before;
start.comments_before_length = len;
if (len == 0 && start.comments_before.length > 0) {
@@ -1299,6 +1269,7 @@ function parse($TEXT, options) {
var end = prev();
end.comments_before = ex.end.comments_before;
[].push.apply(ex.end.comments_after, end.comments_after);
end.comments_after.length = 0;
end.comments_after = ex.end.comments_after;
ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex);

View File

@@ -55,6 +55,7 @@ function SymbolDef(scope, orig, init) {
this.mangled_name = null;
this.undeclared = false;
this.id = SymbolDef.next_id++;
this.lambda = orig instanceof AST_SymbolLambda;
}
SymbolDef.next_id = 1;
@@ -191,13 +192,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 3: fix up any scoping issue with IE8
if (options.ie8) self.walk(new TreeWalker(function(node) {
if (node instanceof AST_SymbolCatch) {
redefine(node, node.thedef.defun);
var scope = node.thedef.defun;
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
scope = scope.parent_scope.resolve();
}
redefine(node, scope);
return true;
}
if (node instanceof AST_SymbolLambda) {
var def = node.thedef;
redefine(node, node.scope.parent_scope);
node.thedef.init = def.init;
redefine(node, node.scope.parent_scope.resolve());
if (typeof node.thedef.init !== "undefined") {
node.thedef.init = false;
} else if (def.init) {
node.thedef.init = def.init;
}
return true;
}
}));
@@ -205,11 +214,19 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
function redefine(node, scope) {
var name = node.name;
var old_def = node.thedef;
var new_def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
var new_def = scope.find_variable(name);
if (new_def) {
var redef;
while (redef = new_def.redefined()) new_def = redef;
} else {
new_def = self.globals.get(name) || scope.def_variable(node);
}
old_def.orig.concat(old_def.references).forEach(function(node) {
node.thedef = new_def;
node.reference(options);
});
if (old_def.lambda) new_def.lambda = true;
if (new_def.undeclared) self.variables.set(name, new_def);
}
});
@@ -281,9 +298,7 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
var def = this.variables.get(symbol.name);
if (def) {
def.orig.push(symbol);
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
def.init = init;
}
if (def.init instanceof AST_Function) def.init = init;
} else {
def = new SymbolDef(this, symbol, init);
this.variables.set(symbol.name, def);
@@ -413,7 +428,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
if (options.cache && node instanceof AST_Toplevel) {
node.globals.each(mangle);
}
node.variables.each(mangle);
node.variables.each(function(def) {
if (!defer_redef(def)) mangle(def);
});
return true;
}
if (node instanceof AST_Label) {
@@ -426,22 +443,11 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
}
if (!options.ie8 && node instanceof AST_Catch) {
var def = node.argname.definition();
var redef = def.redefined();
if (redef) {
redefined.push(def);
reference(node.argname);
def.references.forEach(reference);
}
var redef = defer_redef(def, node.argname);
descend();
if (!redef) mangle(def);
return true;
}
function reference(sym) {
sym.thedef = redef;
sym.reference(options);
sym.thedef = def;
}
});
this.walk(tw);
redefined.forEach(mangle);
@@ -450,6 +456,21 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
if (options.reserved.has[def.name]) return;
def.mangle(options);
}
function defer_redef(def, node) {
var redef = def.redefined();
if (!redef) return false;
redefined.push(def);
def.references.forEach(reference);
if (node) reference(node);
return true;
function reference(sym) {
sym.thedef = redef;
sym.reference(options);
sym.thedef = def;
}
}
});
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
@@ -499,13 +520,14 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
if (def.global && options.cache) return;
if (def.unmangleable(options)) return;
if (options.reserved.has[def.name]) return;
var d = def.redefined();
def.name = d ? d.name : next_name();
var redef = def.redefined();
var name = redef ? redef.rename || redef.name : next_name();
def.rename = name;
def.orig.forEach(function(sym) {
sym.name = def.name;
sym.name = name;
});
def.references.forEach(function(sym) {
sym.name = def.name;
sym.name = name;
});
}
});

View File

@@ -127,8 +127,7 @@ var MAP = (function() {
} else {
top.push(val);
}
}
else if (val !== skip) {
} else if (val !== skip) {
if (val instanceof Splice) {
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
} else {
@@ -145,8 +144,7 @@ var MAP = (function() {
} else {
for (i = 0; i < a.length; ++i) if (doit()) break;
}
}
else {
} else {
for (i in a) if (HOP(a, i)) if (doit()) break;
}
return top.concat(ret);

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.5.13",
"version": "3.6.6",
"engines": {
"node": ">=0.8.0"
},
@@ -23,12 +23,12 @@
"LICENSE"
],
"dependencies": {
"commander": "~2.20.0",
"commander": "~2.20.3",
"source-map": "~0.6.1"
},
"devDependencies": {
"acorn": "~6.1.1",
"semver": "~6.0.0"
"acorn": "~7.1.0",
"semver": "~6.3.0"
},
"scripts": {
"test": "node test/compress.js && node test/mocha.js"

View File

@@ -13,15 +13,15 @@ if (!args.length) {
}
args.push("--timings");
var urls = [
"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://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",
"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",
"https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.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",
];
var results = {};
var remaining = 2 * urls.length;

View File

@@ -1,3 +1,7 @@
"use strict";
require("../tools/exit");
var assert = require("assert");
var child_process = require("child_process");
var fs = require("fs");
@@ -9,7 +13,7 @@ var U = require("./node");
var file = process.argv[2];
var dir = path.resolve(path.dirname(module.filename), "compress");
if (file) {
var minify_options = require("./ufuzz.json").map(JSON.stringify);
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
log("--- {file}", { file: file });
var tests = parse_test(path.resolve(dir, file));
process.exit(Object.keys(tests).filter(function(name) {

View File

@@ -622,3 +622,157 @@ issue_3282_2_passes: {
}
expect_stdout: true
}
issue_3420_1: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
console.log(function() {
return function() {
return arguments[0];
};
}().length);
}
expect: {
console.log(function() {
return function() {
return arguments[0];
};
}().length);
}
expect_stdout: "0"
}
issue_3420_2: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
var foo = function() {
delete arguments[0];
};
foo();
}
expect: {
var foo = function() {
delete arguments[0];
};
foo();
}
expect_stdout: true
}
issue_3420_3: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
"use strict";
var foo = function() {
delete arguments[0];
};
foo();
}
expect: {
"use strict";
var foo = function() {
delete arguments[0];
};
foo();
}
expect_stdout: true
}
issue_3420_4: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
!function() {
console.log(arguments[0]);
delete arguments[0];
console.log(arguments[0]);
}(42);
}
expect: {
!function(argument_0) {
console.log(argument_0);
delete arguments[0];
console.log(arguments[0]);
}(42);
}
expect_stdout: [
"42",
"undefined",
]
}
issue_3420_5: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
"use strict";
!function() {
console.log(arguments[0]);
delete arguments[0];
console.log(arguments[0]);
}(42);
}
expect: {
"use strict";
!function(argument_0) {
console.log(argument_0);
delete arguments[0];
console.log(arguments[0]);
}(42);
}
expect_stdout: [
"42",
"undefined",
]
}
issue_3420_6: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
console.log(function() {
return delete arguments[0];
}());
}
expect: {
console.log(function() {
return delete arguments[0];
}());
}
expect_stdout: "true"
}
issue_3420_7: {
options = {
arguments: true,
keep_fargs: "strict",
}
input: {
"use strict";
console.log(function() {
return delete arguments[0];
}());
}
expect: {
"use strict";
console.log(function() {
return delete arguments[0];
}());
}
expect_stdout: "true"
}

View File

@@ -96,7 +96,7 @@ asm_mixed: {
return +sum;
}
function geometricMean(start, end) {
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
return start |= 0, end |= 0, +exp(logSum(start, end) / (end - start | 0));
}
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
return { geometricMean: geometricMean };

View File

@@ -311,3 +311,65 @@ issue_3375: {
}
expect_stdout: "string"
}
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"
}

88
test/compress/booleans.js Normal file
View File

@@ -0,0 +1,88 @@
iife_boolean_context: {
options = {
booleans: true,
evaluate: true,
}
input: {
console.log(function() {
return Object(1) || false;
}() ? "PASS" : "FAIL");
console.log(function() {
return [].length || true;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function() {
return Object(1);
}() ? "PASS" : "FAIL");
console.log(function() {
return [].length, 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: [
"PASS",
"PASS",
]
expect_warnings: [
"WARN: Dropping side-effect-free || [test/compress/booleans.js:2,19]",
"WARN: Boolean || always true [test/compress/booleans.js:5,19]",
]
}
issue_3465_1: {
options = {
booleans: true,
}
input: {
console.log(function(a) {
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
return 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_3465_2: {
options = {
booleans: true,
}
input: {
console.log(function f(a) {
if (!a) console.log(f(42));
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function f(a) {
if (!a) console.log(f(42));
return typeof a;
}() ? "PASS" : "FAIL");
}
expect_stdout: [
"number",
"PASS",
]
}
issue_3465_3: {
options = {
booleans: true,
passes: 2,
unused: true,
}
input: {
console.log(function f(a) {
return typeof a;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
return 1;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}

View File

@@ -3511,7 +3511,7 @@ issue_2437_2: {
conditionals: true,
inline: true,
join_vars: true,
passes: 2,
passes: 3,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
@@ -4388,7 +4388,7 @@ replace_all_var: {
}
replace_all_var_scope: {
rename = true;
rename = true
options = {
collapse_vars: true,
unused: true,
@@ -6197,3 +6197,154 @@ Infinity_assignment: {
}
expect_stdout: true
}
issue_3439_1: {
options = {
collapse_vars: true,
unused: true,
}
input: {
console.log(typeof function(a) {
function a() {}
return a;
}(42));
}
expect: {
console.log(typeof function(a) {
function a() {}
return a;
}(42));
}
expect_stdout: "function"
}
issue_3439_2: {
options = {
collapse_vars: true,
unused: true,
}
input: {
console.log(typeof function() {
var a = 42;
function a() {}
return a;
}());
}
expect: {
console.log(typeof function() {
return 42;
}());
}
expect_stdout: "number"
}
cond_sequence_return: {
options = {
collapse_vars: true,
}
input: {
console.log(function(n) {
var c = 0;
for (var k in [0, 1])
if (c++, k == n) return c;
}(1));
}
expect: {
console.log(function(n) {
var c = 0;
for (var k in [0, 1])
if (c++, k == n) return c;
}(1));
}
expect_stdout: "2"
}
issue_3520: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
var a = 0;
var b = function(c) {
for (var i = 2; --i >= 0;) {
(function f() {
c = 0;
var i = void 0;
var f = f && f[i];
})();
a += b;
c && b++;
}
}(b = 1);
console.log(a);
}
expect: {
var a = 0;
var b = function(c) {
for (var i = 2; --i >= 0;) {
(function() {
c = 0;
var f = f && f[void 0];
})();
a += b;
c && b++;
}
}(b = 1);
console.log(a);
}
expect_stdout: "2"
}
issue_3526_1: {
options = {
collapse_vars: true,
}
input: {
var b = function() {
this.a = "FAIL";
}();
var a = "PASS";
var b;
var c = b;
console.log(a);
}
expect: {
var b = function() {
this.a = "FAIL";
}();
var a = "PASS";
var b;
var c = b;
console.log(a);
}
expect_stdout: "PASS"
}
issue_3526_2: {
options = {
collapse_vars: true,
}
input: {
function f() {
this.a = "FAIL";
}
var b = f();
var a = "PASS";
var b;
var c = b;
console.log(a);
}
expect: {
function f() {
this.a = "FAIL";
}
var b = f();
var a = "PASS";
var b;
var c = b;
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -161,6 +161,24 @@ ifs_6: {
}
}
ifs_7: {
options = {
conditionals: true,
}
input: {
if (A); else;
if (A) while (B); else;
if (A); else while (C);
if (A) while (B); else while (C);
}
expect: {
A;
if (A) while (B);
if (!A) while (C);
if (A) while (B); else while (C);
}
}
cond_1: {
options = {
conditionals: true,

View File

@@ -1013,3 +1013,54 @@ issue_3406: {
}
expect_stdout: "true"
}
function_assign: {
options = {
dead_code: true,
}
input: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = function(b) {
return b;
}.p = a;
return h;
}().p);
}
expect: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect_stdout: "PASS"
}
issue_3552: {
options = {
dead_code: true,
pure_getters: "strict",
}
input: {
var a = "PASS";
(function() {
(1..p += 42) && (a = "FAIL");
})();
console.log(a);
}
expect: {
var a = "PASS";
(function() {
(1..p += 42) && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -2028,3 +2028,196 @@ issue_3375: {
}
expect_stdout: "0 0"
}
issue_3427_1: {
options = {
sequences: true,
side_effects: true,
unused: true,
}
input: {
(function() {
var a;
a = a || {};
})();
}
expect: {}
}
issue_3427_2: {
options = {
unused: true,
}
input: {
(function() {
var s = "PASS";
console.log(s = s || "FAIL");
})();
}
expect: {
(function() {
var s = "PASS";
console.log(s = s || "FAIL");
})();
}
expect_stdout: "PASS"
}
issue_3495: {
options = {
dead_code: true,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
console.log(function f() {
f = 0;
var a = f.p;
}());
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
}
issue_3497: {
options = {
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
var a;
console.log(function(b) {
(b += a).p = 0;
}());
}
expect: {
var a;
console.log(function(b) {
(b += a).p = 0;
}());
}
expect_stdout: "undefined"
}
issue_3515_1: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
var c = 0;
(function() {
this[c++] = 0;
var expr20 = !0;
for (var key20 in expr20);
})();
console.log(c);
}
expect: {
var c = 0;
(function() {
this[c++] = 0;
for (var key20 in !0);
})();
console.log(c);
}
expect_stdout: "1"
}
issue_3515_2: {
options = {
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "FAIL";
function f() {
typeof b === "number";
delete a;
}
var b = f(a = "PASS");
console.log(a);
}
expect: {
var a = "FAIL";
function f() {
delete a;
}
f(a = "PASS");
console.log(a);
}
expect_stdout: "PASS"
}
issue_3515_3: {
options = {
collapse_vars: true,
unused: true,
}
input: {
var c = "FAIL";
(function() {
function f() {
c = "PASS";
}
var a = f();
var a = function g(b) {
b && (b.p = this);
}(a);
})();
console.log(c);
}
expect: {
var c = "FAIL";
(function() {
function f() {
c = "PASS";
}
(function(b) {
b && (b.p = this);
})(f());
})();
console.log(c);
}
expect_stdout: "PASS"
}
function_assign: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
console.log(function() {
var a = "PASS";
function g(b) {
return b;
}
g.p = a;
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect_stdout: "PASS"
}

View File

@@ -1757,3 +1757,105 @@ issue_3387_2: {
}
expect_stdout: "NaN"
}
simple_function_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function sum(a, b) {
return a + b;
}
console.log(sum(1, 2) * sum(3, 4));
}
expect: {
console.log(21);
}
expect_stdout: "21"
}
simple_function_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var sum = function(a, b) {
return a + b;
}
console.log(sum(1, 2) * sum(3, 4));
}
expect: {
console.log(21);
}
expect_stdout: "21"
}
recursive_function_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function factorial(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect: {
console.log(function factorial(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}(5));
}
expect_stdout: "120"
}
recursive_function_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var factorial = function(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect: {
var factorial = function(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect_stdout: "120"
}
issue_3558: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
function f(a) {
return 1 + --a;
}
console.log(f(true), f(false));
}
expect: {
function f(a) {
return 1 + --a;
}
console.log(1, 0);
}
expect_stdout: "1 0"
}

View File

@@ -1150,7 +1150,7 @@ issue_2620_3: {
}
issue_2620_4: {
rename = true,
rename = true
options = {
dead_code: true,
evaluate: true,
@@ -3066,7 +3066,7 @@ class_iife: {
expect_stdout: "PASS"
}
issue_3400: {
issue_3400_1: {
options = {
collapse_vars: true,
inline: true,
@@ -3096,16 +3096,70 @@ issue_3400: {
});
}
expect: {
void console.log(function g() {
function e() {
return [42].map(function(v) {
return o = {
p: v
}, console.log(o[g]) , o;
var o;
});
void console.log(function() {
function g() {
function h(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}
function e() {
return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
}
return e();
return g;
}()()[0].p);
}
expect_stdout: [
"undefined",
"42",
]
}
issue_3400_2: {
options = {
collapse_vars: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function(f) {
console.log(f()()[0].p);
})(function() {
function g() {
function h(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}
function e() {
return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
}
return g;
});
}
expect: {
void console.log(function g() {
return [ 42 ].map(function(v) {
return function(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}(v);
});
}()[0].p);
}
expect_stdout: [
@@ -3148,3 +3202,171 @@ issue_3402: {
"function",
]
}
issue_3439: {
options = {
inline: true,
}
input: {
console.log(typeof function() {
return function(a) {
function a() {}
return a;
}(42);
}());
}
expect: {
console.log(typeof function(a) {
function a() {}
return a;
}(42));
}
expect_stdout: "function"
}
issue_3444: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function(h) {
return f;
function f() {
g();
}
function g() {
h("PASS");
}
})(console.log)();
}
expect: {
(function(h) {
return function() {
void h("PASS");
};
})(console.log)();
}
expect_stdout: "PASS"
}
issue_3506_1: {
options = {
collapse_vars: true,
evaluate: true,
inline: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = "FAIL";
(function(b) {
(function(b) {
b && (a = "PASS");
})(b);
})(a);
console.log(a);
}
expect: {
var a = "FAIL";
!function(b) {
b && (a = "PASS");
}(a);
console.log(a);
}
expect_stdout: "PASS"
}
issue_3506_2: {
options = {
collapse_vars: true,
evaluate: true,
inline: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = "FAIL";
(function(b) {
(function(c) {
var d = 1;
for (;c && (a = "PASS") && 0 < --d;);
})(b);
})(a);
console.log(a);
}
expect: {
var a = "FAIL";
!function(c) {
var d = 1;
for (;c && (a = "PASS") && 0 < --d;);
}(a);
console.log(a);
}
expect_stdout: "PASS"
}
issue_3506_3: {
options = {
collapse_vars: true,
dead_code: true,
evaluate: true,
inline: true,
loops: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = "FAIL";
(function(b) {
(function(c) {
var d = 1;
for (;c && (a = "PASS") && 0 < --d;);
})(b);
})(a);
console.log(a);
}
expect: {
var a = "FAIL";
!function(c) {
var d = 1;
for (;c && (a = "PASS") && 0 < --d;);
}(a);
console.log(a);
}
expect_stdout: "PASS"
}
issue_3512: {
options = {
collapse_vars: true,
pure_getters: "strict",
sequences: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function(b) {
(function() {
b <<= this || 1;
b.a = "FAIL";
})();
})();
console.log(a);
}
expect: {
var a = "PASS";
(function(b) {
(function() {
(b <<= this || 1).a = "FAIL";
})();
})(),
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -886,3 +886,31 @@ issue_3411: {
}
expect_stdout: "PASS"
}
issue_3440: {
options = {
hoist_props: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
function f() {
console.log(o.p);
}
var o = {
p: "PASS",
};
return f;
})()();
}
expect: {
(function() {
var o_p = "PASS";
return function() {
console.log(o_p);
};
})()();
}
expect_stdout: "PASS"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1051,3 +1051,107 @@ function_name_mangle_ie8: {
expect_exact: "(function(){console.log(typeof function o(){})})();"
expect_stdout: "function"
}
issue_3420_1: {
options = {
keep_fargs: "strict",
unused: true,
}
input: {
console.log(function() {
return function(a, b, c, d) {
return a + b;
};
}().length);
}
expect: {
console.log(function() {
return function(a, b, c, d) {
return a + b;
};
}().length);
}
expect_stdout: "4"
}
issue_3420_2: {
options = {
inline: true,
keep_fargs: "strict",
unused: true,
}
input: {
console.log(function() {
return function(a, b, c, d) {
return a + b;
};
}().length);
}
expect: {
console.log(function(a, b, c, d) {
return a + b;
}.length);
}
expect_stdout: "4"
}
issue_3420_3: {
options = {
inline: true,
keep_fargs: "strict",
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
function f(a, b, c, d) {
return a + b;
}
return f;
}().length);
}
expect: {
console.log(function(a, b, c, d) {
return a + b;
}.length);
}
expect_stdout: "4"
}
issue_3423_1: {
options = {
keep_fargs: "strict",
unused: true,
}
input: {
function f(g) {
console.log(g.length);
}
f(function(a) {});
}
expect: {
function f(g) {
console.log(g.length);
}
f(function(a) {});
}
expect_stdout: "1"
}
issue_3423_2: {
options = {
keep_fargs: "strict",
unused: true,
}
input: {
new function(a) {
console.log(this.constructor.length);
}();
}
expect: {
new function(a) {
console.log(this.constructor.length);
}();
}
expect_stdout: "1"
}

View File

@@ -51,17 +51,20 @@ comparisons: {
comparisons: true,
}
input: {
var x = "42", y = "0x30";
console.log(
~x === 42,
x % n === 42
x % y === 42
);
}
expect: {
var x = "42", y = "0x30";
console.log(
42 == ~x,
x % n == 42
x % y == 42
);
}
expect_stdout: "false true"
}
evaluate_1: {
@@ -103,7 +106,7 @@ evaluate_1: {
}
}
evaluate_2: {
evaluate_1_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
@@ -118,6 +121,8 @@ evaluate_2: {
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3)
);
@@ -126,18 +131,138 @@ evaluate_2: {
console.log(
x + 1 + 2,
2 * x,
3 + +x,
+x + 3,
1 + x + 2 + 3,
3 | x,
6 + x--,
6 + x*y,
x*y + 6,
1 + (2 + x + 3),
6 + ~x,
5 - y + ~x,
0 & x,
6 + (x |= 0)
);
}
}
evaluate_2: {
options = {
evaluate: true,
unsafe_math: false,
}
input: {
var x = "42", y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var x = "42", y = null;
[
x + 1 + 2,
1 * x * 2,
+x + 1 + 2,
1 + x + 2 + 3,
3 | x,
1 + x-- + 2 + 3,
x*y + 2 + 1 + 3,
1 + (2 + x + 3),
2 + ~x + 3 + 1,
2 + ~x + 3 - y,
0 & x,
2 + (x |= 0) + 3 + 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 4212",
"number 84",
"number 45",
"string 14223",
"number 43",
"number 48",
"number 6",
"number 47",
"number -36",
"number -37",
"number 0",
"number 47",
]
}
evaluate_2_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var x = "42", y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var x = "42", y = null;
[
x + 1 + 2,
2 * x,
+x + 3,
1 + x + 2 + 3,
3 | x,
6 + x--,
x*y + 6,
1 + (2 + x + 3),
6 + ~x,
5 + ~x - y,
0 & x,
6 + (x |= 0),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 4212",
"number 84",
"number 45",
"string 14223",
"number 43",
"number 48",
"number 6",
"number 47",
"number -36",
"number -37",
"number 0",
"number 47",
]
}
evaluate_3: {
options = {
evaluate: true,
@@ -148,7 +273,7 @@ evaluate_3: {
console.log(1 + Number(x) + 2);
}
expect: {
console.log(3 + +x);
console.log(+x + 3);
}
}
@@ -182,6 +307,352 @@ evaluate_4: {
}
}
evaluate_5: {
options = {
evaluate: true,
unsafe_math: false,
}
input: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
a - 2 + 3,
a - 2 - 3,
+a + 2 + 3,
+a + 2 - 3,
2 - a + 3,
2 - a - 3,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 6",
"number 0",
"number 2",
"number -4",
"number 6",
"number 0",
"number 4",
"number -2",
"number 6",
"number 4",
"number 0",
"number -2",
]
}
evaluate_5_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "1";
[
+a + 5,
+a + -1,
a - -1,
a - 5,
+a + 5,
+a + -1,
5 - a,
-1 - a,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 6",
"number 0",
"number 2",
"number -4",
"number 6",
"number 0",
"number 4",
"number -2",
"number 6",
"number 4",
"number 0",
"number -2",
]
}
evaluate_6: {
options = {
evaluate: true,
unsafe_math: false,
}
input: {
var a = "1";
[
-a + 2 + 3,
-a + 2 - 3,
-a - 2 + 3,
-a - 2 - 3,
2 + -a + 3,
2 + -a - 3,
2 - -a + 3,
2 - -a - 3,
2 + 3 + -a,
2 + 3 - -a,
2 - 3 + -a,
2 - 3 - -a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "1";
[
2 - a + 3,
2 - a - 3,
-a - 2 + 3,
-a - 2 - 3,
2 - a + 3,
2 - a - 3,
2 - -a + 3,
2 - -a - 3,
5 - a,
5 - -a,
-1 - a,
-1 - -a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 4",
"number -2",
"number 0",
"number -6",
"number 4",
"number -2",
"number 6",
"number 0",
"number 4",
"number 6",
"number -2",
"number 0",
]
}
evaluate_6_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "1";
[
-a + 2 + 3,
-a + 2 - 3,
-a - 2 + 3,
-a - 2 - 3,
2 + -a + 3,
2 + -a - 3,
2 - -a + 3,
2 - -a - 3,
2 + 3 + -a,
2 + 3 - -a,
2 - 3 + -a,
2 - 3 - -a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "1";
[
5 - a,
-1 - a,
-a - -1,
-a - 5,
5 - a,
-1 - a,
5 - -a,
-1 - -a,
5 - a,
5 - -a,
-1 - a,
-1 - -a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 4",
"number -2",
"number 0",
"number -6",
"number 4",
"number -2",
"number 6",
"number 0",
"number 4",
"number 6",
"number -2",
"number 0",
]
}
evaluate_7: {
options = {
evaluate: true,
unsafe_math: false,
}
input: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
x - 2 + (3 + !y),
x - 2 + (3 - !y),
x - 2 - (3 + !y),
x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 48",
"number 46",
"number 40",
"number 42",
"number 44",
"number 42",
"number 36",
"number 38",
]
}
evaluate_7_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var x = "42", y;
[
+x + 5 + !y,
+x + 5 - !y,
+x + -1 - !y,
+x + -1 + !y,
x - -1 + !y,
x - -1 - !y,
x - 5 - !y,
x - 5 + !y,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"number 48",
"number 46",
"number 40",
"number 42",
"number 44",
"number 42",
"number 36",
"number 38",
]
}
NaN_redefined: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var NaN;
console.log(1 / (0 / 0));
}
expect: {
var NaN;
console.log(0 / 0);
}
expect_stdout: "NaN"
}
issue_1710: {
options = {
evaluate: true,
@@ -230,3 +701,219 @@ unary_binary_parenthesis: {
}
expect_stdout: true
}
issue_3531_1: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "1";
console.log(typeof (a + 1 - .1 - .1 - .1));
}
expect: {
var a = "1";
console.log(typeof (a + 1 - .3));
}
expect_stdout: "number"
}
issue_3531_2: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(1 - (2 - {}));
}
expect: {
console.log(-1 + +{});
}
expect_stdout: "NaN"
}
issue_3531_3: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "3";
console.log(1 - (2 + a));
}
expect: {
var a = "3";
console.log(1 - (2 + a));
}
expect_stdout: "-22"
}
issue_3536: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = 100, b = 10;
var c = --a + ("23" - (b++, 1));
console.log(typeof c, a, b, c);
}
expect: {
var a = 100, b = 10;
var c = --a + ("23" - (b++, 1));
console.log(typeof c, a, b, c);
}
expect_stdout: "number 99 11 121"
}
issue_3539: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = -0 + -"";
console.log(0/a, 1/a, -1/a);
}
expect: {
var a = -0;
console.log(0/a, 1/a, -1/a);
}
expect_stdout: "NaN -Infinity Infinity"
}
issue_3547_1: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
[
1/0 + "1" + 0,
1/0 + "1" - 0,
1/0 - "1" + 0,
1/0 - "1" - 0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
[
1/0 + "10",
NaN,
1/0,
1/0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string Infinity10",
"number NaN",
"number Infinity",
"number Infinity",
]
}
issue_3547_2: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
[
"1" + 1/0 + 0,
"1" + 1/0 - 0,
"1" - 1/0 + 0,
"1" - 1/0 - 0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
[
"1" + 1/0 + 0,
NaN,
-1/0,
-1/0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 1Infinity0",
"number NaN",
"number -Infinity",
"number -Infinity",
]
}
issue_3547_3: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "3";
[
a + "2" + 1,
a + "2" - 1,
a - "2" + 1,
a - "2" - 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "3";
[
a + "21",
a + "2" - 1,
a - 1,
a - "2" - 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 321",
"number 31",
"number 2",
"number 0",
]
}
issue_3547_4: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "2";
[
"3" + a + 1,
"3" + a - 1,
"3" - a + 1,
"3" - a - 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "2";
[
"3" + a + 1,
"3" + a - 1,
"3" - a + 1,
2 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 321",
"number 31",
"number 2",
"number 0",
]
}

223
test/compress/objects.js Normal file
View File

@@ -0,0 +1,223 @@
duplicate_key: {
options = {
objects: true,
side_effects: true,
}
input: {
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
var o = {
a: 3,
b: 2,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: [
"a 3",
"b 2",
]
}
duplicate_key_strict: {
options = {
objects: true,
side_effects: true,
}
input: {
"use strict";
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
"use strict";
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: true
}
duplicate_key_side_effect: {
options = {
objects: true,
side_effects: true,
}
input: {
var o = {
a: 1,
b: o = 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
var o = {
a: 1,
b: o = 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: [
"a 3",
"b 2",
]
}
duplicate_key_with_accessor: {
options = {
objects: true,
side_effects: true,
}
input: {
[
{
a: 0,
b: 1,
a: 2,
set b(v) {},
},
{
a: 3,
b: 4,
get a() {
return 5;
},
a: 6,
b: 7,
a: 8,
b: 9,
},
].forEach(function(o) {
for (var k in o)
console.log(k, o[k]);
});
}
expect: {
[
{
a: 2,
b: 1,
set b(v) {},
},
{
a: 3,
b: 4,
get a() {
return 5;
},
a: 8,
b: 9,
},
].forEach(function(o) {
for (var k in o)
console.log(k, o[k]);
});
}
expect_stdout: true
}
unsafe_object_repeated: {
options = {
evaluate: true,
objects: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unsafe: true,
}
input: {
var o = { a: { b: 1 }, a: 1 };
console.log(
o + 1,
o.a + 1,
o.b + 1,
o.a.b + 1
);
}
expect: {
var o = { a: 1 };
console.log(
o + 1,
2,
o.b + 1,
NaN
);
}
expect_stdout: true
}
numeric_literal: {
options = {
objects: true,
side_effects: true,
}
mangle = {
properties: true,
}
beautify = {
beautify: true,
}
input: {
var obj = {
0: 0,
"-0": 1,
42: 2,
"42": 3,
0x25: 4,
"0x25": 5,
1E42: 6,
"1E42": 7,
"1e+42": 8,
};
console.log(obj[-0], obj[-""], obj["-0"]);
console.log(obj[42], obj["42"]);
console.log(obj[0x25], obj["0x25"], obj[37], obj["37"]);
console.log(obj[1E42], obj["1E42"], obj["1e+42"]);
}
expect_exact: [
'var obj = {',
' 0: 0,',
' "-0": 1,',
' 42: 3,',
' 37: 4,',
' o: 5,',
' 1e42: 8,',
' b: 7',
'};',
'',
'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[1e42], obj["b"], obj["1e+42"]);',
]
expect_stdout: [
"0 0 1",
"3 3",
"4 5 4 4",
"8 7 8",
]
}

View File

@@ -1187,3 +1187,25 @@ drop_arguments: {
}
expect_stdout: "PASS"
}
issue_3427: {
options = {
assignments: true,
collapse_vars: true,
inline: true,
passes: 2,
pure_getters: "strict",
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a;
(function(b) {
b.p = 42;
})(a || (a = {}));
}
expect: {}
expect_stdout: true
}

View File

@@ -4947,7 +4947,7 @@ defun_single_use_loop: {
unused: true,
}
input: {
for (var x, i = 2; --i >= 0; ) {
for (var x, i = 2; --i >= 0;) {
var y = x;
x = f;
console.log(x === y);
@@ -4955,7 +4955,7 @@ defun_single_use_loop: {
function f() {};
}
expect: {
for (var x, i = 2; --i >= 0; ) {
for (var x, i = 2; --i >= 0;) {
var y = x;
x = f;
console.log(x === y);
@@ -6609,10 +6609,10 @@ issues_3267_1: {
}
expect: {
!function(i) {
if (i)
if (Object())
return console.log("PASS");
throw "FAIL";
}(Object());
}();
}
expect_stdout: "PASS"
}
@@ -6752,3 +6752,31 @@ issue_3377: {
}
expect_stdout: "42"
}
issue_3509: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function a() {
console.log("PASS");
}
try {
} catch (a) {
var a;
}
a();
}
expect: {
try {
} catch (a) {
var a;
}
(function() {
console.log("PASS");
})();
}
expect_stdout: "PASS"
}

View File

@@ -35,3 +35,140 @@ regexp_2: {
}
expect_stdout: '["PASS","pass"]'
}
issue_3434_1: {
options = {
evaluate: true,
unsafe: true,
}
beautify = {
beautify: true,
}
input: {
var o = {
"\n": RegExp("\n"),
"\r": RegExp("\r"),
"\t": RegExp("\t"),
"\b": RegExp("\b"),
"\f": RegExp("\f"),
"\0": RegExp("\0"),
"\x0B": RegExp("\x0B"),
"\u2028": RegExp("\u2028"),
"\u2029": RegExp("\u2029"),
};
for (var c in o)
console.log(o[c].test("\\"), o[c].test(c));
}
expect_exact: [
"var o = {",
' "\\n": /\\n/,',
' "\\r": /\\r/,',
' "\\t": /\t/,',
' "\\b": /\b/,',
' "\\f": /\f/,',
' "\\0": /\0/,',
' "\\v": /\v/,',
' "\\u2028": /\\u2028/,',
' "\\u2029": /\\u2029/',
"};",
"",
'for (var c in o) console.log(o[c].test("\\\\"), o[c].test(c));',
]
expect_stdout: [
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
]
}
issue_3434_2: {
options = {
evaluate: true,
unsafe: true,
}
beautify = {
beautify: true,
}
input: {
var o = {
"\n": RegExp("\\\n"),
"\r": RegExp("\\\r"),
"\t": RegExp("\\\t"),
"\b": RegExp("\\\b"),
"\f": RegExp("\\\f"),
"\0": RegExp("\\\0"),
"\x0B": RegExp("\\\x0B"),
"\u2028": RegExp("\\\u2028"),
"\u2029": RegExp("\\\u2029"),
};
for (var c in o)
console.log(o[c].test("\\"), o[c].test(c));
}
expect_exact: [
"var o = {",
' "\\n": /\\n/,',
' "\\r": /\\r/,',
' "\\t": /\t/,',
' "\\b": /\b/,',
' "\\f": /\f/,',
' "\\0": /\0/,',
' "\\v": /\v/,',
' "\\u2028": /\\u2028/,',
' "\\u2029": /\\u2029/',
"};",
"",
'for (var c in o) console.log(o[c].test("\\\\"), o[c].test(c));',
]
expect_stdout: [
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
"false true",
]
}
issue_3434_3: {
options = {
evaluate: true,
unsafe: true,
}
input: {
RegExp("\n");
RegExp("\r");
RegExp("\\n");
RegExp("\\\n");
RegExp("\\\\n");
RegExp("\\\\\n");
RegExp("\\\\\\n");
RegExp("\\\\\\\n");
RegExp("\u2028");
RegExp("\u2029");
RegExp("\n\r\u2028\u2029");
RegExp("\\\nfo\n[\n]o\\bbb");
}
expect: {
/\n/;
/\r/;
/\n/;
/\n/;
/\\n/;
/\\\n/;
/\\\n/;
/\\\n/;
/\u2028/;
/\u2029/;
/\n\r\u2028\u2029/;
/\nfo\n[\n]o\bbb/;
}
}

View File

@@ -579,7 +579,7 @@ function_do_catch_ie8: {
console.log(b, c);
}
expect: {
var t = 1, u = 1, y = 0;
var u = 1, y = 1, a = 0;
function c(c) {
var d;
do {
@@ -587,7 +587,7 @@ function_do_catch_ie8: {
try {
var e = void 0;
} catch (i) {
--t && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
--u && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
0;
0;
0;
@@ -596,18 +596,146 @@ function_do_catch_ie8: {
d[1];
} catch (l) {
var g;
switch(function x() {
y++;
switch (function n() {
a++;
}()) {
case e + --g:
case e + --g:
}
}
} catch (n) {}
} catch (t) {}
} while (--d);
u--;
y--;
}
c();
console.log(u, y);
console.log(y, a);
}
expect_stdout: "0 1"
}
issue_3480: {
rename = true,
mangle = {
ie8: false,
toplevel: false,
}
input: {
var d, a, b, c = "FAIL";
(function b() {
(function() {
try {
c = "PASS";
} catch (b) {
}
})();
})();
console.log(c);
}
expect: {
var d, a, b, c = "FAIL";
(function n() {
(function() {
try {
c = "PASS";
} catch (c) {}
})();
})();
console.log(c);
}
expect_stdout: "PASS"
}
issue_3480_ie8: {
rename = true,
mangle = {
ie8: true,
toplevel: false,
}
input: {
var d, a, b, c = "FAIL";
(function b() {
(function() {
try {
c = "PASS";
} catch (b) {
}
})();
})();
console.log(c);
}
expect: {
var d, a, b, c = "FAIL";
(function b() {
(function() {
try {
c = "PASS";
} catch (b) {}
})();
})();
console.log(c);
}
expect_stdout: "PASS"
}
issue_3480_toplevel: {
rename = true,
mangle = {
ie8: false,
toplevel: true,
}
input: {
var d, a, b, c = "FAIL";
(function b() {
(function() {
try {
c = "PASS";
} catch (b) {
}
})();
})();
console.log(c);
}
expect: {
var c, n, o, t = "FAIL";
(function c() {
(function() {
try {
t = "PASS";
} catch (c) {}
})();
})();
console.log(t);
}
expect_stdout: "PASS"
}
issue_3480_ie8_toplevel: {
rename = true,
mangle = {
ie8: true,
toplevel: true,
}
input: {
var d, a, b, c = "FAIL";
(function b() {
(function() {
try {
c = "PASS";
} catch (b) {
}
})();
})();
console.log(c);
}
expect: {
var c, n, o, t = "FAIL";
(function o() {
(function() {
try {
t = "PASS";
} catch (o) {}
})();
})();
console.log(t);
}
expect_stdout: "PASS"
}

View File

@@ -1006,3 +1006,66 @@ angularjs_chain: {
}
}
}
issue_3490_1: {
options = {
conditionals: true,
dead_code: true,
inline: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var b = 42, c = "FAIL";
if ({
3: function() {
var a;
return (a && a.p) < this;
}(),
}) c = "PASS";
if (b) while ("" == typeof d);
console.log(c, b);
}
expect: {
var b = 42, c = "FAIL";
if (function() {
var a;
a && a.p;
}(), c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
}
issue_3490_2: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
inline: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var b = 42, c = "FAIL";
if ({
3: function() {
var a;
return (a && a.p) < this;
}(),
}) c = "PASS";
if (b) for (; "" == typeof d;);
console.log(c, b);
}
expect: {
var b = 42, c = "FAIL";
for (function() {
var a;
}(), c = "PASS", b; "" == typeof d;);
console.log(c, b);
}
expect_stdout: "PASS 42"
}

View File

@@ -295,3 +295,145 @@ issue_2728_6: {
}
expect_stdout: "function undefined"
}
typeof_defined_1: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"undefined" == typeof A && A;
"undefined" != typeof A && A;
"undefined" == typeof A || A;
"undefined" != typeof A || A;
}
expect: {
"undefined" == typeof A && A;
"undefined" != typeof A || A;
}
}
typeof_defined_2: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"function" == typeof A && A;
"function" != typeof A && A;
"function" == typeof A || A;
"function" != typeof A || A;
}
expect: {
"function" != typeof A && A;
"function" == typeof A || A;
}
}
typeof_defined_3: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"undefined" == typeof A && "undefined" == typeof B && (A, B);
"undefined" == typeof A && "undefined" != typeof B && (A, B);
"undefined" != typeof A && "undefined" == typeof B && (A, B);
"undefined" != typeof A && "undefined" != typeof B && (A, B);
"undefined" == typeof A && "undefined" == typeof B || (A, B);
"undefined" == typeof A && "undefined" != typeof B || (A, B);
"undefined" != typeof A && "undefined" == typeof B || (A, B);
"undefined" != typeof A && "undefined" != typeof B || (A, B);
"undefined" == typeof A || "undefined" == typeof B && (A, B);
"undefined" == typeof A || "undefined" != typeof B && (A, B);
"undefined" != typeof A || "undefined" == typeof B && (A, B);
"undefined" != typeof A || "undefined" != typeof B && (A, B);
"undefined" == typeof A || "undefined" == typeof B || (A, B);
"undefined" == typeof A || "undefined" != typeof B || (A, B);
"undefined" != typeof A || "undefined" == typeof B || (A, B);
"undefined" != typeof A || "undefined" != typeof B || (A, B);
}
expect: {
"undefined" == typeof A && "undefined" == typeof B && (A, B);
"undefined" == typeof A && "undefined" != typeof B && A;
"undefined" != typeof A && "undefined" == typeof B && B;
"undefined" == typeof A && "undefined" == typeof B || (A, B);
"undefined" == typeof A && "undefined" != typeof B || (A, B);
"undefined" != typeof A && "undefined" == typeof B || (A, B);
"undefined" != typeof A && "undefined" != typeof B || (A, B);
"undefined" == typeof A || "undefined" == typeof B && B;
"undefined" != typeof A || "undefined" == typeof B && (A, B);
"undefined" != typeof A || "undefined" != typeof B && A;
"undefined" == typeof A || "undefined" != typeof B || B;
"undefined" != typeof A || "undefined" == typeof B || A;
"undefined" != typeof A || "undefined" != typeof B || (A, B);
}
}
typeof_defined_4: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"object" == typeof A && "object" == typeof B && (A, B);
"object" == typeof A && "object" != typeof B && (A, B);
"object" != typeof A && "object" == typeof B && (A, B);
"object" != typeof A && "object" != typeof B && (A, B);
"object" == typeof A && "object" == typeof B || (A, B);
"object" == typeof A && "object" != typeof B || (A, B);
"object" != typeof A && "object" == typeof B || (A, B);
"object" != typeof A && "object" != typeof B || (A, B);
"object" == typeof A || "object" == typeof B && (A, B);
"object" == typeof A || "object" != typeof B && (A, B);
"object" != typeof A || "object" == typeof B && (A, B);
"object" != typeof A || "object" != typeof B && (A, B);
"object" == typeof A || "object" == typeof B || (A, B);
"object" == typeof A || "object" != typeof B || (A, B);
"object" != typeof A || "object" == typeof B || (A, B);
"object" != typeof A || "object" != typeof B || (A, B);
}
expect: {
"object" == typeof A && "object" != typeof B && B;
"object" != typeof A && "object" == typeof B && A;
"object" != typeof A && "object" != typeof B && (A, B);
"object" == typeof A && "object" == typeof B || (A, B);
"object" == typeof A && "object" != typeof B || (A, B);
"object" != typeof A && "object" == typeof B || (A, B);
"object" != typeof A && "object" != typeof B || (A, B);
"object" == typeof A || "object" == typeof B && A;
"object" == typeof A || "object" != typeof B && (A, B);
"object" != typeof A || "object" != typeof B && B;
"object" == typeof A || "object" == typeof B || (A, B);
"object" == typeof A || "object" != typeof B || A;
"object" != typeof A || "object" == typeof B || B;
}
}
emberjs_global: {
options = {
comparisons: true,
conditionals: true,
if_return: true,
passes: 2,
side_effects: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
var a;
if (typeof A === "object") {
a = A;
} else if (typeof B === "object") {
a = B;
} else {
throw new Error("PASS");
}
}
expect: {
if ("object" != typeof A && "object" != typeof B)
throw new Error("PASS");
}
expect_stdout: Error("PASS")
}

View File

@@ -8,6 +8,7 @@ exports["parse"] = parse;
exports["push_uniq"] = push_uniq;
exports["reserve_quoted_keys"] = reserve_quoted_keys;
exports["string_template"] = string_template;
exports["to_ascii"] = to_ascii;
exports["tokenizer"] = tokenizer;
exports["TreeTransformer"] = TreeTransformer;
exports["TreeWalker"] = TreeWalker;

View File

@@ -0,0 +1,8 @@
// Generated by CoffeeScript 2.4.1
(function() {
console.log('hello');
}).call(this);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1haW4uY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtFQUFBLE9BQU8sQ0FBQyxHQUFSLENBQVksT0FBWjtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiY29uc29sZS5sb2cgJ2hlbGxvJ1xuIl19
//# sourceURL=/Users/mohamed/Downloads/main.coffee

View File

@@ -48,53 +48,84 @@ describe("comments", function() {
}
});
it("Should handle comment within return correctly", function() {
var result = UglifyJS.minify([
"function unequal(x, y) {",
" return (",
" // Either one",
" x < y",
" ||",
" y < x",
" );",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
describe("comment within return", function() {
it("Should handle leading return", function() {
var result = UglifyJS.minify([
"function unequal(x, y) {",
" return (",
" // Either one",
" x < y",
" ||",
" y < x",
" );",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function unequal(x, y) {",
" // Either one",
" return x < y || y < x;",
"}",
].join("\n"));
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function unequal(x, y) {",
" // Either one",
" return x < y || y < x;",
"}",
].join("\n"));
});
it("Should handle comment folded into return correctly", function() {
var result = UglifyJS.minify([
"function f() {",
" /* boo */ x();",
" return y();",
"}",
].join("\n"), {
mangle: false,
output: {
beautify: true,
comments: "all",
},
it("Should handle trailing return", function() {
var result = UglifyJS.minify([
"function unequal(x) {",
" var y;",
" return (",
" // Either one",
" x < y",
" ||",
" y < x",
" );",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function unequal(x) {",
" var y;",
" // Either one",
" return x < y || y < x;",
"}",
].join("\n"));
});
it("Should handle comment folded into return", function() {
var result = UglifyJS.minify([
"function f() {",
" /* boo */ x();",
" return y();",
"}",
].join("\n"), {
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function f() {",
" /* boo */",
" return x(), y();",
"}",
].join("\n"));
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function f() {",
" /* boo */",
" return x(), y();",
"}",
].join("\n"));
});
it("Should not drop comments after first OutputStream", function() {
@@ -228,6 +259,30 @@ describe("comments", function() {
assert.strictEqual(result.code, code);
});
it("Should handle comments around parenthesis correctly", function() {
var code = [
"a();",
"/* foo */",
"(b())",
"/* bar */",
"c();",
].join("\n");
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"a();",
"/* foo */",
"b()",
"/* bar */;c();",
].join("\n"));
});
it("Should preserve comments around IIFE", function() {
var result = UglifyJS.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
compress: false,

View File

@@ -1,7 +1,7 @@
var assert = require("assert");
var readFileSync = require("fs").readFileSync;
var SourceMapConsumer = require("source-map").SourceMapConsumer;
var UglifyJS = require("../..");
var UglifyJS = require("../node");
function read(path) {
return readFileSync(path, "utf8");
@@ -181,6 +181,18 @@ describe("sourcemaps", function() {
if (result.error) throw result.error;
assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-3294/output.js", "utf8"));
});
it("Should work in presence of unrecognised annotations", function() {
var result = UglifyJS.minify(read("./test/input/issue-3441/input.js"), {
compress: false,
mangle: false,
sourceMap: {
content: "inline",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI"}');
});
});
describe("sourceMapInline", function() {
@@ -232,7 +244,7 @@ describe("sourcemaps", function() {
assert.strictEqual(map.sourcesContent.length, 1);
assert.strictEqual(map.sourcesContent[0], code);
var encoded = result.code.slice(result.code.lastIndexOf(",") + 1);
map = JSON.parse(new Buffer(encoded, "base64").toString());
map = JSON.parse(UglifyJS.to_ascii(encoded));
assert.strictEqual(map.sourcesContent.length, 1);
assert.strictEqual(map.sourcesContent[0], code);
result = UglifyJS.minify(result.code, {

View File

@@ -1,3 +1,6 @@
setInterval(function() {
process.stderr.write("\0");
}, 8 * 60 * 1000).unref();
require("./run")([
"-b",
"-b braces",

View File

@@ -1,81 +0,0 @@
"use strict";
var child_process = require("child_process");
var https = require("https");
var url = require("url");
var period = 45 * 60 * 1000;
var wait = 2 * 60 * 1000;
var ping = 5 * 60 * 1000;
if (process.argv[2] == "run") {
var endTime = Date.now() + period;
for (var i = 0; i < 2; i++) spawn(endTime);
} else if (process.argv.length > 2) {
var token = process.argv[2];
var branch = process.argv[3] || "v" + require("../package.json").version;
var repository = encodeURIComponent(process.argv[4] || "mishoo/UglifyJS2");
var concurrency = process.argv[5] || 1;
var platform = process.argv[6] || "node/latest";
(function request() {
setTimeout(request, (period + wait) / concurrency);
var options = url.parse("https://api.travis-ci.org/repo/" + repository + "/requests");
options.method = "POST";
options.headers = {
"Content-Type": "application/json",
"Travis-API-Version": 3,
"Authorization": "token " + token
};
https.request(options, function(res) {
console.log("HTTP", res.statusCode);
console.log(JSON.stringify(res.headers, null, 2));
console.log();
res.setEncoding("utf8");
res.on("data", console.log);
}).on("error", console.error).end(JSON.stringify({
request: {
message: "ufuzz testing",
branch: branch,
config: {
cache: false,
env: "NODEJS_VER=" + platform,
script: "node test/travis-ufuzz run"
}
}
}));
})();
} else {
console.log("Usage: test/travis-ufuzz.js <token> [branch] [repository] [concurrency] [platform]");
}
function spawn(endTime) {
var child = child_process.spawn("node", [
"--max-old-space-size=2048",
"test/ufuzz"
], {
stdio: [ "ignore", "pipe", "pipe" ]
}).on("exit", respawn);
var line = "";
child.stdout.on("data", function(data) {
line += data;
});
child.stderr.on("data", function() {
process.exitCode = 1;
}).pipe(process.stdout);
var keepAlive = setInterval(function() {
var end = line.lastIndexOf("\r");
console.log(line.slice(line.lastIndexOf("\r", end - 1) + 1, end));
line = line.slice(end + 1);
}, ping);
var timer = setTimeout(function() {
clearInterval(keepAlive);
child.removeListener("exit", respawn);
child.kill();
}, endTime - Date.now());
function respawn() {
console.log(line);
clearInterval(keepAlive);
clearTimeout(timer);
spawn(endTime);
}
}

File diff suppressed because it is too large Load Diff

39
test/ufuzz/job.js Normal file
View File

@@ -0,0 +1,39 @@
var child_process = require("child_process");
var ping = 5 * 60 * 1000;
var period = +process.argv[2];
var endTime = Date.now() + period;
for (var i = 0; i < 2; i++) spawn(endTime);
function spawn(endTime) {
var child = child_process.spawn("node", [
"--max-old-space-size=2048",
"test/ufuzz"
], {
stdio: [ "ignore", "pipe", "pipe" ]
}).on("exit", respawn);
var line = "";
child.stdout.on("data", function(data) {
line += data;
});
child.stderr.once("data", function() {
process.exitCode = 1;
}).pipe(process.stdout);
var keepAlive = setInterval(function() {
var end = line.lastIndexOf("\r");
console.log(line.slice(line.lastIndexOf("\r", end - 1) + 1, end));
line = line.slice(end + 1);
}, ping);
var timer = setTimeout(function() {
clearInterval(keepAlive);
child.removeListener("exit", respawn);
child.kill();
}, endTime - Date.now());
function respawn() {
console.log(line);
clearInterval(keepAlive);
clearTimeout(timer);
spawn(endTime);
}
}

44
test/ufuzz/travis.js Normal file
View File

@@ -0,0 +1,44 @@
"use strict";
var child_process = require("child_process");
var https = require("https");
var url = require("url");
var period = 45 * 60 * 1000;
var wait = 2 * 60 * 1000;
if (process.argv.length > 2) {
var token = process.argv[2];
var branch = process.argv[3] || "v" + require("../../package.json").version;
var repository = encodeURIComponent(process.argv[4] || "mishoo/UglifyJS2");
var concurrency = process.argv[5] || 1;
var platform = process.argv[6] || "latest";
(function request() {
setTimeout(request, (period + wait) / concurrency);
var options = url.parse("https://api.travis-ci.org/repo/" + repository + "/requests");
options.method = "POST";
options.headers = {
"Content-Type": "application/json",
"Travis-API-Version": 3,
"Authorization": "token " + token
};
https.request(options, function(res) {
console.log("HTTP", res.statusCode);
console.log(JSON.stringify(res.headers, null, 2));
console.log();
res.setEncoding("utf8");
res.on("data", console.log);
}).on("error", console.error).end(JSON.stringify({
request: {
message: "ufuzz testing",
branch: branch,
config: {
cache: false,
env: "NODE=" + platform,
script: "node test/ufuzz/job " + period
}
}
}));
})();
} else {
console.log("Usage: test/ufuzz/travis.js <token> [branch] [repository] [concurrency] [platform]");
}

View File

@@ -2702,8 +2702,10 @@
"attrChange",
"attrName",
"attributeChangedCallback",
"attributeFilter",
"attributeName",
"attributeNamespace",
"attributeOldValue",
"attributeStyleMap",
"attributes",
"audioTracks",
@@ -2993,6 +2995,7 @@
"caption",
"caption-side",
"captionSide",
"capture",
"captureEvents",
"captureStackTrace",
"captureStream",
@@ -3024,6 +3027,8 @@
"charCode",
"charCodeAt",
"charIndex",
"characterData",
"characterDataOldValue",
"characterSet",
"charging",
"chargingTime",
@@ -3035,6 +3040,7 @@
"checkValidity",
"checked",
"childElementCount",
"childList",
"childNodes",
"children",
"chrome",
@@ -4957,6 +4963,7 @@
"oncandidatewindowupdate",
"oncanplay",
"oncanplaythrough",
"once",
"oncellchange",
"onchange",
"onchargingchange",
@@ -5343,6 +5350,7 @@
"parseInt",
"part",
"participants",
"passive",
"password",
"pasteHTML",
"path",
@@ -6147,6 +6155,7 @@
"substring",
"substringData",
"subtle",
"subtree",
"suffix",
"suffixes",
"summary",

View File

@@ -1,21 +1,19 @@
var fs = require("fs");
exports.FILES = [
"../lib/utils.js",
"../lib/ast.js",
"../lib/parse.js",
"../lib/transform.js",
"../lib/scope.js",
"../lib/output.js",
"../lib/compress.js",
"../lib/sourcemap.js",
"../lib/mozilla-ast.js",
"../lib/propmangle.js",
"../lib/minify.js",
"./exports.js",
].map(function(file) {
return require.resolve(file);
});
require.resolve("../lib/utils.js"),
require.resolve("../lib/ast.js"),
require.resolve("../lib/parse.js"),
require.resolve("../lib/transform.js"),
require.resolve("../lib/scope.js"),
require.resolve("../lib/output.js"),
require.resolve("../lib/compress.js"),
require.resolve("../lib/sourcemap.js"),
require.resolve("../lib/mozilla-ast.js"),
require.resolve("../lib/propmangle.js"),
require.resolve("../lib/minify.js"),
require.resolve("./exports.js"),
];
new Function("MOZ_SourceMap", "exports", function() {
var code = exports.FILES.map(function(file) {
@@ -48,7 +46,9 @@ function describe_ast() {
if (ctor.SUBCLASSES.length > 0) {
out.space();
out.with_block(function() {
ctor.SUBCLASSES.forEach(function(ctor, i) {
ctor.SUBCLASSES.sort(function(a, b) {
return a.TYPE < b.TYPE ? -1 : 1;
}).forEach(function(ctor, i) {
out.indent();
doitem(ctor);
out.newline();