terser 5.3.6 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +9 -2
- package/dist/bundle.min.js +289 -129
- package/lib/ast.js +55 -6
- package/lib/compress/index.js +140 -34
- package/lib/mozilla-ast.js +24 -39
- package/lib/output.js +5 -2
- package/lib/parse.js +67 -49
- package/package.json +11 -12
- package/dist/bundle.min.js.map +0 -1
package/dist/bundle.min.js
CHANGED
@@ -324,6 +324,9 @@ function set_annotation(node, annotation) {
|
|
324
324
|
|
325
325
|
***********************************************************************/
|
326
326
|
|
327
|
+
var LATEST_RAW = ""; // Only used for numbers and template strings
|
328
|
+
var LATEST_TEMPLATE_END = true;
|
329
|
+
|
327
330
|
var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with";
|
328
331
|
var KEYWORDS_ATOM = "false null true";
|
329
332
|
var RESERVED_WORDS = "enum implements import interface package private protected public static super this " + KEYWORDS_ATOM + " " + KEYWORDS;
|
@@ -379,6 +382,9 @@ var OPERATORS = makePredicate([
|
|
379
382
|
"=",
|
380
383
|
"+=",
|
381
384
|
"-=",
|
385
|
+
"||=",
|
386
|
+
"&&=",
|
387
|
+
"??=",
|
382
388
|
"/=",
|
383
389
|
"*=",
|
384
390
|
"**=",
|
@@ -639,29 +645,23 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
639
645
|
} else if (!is_comment) {
|
640
646
|
prev_was_dot = false;
|
641
647
|
}
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
endpos : S.pos,
|
651
|
-
nlb : S.newline_before,
|
652
|
-
file : filename
|
653
|
-
};
|
654
|
-
if (/^(?:num|string|regexp)$/i.test(type)) {
|
655
|
-
ret.raw = $TEXT.substring(ret.pos, ret.endpos);
|
656
|
-
}
|
648
|
+
const line = S.tokline;
|
649
|
+
const col = S.tokcol;
|
650
|
+
const pos = S.tokpos;
|
651
|
+
const nlb = S.newline_before;
|
652
|
+
const file = filename;
|
653
|
+
let comments_before = [];
|
654
|
+
let comments_after = [];
|
655
|
+
|
657
656
|
if (!is_comment) {
|
658
|
-
|
659
|
-
|
657
|
+
comments_before = S.comments_before;
|
658
|
+
comments_after = S.comments_before = [];
|
660
659
|
}
|
661
660
|
S.newline_before = false;
|
662
|
-
|
663
|
-
|
664
|
-
|
661
|
+
const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file);
|
662
|
+
|
663
|
+
if (!is_comment) previous_token = tok;
|
664
|
+
return tok;
|
665
665
|
}
|
666
666
|
|
667
667
|
function skip_whitespace() {
|
@@ -713,6 +713,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
713
713
|
return RE_NUM_LITERAL.test(ch);
|
714
714
|
});
|
715
715
|
if (prefix) num = prefix + num;
|
716
|
+
|
717
|
+
LATEST_RAW = num;
|
718
|
+
|
716
719
|
if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
|
717
720
|
parse_error("Legacy octal literals are not allowed in strict mode");
|
718
721
|
}
|
@@ -820,15 +823,17 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
820
823
|
}
|
821
824
|
|
822
825
|
var read_string = with_eof_error("Unterminated string constant", function() {
|
823
|
-
|
826
|
+
const start_pos = S.pos;
|
827
|
+
var quote = next(), ret = [];
|
824
828
|
for (;;) {
|
825
829
|
var ch = next(true, true);
|
826
830
|
if (ch == "\\") ch = read_escaped_char(true, true);
|
827
831
|
else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
|
828
832
|
else if (ch == quote) break;
|
829
|
-
ret
|
833
|
+
ret.push(ch);
|
830
834
|
}
|
831
|
-
var tok = token("string", ret);
|
835
|
+
var tok = token("string", ret.join(""));
|
836
|
+
LATEST_RAW = S.text.slice(start_pos, S.pos);
|
832
837
|
tok.quote = quote;
|
833
838
|
return tok;
|
834
839
|
});
|
@@ -847,7 +852,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
847
852
|
next(true, true);
|
848
853
|
S.brace_counter++;
|
849
854
|
tok = token(begin ? "template_head" : "template_substitution", content);
|
850
|
-
|
855
|
+
LATEST_RAW = raw;
|
856
|
+
LATEST_TEMPLATE_END = false;
|
851
857
|
return tok;
|
852
858
|
}
|
853
859
|
|
@@ -863,8 +869,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
863
869
|
}
|
864
870
|
S.template_braces.pop();
|
865
871
|
tok = token(begin ? "template_head" : "template_substitution", content);
|
866
|
-
|
867
|
-
|
872
|
+
LATEST_RAW = raw;
|
873
|
+
LATEST_TEMPLATE_END = true;
|
868
874
|
return tok;
|
869
875
|
});
|
870
876
|
|
@@ -897,7 +903,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
897
903
|
});
|
898
904
|
|
899
905
|
var read_name = with_eof_error("Unterminated identifier name", function() {
|
900
|
-
var name, ch, escaped = false;
|
906
|
+
var name = [], ch, escaped = false;
|
901
907
|
var read_escaped_identifier_char = function() {
|
902
908
|
escaped = true;
|
903
909
|
next();
|
@@ -908,17 +914,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
908
914
|
};
|
909
915
|
|
910
916
|
// Read first character (ID_Start)
|
911
|
-
if ((
|
912
|
-
|
913
|
-
if (!is_identifier_start(
|
917
|
+
if ((ch = peek()) === "\\") {
|
918
|
+
ch = read_escaped_identifier_char();
|
919
|
+
if (!is_identifier_start(ch)) {
|
914
920
|
parse_error("First identifier char is an invalid identifier char");
|
915
921
|
}
|
916
|
-
} else if (is_identifier_start(
|
922
|
+
} else if (is_identifier_start(ch)) {
|
917
923
|
next();
|
918
924
|
} else {
|
919
925
|
return "";
|
920
926
|
}
|
921
927
|
|
928
|
+
name.push(ch);
|
929
|
+
|
922
930
|
// Read ID_Continue
|
923
931
|
while ((ch = peek()) != null) {
|
924
932
|
if ((ch = peek()) === "\\") {
|
@@ -932,12 +940,13 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
932
940
|
}
|
933
941
|
next();
|
934
942
|
}
|
935
|
-
name
|
943
|
+
name.push(ch);
|
936
944
|
}
|
937
|
-
|
945
|
+
const name_str = name.join("");
|
946
|
+
if (RESERVED_WORDS.has(name_str) && escaped) {
|
938
947
|
parse_error("Escaped characters are not allowed in keywords");
|
939
948
|
}
|
940
|
-
return
|
949
|
+
return name_str;
|
941
950
|
});
|
942
951
|
|
943
952
|
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
@@ -961,7 +970,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
961
970
|
source += ch;
|
962
971
|
}
|
963
972
|
const flags = read_name();
|
964
|
-
return token("regexp",
|
973
|
+
return token("regexp", "/" + source + "/" + flags);
|
965
974
|
});
|
966
975
|
|
967
976
|
function read_operator(prefix) {
|
@@ -1154,7 +1163,9 @@ var UNARY_PREFIX = makePredicate([
|
|
1154
1163
|
|
1155
1164
|
var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
|
1156
1165
|
|
1157
|
-
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
|
1166
|
+
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
|
1167
|
+
|
1168
|
+
var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]);
|
1158
1169
|
|
1159
1170
|
var PRECEDENCE = (function(a, ret) {
|
1160
1171
|
for (var i = 0; i < a.length; ++i) {
|
@@ -1192,7 +1203,7 @@ function parse($TEXT, options) {
|
|
1192
1203
|
// Useful because comments_before property of call with parens outside
|
1193
1204
|
// contains both comments inside and outside these parens. Used to find the
|
1194
1205
|
// right #__PURE__ comments for an expression
|
1195
|
-
const outer_comments_before_counts = new
|
1206
|
+
const outer_comments_before_counts = new WeakMap();
|
1196
1207
|
|
1197
1208
|
options = defaults(options, {
|
1198
1209
|
bare_returns : false,
|
@@ -1326,7 +1337,7 @@ function parse($TEXT, options) {
|
|
1326
1337
|
case "string":
|
1327
1338
|
if (S.in_directives) {
|
1328
1339
|
var token = peek();
|
1329
|
-
if (!
|
1340
|
+
if (!LATEST_RAW.includes("\\")
|
1330
1341
|
&& (is_token(token, "punc", ";")
|
1331
1342
|
|| is_token(token, "punc", "}")
|
1332
1343
|
|| has_newline_before(token)
|
@@ -2309,7 +2320,12 @@ function parse($TEXT, options) {
|
|
2309
2320
|
ret = _make_symbol(AST_SymbolRef);
|
2310
2321
|
break;
|
2311
2322
|
case "num":
|
2312
|
-
ret = new AST_Number({
|
2323
|
+
ret = new AST_Number({
|
2324
|
+
start: tok,
|
2325
|
+
end: tok,
|
2326
|
+
value: tok.value,
|
2327
|
+
raw: LATEST_RAW
|
2328
|
+
});
|
2313
2329
|
break;
|
2314
2330
|
case "big_int":
|
2315
2331
|
ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
|
@@ -2323,7 +2339,9 @@ function parse($TEXT, options) {
|
|
2323
2339
|
});
|
2324
2340
|
break;
|
2325
2341
|
case "regexp":
|
2326
|
-
|
2342
|
+
const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/);
|
2343
|
+
|
2344
|
+
ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } });
|
2327
2345
|
break;
|
2328
2346
|
case "atom":
|
2329
2347
|
switch (tok.value) {
|
@@ -2493,22 +2511,19 @@ function parse($TEXT, options) {
|
|
2493
2511
|
|
2494
2512
|
segments.push(new AST_TemplateSegment({
|
2495
2513
|
start: S.token,
|
2496
|
-
raw:
|
2514
|
+
raw: LATEST_RAW,
|
2497
2515
|
value: S.token.value,
|
2498
2516
|
end: S.token
|
2499
2517
|
}));
|
2500
|
-
|
2518
|
+
|
2519
|
+
while (!LATEST_TEMPLATE_END) {
|
2501
2520
|
next();
|
2502
2521
|
handle_regexp();
|
2503
2522
|
segments.push(expression(true));
|
2504
2523
|
|
2505
|
-
if (!is_token("template_substitution")) {
|
2506
|
-
unexpected();
|
2507
|
-
}
|
2508
|
-
|
2509
2524
|
segments.push(new AST_TemplateSegment({
|
2510
2525
|
start: S.token,
|
2511
|
-
raw:
|
2526
|
+
raw: LATEST_RAW,
|
2512
2527
|
value: S.token.value,
|
2513
2528
|
end: S.token
|
2514
2529
|
}));
|
@@ -2602,6 +2617,7 @@ function parse($TEXT, options) {
|
|
2602
2617
|
left: value,
|
2603
2618
|
operator: "=",
|
2604
2619
|
right: expression(false),
|
2620
|
+
logical: false,
|
2605
2621
|
end: prev()
|
2606
2622
|
});
|
2607
2623
|
}
|
@@ -3370,11 +3386,13 @@ function parse($TEXT, options) {
|
|
3370
3386
|
if (is("operator") && ASSIGNMENT.has(val)) {
|
3371
3387
|
if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
|
3372
3388
|
next();
|
3389
|
+
|
3373
3390
|
return new AST_Assign({
|
3374
3391
|
start : start,
|
3375
3392
|
left : left,
|
3376
3393
|
operator : val,
|
3377
3394
|
right : maybe_assign(no_in),
|
3395
|
+
logical : LOGICAL_ASSIGNMENT.has(val),
|
3378
3396
|
end : prev()
|
3379
3397
|
});
|
3380
3398
|
}
|
@@ -3518,8 +3536,54 @@ function DEFNODE(type, props, methods, base = AST_Node) {
|
|
3518
3536
|
return ctor;
|
3519
3537
|
}
|
3520
3538
|
|
3521
|
-
|
3522
|
-
|
3539
|
+
const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag);
|
3540
|
+
const set_tok_flag = (tok, flag, truth) => {
|
3541
|
+
if (truth) {
|
3542
|
+
tok.flags |= flag;
|
3543
|
+
} else {
|
3544
|
+
tok.flags &= ~flag;
|
3545
|
+
}
|
3546
|
+
};
|
3547
|
+
|
3548
|
+
const TOK_FLAG_NLB = 0b0001;
|
3549
|
+
const TOK_FLAG_QUOTE_SINGLE = 0b0010;
|
3550
|
+
const TOK_FLAG_QUOTE_EXISTS = 0b0100;
|
3551
|
+
|
3552
|
+
class AST_Token {
|
3553
|
+
constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
|
3554
|
+
this.flags = (nlb ? 1 : 0);
|
3555
|
+
|
3556
|
+
this.type = type;
|
3557
|
+
this.value = value;
|
3558
|
+
this.line = line;
|
3559
|
+
this.col = col;
|
3560
|
+
this.pos = pos;
|
3561
|
+
this.comments_before = comments_before;
|
3562
|
+
this.comments_after = comments_after;
|
3563
|
+
this.file = file;
|
3564
|
+
|
3565
|
+
Object.seal(this);
|
3566
|
+
}
|
3567
|
+
|
3568
|
+
get nlb() {
|
3569
|
+
return has_tok_flag(this, TOK_FLAG_NLB);
|
3570
|
+
}
|
3571
|
+
|
3572
|
+
set nlb(new_nlb) {
|
3573
|
+
set_tok_flag(this, TOK_FLAG_NLB, new_nlb);
|
3574
|
+
}
|
3575
|
+
|
3576
|
+
get quote() {
|
3577
|
+
return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS)
|
3578
|
+
? ""
|
3579
|
+
: (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"');
|
3580
|
+
}
|
3581
|
+
|
3582
|
+
set quote(quote_type) {
|
3583
|
+
set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
|
3584
|
+
set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
|
3585
|
+
}
|
3586
|
+
}
|
3523
3587
|
|
3524
3588
|
var AST_Node = DEFNODE("Node", "start end", {
|
3525
3589
|
_clone: function(deep) {
|
@@ -3988,7 +4052,7 @@ var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", {
|
|
3988
4052
|
$documentation: "A segment of a template string literal",
|
3989
4053
|
$propdoc: {
|
3990
4054
|
value: "Content of the segment",
|
3991
|
-
raw: "Raw
|
4055
|
+
raw: "Raw source of the segment",
|
3992
4056
|
}
|
3993
4057
|
});
|
3994
4058
|
|
@@ -4500,8 +4564,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|
4500
4564
|
},
|
4501
4565
|
});
|
4502
4566
|
|
4503
|
-
var AST_Assign = DEFNODE("Assign",
|
4567
|
+
var AST_Assign = DEFNODE("Assign", "logical", {
|
4504
4568
|
$documentation: "An assignment expression — `a = b + 5`",
|
4569
|
+
$propdoc: {
|
4570
|
+
logical: "Whether it's a logical assignment"
|
4571
|
+
}
|
4505
4572
|
}, AST_Binary);
|
4506
4573
|
|
4507
4574
|
var AST_DefaultAssign = DEFNODE("DefaultAssign", null, {
|
@@ -4792,11 +4859,11 @@ var AST_String = DEFNODE("String", "value quote", {
|
|
4792
4859
|
}
|
4793
4860
|
}, AST_Constant);
|
4794
4861
|
|
4795
|
-
var AST_Number = DEFNODE("Number", "value
|
4862
|
+
var AST_Number = DEFNODE("Number", "value raw", {
|
4796
4863
|
$documentation: "A number literal",
|
4797
4864
|
$propdoc: {
|
4798
4865
|
value: "[number] the numeric value",
|
4799
|
-
|
4866
|
+
raw: "[string] numeric value as string"
|
4800
4867
|
}
|
4801
4868
|
}, AST_Constant);
|
4802
4869
|
|
@@ -5875,6 +5942,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
5875
5942
|
return new AST_String(args);
|
5876
5943
|
case "number":
|
5877
5944
|
args.value = val;
|
5945
|
+
args.raw = M.raw || val.toString();
|
5878
5946
|
return new AST_Number(args);
|
5879
5947
|
case "boolean":
|
5880
5948
|
return new (val ? AST_True : AST_False)(args);
|
@@ -6399,22 +6467,10 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6399
6467
|
|
6400
6468
|
def_to_moz(AST_Constant, function To_Moz_Literal(M) {
|
6401
6469
|
var value = M.value;
|
6402
|
-
if (typeof value === "number" && (value < 0 || (value === 0 && 1 / value < 0))) {
|
6403
|
-
return {
|
6404
|
-
type: "UnaryExpression",
|
6405
|
-
operator: "-",
|
6406
|
-
prefix: true,
|
6407
|
-
argument: {
|
6408
|
-
type: "Literal",
|
6409
|
-
value: -value,
|
6410
|
-
raw: M.start.raw
|
6411
|
-
}
|
6412
|
-
};
|
6413
|
-
}
|
6414
6470
|
return {
|
6415
6471
|
type: "Literal",
|
6416
6472
|
value: value,
|
6417
|
-
raw: M.
|
6473
|
+
raw: M.raw || M.print_to_string()
|
6418
6474
|
};
|
6419
6475
|
});
|
6420
6476
|
|
@@ -6439,40 +6495,36 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6439
6495
|
|
6440
6496
|
/* -----[ tools ]----- */
|
6441
6497
|
|
6442
|
-
function raw_token(moznode) {
|
6443
|
-
if (moznode.type == "Literal") {
|
6444
|
-
return moznode.raw != null ? moznode.raw : moznode.value + "";
|
6445
|
-
}
|
6446
|
-
}
|
6447
|
-
|
6448
6498
|
function my_start_token(moznode) {
|
6449
6499
|
var loc = moznode.loc, start = loc && loc.start;
|
6450
6500
|
var range = moznode.range;
|
6451
|
-
return new AST_Token(
|
6452
|
-
|
6453
|
-
|
6454
|
-
|
6455
|
-
|
6456
|
-
|
6457
|
-
|
6458
|
-
|
6459
|
-
|
6460
|
-
|
6501
|
+
return new AST_Token(
|
6502
|
+
"",
|
6503
|
+
"",
|
6504
|
+
start && start.line || 0,
|
6505
|
+
start && start.column || 0,
|
6506
|
+
range ? range [0] : moznode.start,
|
6507
|
+
false,
|
6508
|
+
[],
|
6509
|
+
[],
|
6510
|
+
loc && loc.source,
|
6511
|
+
);
|
6461
6512
|
}
|
6462
6513
|
|
6463
6514
|
function my_end_token(moznode) {
|
6464
6515
|
var loc = moznode.loc, end = loc && loc.end;
|
6465
6516
|
var range = moznode.range;
|
6466
|
-
return new AST_Token(
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
|
6471
|
-
|
6472
|
-
|
6473
|
-
|
6474
|
-
|
6475
|
-
|
6517
|
+
return new AST_Token(
|
6518
|
+
"",
|
6519
|
+
"",
|
6520
|
+
end && end.line || 0,
|
6521
|
+
end && end.column || 0,
|
6522
|
+
range ? range [0] : moznode.end,
|
6523
|
+
false,
|
6524
|
+
[],
|
6525
|
+
[],
|
6526
|
+
loc && loc.source,
|
6527
|
+
);
|
6476
6528
|
}
|
6477
6529
|
|
6478
6530
|
function map(moztype, mytype, propmap) {
|
@@ -7868,6 +7920,9 @@ function OutputStream(options) {
|
|
7868
7920
|
}
|
7869
7921
|
output.print("`");
|
7870
7922
|
});
|
7923
|
+
DEFPRINT(AST_TemplateSegment, function(self, output) {
|
7924
|
+
output.print_template_string_chars(self.value);
|
7925
|
+
});
|
7871
7926
|
|
7872
7927
|
AST_Arrow.DEFMETHOD("_do_print", function(output) {
|
7873
7928
|
var self = this;
|
@@ -8605,8 +8660,8 @@ function OutputStream(options) {
|
|
8605
8660
|
output.print_string(self.getValue(), self.quote, output.in_directive);
|
8606
8661
|
});
|
8607
8662
|
DEFPRINT(AST_Number, function(self, output) {
|
8608
|
-
if ((output.option("keep_numbers") || output.use_asm) && self.
|
8609
|
-
output.print(self.
|
8663
|
+
if ((output.option("keep_numbers") || output.use_asm) && self.raw) {
|
8664
|
+
output.print(self.raw);
|
8610
8665
|
} else {
|
8611
8666
|
output.print(make_num(self.getValue()));
|
8612
8667
|
}
|
@@ -10664,6 +10719,7 @@ AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
|
|
10664
10719
|
function read_property(obj, key) {
|
10665
10720
|
key = get_value(key);
|
10666
10721
|
if (key instanceof AST_Node) return;
|
10722
|
+
|
10667
10723
|
var value;
|
10668
10724
|
if (obj instanceof AST_Array) {
|
10669
10725
|
var elements = obj.elements;
|
@@ -10678,6 +10734,7 @@ function read_property(obj, key) {
|
|
10678
10734
|
if (!value && props[i].key === key) value = props[i].value;
|
10679
10735
|
}
|
10680
10736
|
}
|
10737
|
+
|
10681
10738
|
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
10682
10739
|
}
|
10683
10740
|
|
@@ -10810,38 +10867,56 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
10810
10867
|
|| value instanceof AST_This;
|
10811
10868
|
}
|
10812
10869
|
|
10813
|
-
|
10870
|
+
// A definition "escapes" when its value can leave the point of use.
|
10871
|
+
// Example: `a = b || c`
|
10872
|
+
// In this example, "b" and "c" are escaping, because they're going into "a"
|
10873
|
+
//
|
10874
|
+
// def.escaped is != 0 when it escapes.
|
10875
|
+
//
|
10876
|
+
// When greater than 1, it means that N chained properties will be read off
|
10877
|
+
// of that def before an escape occurs. This is useful for evaluating
|
10878
|
+
// property accesses, where you need to know when to stop.
|
10879
|
+
function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
|
10814
10880
|
var parent = tw.parent(level);
|
10815
10881
|
if (value) {
|
10816
10882
|
if (value.is_constant()) return;
|
10817
10883
|
if (value instanceof AST_ClassExpression) return;
|
10818
10884
|
}
|
10819
|
-
|
10885
|
+
|
10886
|
+
if (
|
10887
|
+
parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
|
10820
10888
|
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
10821
10889
|
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
10822
10890
|
|| parent instanceof AST_VarDef && node === parent.value
|
10823
|
-
|| parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
|
10891
|
+
|| parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
|
10892
|
+
) {
|
10824
10893
|
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
10825
10894
|
if (!d.escaped || d.escaped > depth) d.escaped = depth;
|
10826
10895
|
return;
|
10827
|
-
} else if (
|
10896
|
+
} else if (
|
10897
|
+
parent instanceof AST_Array
|
10828
10898
|
|| parent instanceof AST_Await
|
10829
10899
|
|| parent instanceof AST_Binary && lazy_op.has(parent.operator)
|
10830
10900
|
|| parent instanceof AST_Conditional && node !== parent.condition
|
10831
10901
|
|| parent instanceof AST_Expansion
|
10832
|
-
|| parent instanceof AST_Sequence && node === parent.tail_node()
|
10902
|
+
|| parent instanceof AST_Sequence && node === parent.tail_node()
|
10903
|
+
) {
|
10833
10904
|
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
10834
10905
|
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
10835
10906
|
var obj = tw.parent(level + 1);
|
10907
|
+
|
10836
10908
|
mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
|
10837
10909
|
} else if (parent instanceof AST_PropAccess && node === parent.expression) {
|
10838
10910
|
value = read_property(value, parent.property);
|
10911
|
+
|
10839
10912
|
mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
|
10840
10913
|
if (value) return;
|
10841
10914
|
}
|
10915
|
+
|
10842
10916
|
if (level > 0) return;
|
10843
10917
|
if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
|
10844
10918
|
if (parent instanceof AST_SimpleStatement) return;
|
10919
|
+
|
10845
10920
|
d.direct_access = true;
|
10846
10921
|
}
|
10847
10922
|
|
@@ -10865,32 +10940,64 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
10865
10940
|
suppress(node.left);
|
10866
10941
|
return;
|
10867
10942
|
}
|
10943
|
+
|
10944
|
+
const finish_walk = () => {
|
10945
|
+
if (node.logical) {
|
10946
|
+
node.left.walk(tw);
|
10947
|
+
|
10948
|
+
push(tw);
|
10949
|
+
node.right.walk(tw);
|
10950
|
+
pop(tw);
|
10951
|
+
|
10952
|
+
return true;
|
10953
|
+
}
|
10954
|
+
};
|
10955
|
+
|
10868
10956
|
var sym = node.left;
|
10869
|
-
if (!(sym instanceof AST_SymbolRef)) return;
|
10957
|
+
if (!(sym instanceof AST_SymbolRef)) return finish_walk();
|
10958
|
+
|
10870
10959
|
var def = sym.definition();
|
10871
10960
|
var safe = safe_to_assign(tw, def, sym.scope, node.right);
|
10872
10961
|
def.assignments++;
|
10873
|
-
if (!safe) return;
|
10962
|
+
if (!safe) return finish_walk();
|
10963
|
+
|
10874
10964
|
var fixed = def.fixed;
|
10875
|
-
if (!fixed && node.operator != "=") return;
|
10965
|
+
if (!fixed && node.operator != "=" && !node.logical) return finish_walk();
|
10966
|
+
|
10876
10967
|
var eq = node.operator == "=";
|
10877
10968
|
var value = eq ? node.right : node;
|
10878
|
-
if (is_modified(compressor, tw, node, value, 0)) return;
|
10969
|
+
if (is_modified(compressor, tw, node, value, 0)) return finish_walk();
|
10970
|
+
|
10879
10971
|
def.references.push(sym);
|
10880
|
-
|
10881
|
-
|
10882
|
-
|
10883
|
-
|
10884
|
-
|
10885
|
-
|
10886
|
-
|
10887
|
-
|
10888
|
-
|
10889
|
-
|
10972
|
+
|
10973
|
+
if (!node.logical) {
|
10974
|
+
if (!eq) def.chained = true;
|
10975
|
+
|
10976
|
+
def.fixed = eq ? function() {
|
10977
|
+
return node.right;
|
10978
|
+
} : function() {
|
10979
|
+
return make_node(AST_Binary, node, {
|
10980
|
+
operator: node.operator.slice(0, -1),
|
10981
|
+
left: fixed instanceof AST_Node ? fixed : fixed(),
|
10982
|
+
right: node.right
|
10983
|
+
});
|
10984
|
+
};
|
10985
|
+
}
|
10986
|
+
|
10987
|
+
if (node.logical) {
|
10988
|
+
mark(tw, def, false);
|
10989
|
+
push(tw);
|
10990
|
+
node.right.walk(tw);
|
10991
|
+
pop(tw);
|
10992
|
+
return true;
|
10993
|
+
}
|
10994
|
+
|
10890
10995
|
mark(tw, def, false);
|
10891
10996
|
node.right.walk(tw);
|
10892
10997
|
mark(tw, def, true);
|
10998
|
+
|
10893
10999
|
mark_escaped(tw, def, sym.scope, node, value, 0, 1);
|
11000
|
+
|
10894
11001
|
return true;
|
10895
11002
|
});
|
10896
11003
|
def_reduce_vars(AST_Binary, function(tw) {
|
@@ -11493,7 +11600,8 @@ function tighten_body(statements, compressor) {
|
|
11493
11600
|
}
|
11494
11601
|
// Stop immediately if these node types are encountered
|
11495
11602
|
var parent = scanner.parent();
|
11496
|
-
if (node instanceof AST_Assign
|
11603
|
+
if (node instanceof AST_Assign
|
11604
|
+
&& (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
|
11497
11605
|
|| node instanceof AST_Await
|
11498
11606
|
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
11499
11607
|
|| node instanceof AST_Debugger
|
@@ -11561,6 +11669,7 @@ function tighten_body(statements, compressor) {
|
|
11561
11669
|
}
|
11562
11670
|
return make_node(AST_Assign, candidate, {
|
11563
11671
|
operator: "=",
|
11672
|
+
logical: false,
|
11564
11673
|
left: make_node(AST_SymbolRef, candidate.name, candidate.name),
|
11565
11674
|
right: value
|
11566
11675
|
});
|
@@ -11865,6 +11974,7 @@ function tighten_body(statements, compressor) {
|
|
11865
11974
|
var parent = scanner.parent(level);
|
11866
11975
|
if (parent instanceof AST_Assign) {
|
11867
11976
|
if (write_only
|
11977
|
+
&& !parent.logical
|
11868
11978
|
&& !(parent.left instanceof AST_PropAccess
|
11869
11979
|
|| lvalues.has(parent.left.name))) {
|
11870
11980
|
return find_stop(parent, level + 1, write_only);
|
@@ -11919,7 +12029,9 @@ function tighten_body(statements, compressor) {
|
|
11919
12029
|
}
|
11920
12030
|
|
11921
12031
|
function get_lhs(expr) {
|
11922
|
-
if (expr instanceof
|
12032
|
+
if (expr instanceof AST_Assign && expr.logical) {
|
12033
|
+
return false;
|
12034
|
+
} else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
|
11923
12035
|
var def = expr.name.definition();
|
11924
12036
|
if (!member(expr.name, def.orig)) return;
|
11925
12037
|
var referenced = def.references.length - def.replaced;
|
@@ -11930,14 +12042,20 @@ function tighten_body(statements, compressor) {
|
|
11930
12042
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
11931
12043
|
}
|
11932
12044
|
} else {
|
11933
|
-
const lhs = expr
|
12045
|
+
const lhs = expr instanceof AST_Assign
|
12046
|
+
? expr.left
|
12047
|
+
: expr.expression;
|
11934
12048
|
return !is_ref_of(lhs, AST_SymbolConst)
|
11935
12049
|
&& !is_ref_of(lhs, AST_SymbolLet) && lhs;
|
11936
12050
|
}
|
11937
12051
|
}
|
11938
12052
|
|
11939
12053
|
function get_rvalue(expr) {
|
11940
|
-
|
12054
|
+
if (expr instanceof AST_Assign) {
|
12055
|
+
return expr.right;
|
12056
|
+
} else {
|
12057
|
+
return expr.value;
|
12058
|
+
}
|
11941
12059
|
}
|
11942
12060
|
|
11943
12061
|
function get_lvalues(expr) {
|
@@ -11996,7 +12114,9 @@ function tighten_body(statements, compressor) {
|
|
11996
12114
|
&& !(in_loop
|
11997
12115
|
&& (lvalues.has(lhs.name)
|
11998
12116
|
|| candidate instanceof AST_Unary
|
11999
|
-
|| candidate instanceof AST_Assign
|
12117
|
+
|| (candidate instanceof AST_Assign
|
12118
|
+
&& !candidate.logical
|
12119
|
+
&& candidate.operator != "=")));
|
12000
12120
|
}
|
12001
12121
|
|
12002
12122
|
function value_has_side_effects(expr) {
|
@@ -12423,7 +12543,7 @@ function tighten_body(statements, compressor) {
|
|
12423
12543
|
var def = defn.definitions[defn.definitions.length - 1];
|
12424
12544
|
if (!(def.value instanceof AST_Object)) return;
|
12425
12545
|
var exprs;
|
12426
|
-
if (body instanceof AST_Assign) {
|
12546
|
+
if (body instanceof AST_Assign && !body.logical) {
|
12427
12547
|
exprs = [ body ];
|
12428
12548
|
} else if (body instanceof AST_Sequence) {
|
12429
12549
|
exprs = body.expressions.slice();
|
@@ -12646,6 +12766,8 @@ function is_undefined(node, compressor) {
|
|
12646
12766
|
&& (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
|
12647
12767
|
});
|
12648
12768
|
def_may_throw_on_access(AST_Assign, function(compressor) {
|
12769
|
+
if (this.logical) return true;
|
12770
|
+
|
12649
12771
|
return this.operator == "="
|
12650
12772
|
&& this.right._dot_throw(compressor);
|
12651
12773
|
});
|
@@ -13870,6 +13992,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
13870
13992
|
var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
|
13871
13993
|
const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
|
13872
13994
|
if (node instanceof AST_Assign
|
13995
|
+
&& !node.logical
|
13873
13996
|
&& (has_flag(node, WRITE_ONLY) || node.operator == "=")
|
13874
13997
|
) {
|
13875
13998
|
return node.left;
|
@@ -14088,6 +14211,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
14088
14211
|
sym.references.push(ref);
|
14089
14212
|
var assign = make_node(AST_Assign, def, {
|
14090
14213
|
operator: "=",
|
14214
|
+
logical: false,
|
14091
14215
|
left: ref,
|
14092
14216
|
right: def.value
|
14093
14217
|
});
|
@@ -14523,6 +14647,8 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
14523
14647
|
}
|
14524
14648
|
});
|
14525
14649
|
def_drop_side_effect_free(AST_Assign, function(compressor) {
|
14650
|
+
if (this.logical) return this;
|
14651
|
+
|
14526
14652
|
var left = this.left;
|
14527
14653
|
if (left.has_side_effects(compressor)
|
14528
14654
|
|| compressor.has_directive("use strict")
|
@@ -15119,6 +15245,7 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
15119
15245
|
var name = make_node(AST_SymbolRef, def.name, def.name);
|
15120
15246
|
assignments.push(make_node(AST_Assign, def, {
|
15121
15247
|
operator : "=",
|
15248
|
+
logical: false,
|
15122
15249
|
left : name,
|
15123
15250
|
right : def.value
|
15124
15251
|
}));
|
@@ -15149,6 +15276,17 @@ def_optimize(AST_Definitions, function(self) {
|
|
15149
15276
|
return self;
|
15150
15277
|
});
|
15151
15278
|
|
15279
|
+
def_optimize(AST_VarDef, function(self) {
|
15280
|
+
if (
|
15281
|
+
self.name instanceof AST_SymbolLet
|
15282
|
+
&& self.value != null
|
15283
|
+
&& is_undefined(self.value)
|
15284
|
+
) {
|
15285
|
+
self.value = null;
|
15286
|
+
}
|
15287
|
+
return self;
|
15288
|
+
});
|
15289
|
+
|
15152
15290
|
def_optimize(AST_Import, function(self) {
|
15153
15291
|
return self;
|
15154
15292
|
});
|
@@ -15733,6 +15871,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
15733
15871
|
def.references.push(sym);
|
15734
15872
|
if (value) expressions.push(make_node(AST_Assign, self, {
|
15735
15873
|
operator: "=",
|
15874
|
+
logical: false,
|
15736
15875
|
left: sym,
|
15737
15876
|
right: value.clone()
|
15738
15877
|
}));
|
@@ -15776,6 +15915,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
15776
15915
|
def.references.push(sym);
|
15777
15916
|
expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
|
15778
15917
|
operator: "=",
|
15918
|
+
logical: false,
|
15779
15919
|
left: sym,
|
15780
15920
|
right: make_node(AST_Undefined, name)
|
15781
15921
|
}));
|
@@ -16296,7 +16436,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
16296
16436
|
var l = self.left;
|
16297
16437
|
var r = self.right.evaluate(compressor);
|
16298
16438
|
if (r != self.right) {
|
16299
|
-
l.segments[l.segments.length - 1].value += r
|
16439
|
+
l.segments[l.segments.length - 1].value += String(r);
|
16300
16440
|
return l;
|
16301
16441
|
}
|
16302
16442
|
}
|
@@ -16305,7 +16445,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
16305
16445
|
var r = self.right;
|
16306
16446
|
var l = self.left.evaluate(compressor);
|
16307
16447
|
if (l != self.left) {
|
16308
|
-
r.segments[0].value = l
|
16448
|
+
r.segments[0].value = String(l) + r.segments[0].value;
|
16309
16449
|
return r;
|
16310
16450
|
}
|
16311
16451
|
}
|
@@ -16733,6 +16873,10 @@ function is_reachable(self, defs) {
|
|
16733
16873
|
const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &");
|
16734
16874
|
const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
|
16735
16875
|
def_optimize(AST_Assign, function(self, compressor) {
|
16876
|
+
if (self.logical) {
|
16877
|
+
return self.lift_sequences(compressor);
|
16878
|
+
}
|
16879
|
+
|
16736
16880
|
var def;
|
16737
16881
|
if (compressor.option("dead_code")
|
16738
16882
|
&& self.left instanceof AST_SymbolRef
|
@@ -16950,16 +17094,20 @@ def_optimize(AST_Conditional, function(self, compressor) {
|
|
16950
17094
|
// |
|
16951
17095
|
// v
|
16952
17096
|
// exp = foo ? something : something_else;
|
16953
|
-
if (
|
17097
|
+
if (
|
17098
|
+
consequent instanceof AST_Assign
|
16954
17099
|
&& alternative instanceof AST_Assign
|
16955
|
-
&& consequent.operator
|
17100
|
+
&& consequent.operator === alternative.operator
|
17101
|
+
&& consequent.logical === alternative.logical
|
16956
17102
|
&& consequent.left.equivalent_to(alternative.left)
|
16957
17103
|
&& (!self.condition.has_side_effects(compressor)
|
16958
17104
|
|| consequent.operator == "="
|
16959
|
-
&& !consequent.left.has_side_effects(compressor))
|
17105
|
+
&& !consequent.left.has_side_effects(compressor))
|
17106
|
+
) {
|
16960
17107
|
return make_node(AST_Assign, self, {
|
16961
17108
|
operator: consequent.operator,
|
16962
17109
|
left: consequent.left,
|
17110
|
+
logical: consequent.logical,
|
16963
17111
|
right: make_node(AST_Conditional, self, {
|
16964
17112
|
condition: self.condition,
|
16965
17113
|
consequent: consequent.right,
|
@@ -17555,9 +17703,12 @@ def_optimize(AST_Yield, function(self, compressor) {
|
|
17555
17703
|
});
|
17556
17704
|
|
17557
17705
|
def_optimize(AST_TemplateString, function(self, compressor) {
|
17558
|
-
if (
|
17559
|
-
|
17706
|
+
if (
|
17707
|
+
!compressor.option("evaluate")
|
17708
|
+
|| compressor.parent() instanceof AST_PrefixedTemplateString
|
17709
|
+
) {
|
17560
17710
|
return self;
|
17711
|
+
}
|
17561
17712
|
|
17562
17713
|
var segments = [];
|
17563
17714
|
for (var i = 0; i < self.segments.length; i++) {
|
@@ -17593,7 +17744,17 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
17593
17744
|
if (segments.length == 1) {
|
17594
17745
|
return make_node(AST_String, self, segments[0]);
|
17595
17746
|
}
|
17596
|
-
|
17747
|
+
|
17748
|
+
if (
|
17749
|
+
segments.length === 3
|
17750
|
+
&& segments[1] instanceof AST_Node
|
17751
|
+
&& (
|
17752
|
+
segments[1].is_string(compressor)
|
17753
|
+
|| segments[1].is_number(compressor)
|
17754
|
+
|| is_nullish(segments[1])
|
17755
|
+
|| compressor.option("unsafe")
|
17756
|
+
)
|
17757
|
+
) {
|
17597
17758
|
// `foo${bar}` => "foo" + bar
|
17598
17759
|
if (segments[2].value === "") {
|
17599
17760
|
return make_node(AST_Binary, self, {
|
@@ -17604,7 +17765,7 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
17604
17765
|
right: segments[1],
|
17605
17766
|
});
|
17606
17767
|
}
|
17607
|
-
//
|
17768
|
+
// `${bar}baz` => bar + "baz"
|
17608
17769
|
if (segments[0].value === "") {
|
17609
17770
|
return make_node(AST_Binary, self, {
|
17610
17771
|
operator: "+",
|
@@ -26661,4 +26822,3 @@ exports._run_cli = run_cli;
|
|
26661
26822
|
exports.minify = minify;
|
26662
26823
|
|
26663
26824
|
})));
|
26664
|
-
//# sourceMappingURL=bundle.min.js.map
|