terser 5.46.0 → 5.46.2
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 +12 -0
- package/dist/bundle.min.js +67 -43
- package/lib/compress/drop-side-effect-free.js +2 -2
- package/lib/compress/drop-unused.js +2 -0
- package/lib/compress/evaluate.js +24 -17
- package/lib/compress/import-export.js +121 -0
- package/lib/compress/inference.js +5 -2
- package/lib/equivalent-to.js +4 -1
- package/lib/output.js +15 -15
- package/lib/parse.js +15 -6
- package/package.json +1 -1
- package/tools/domprops.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v5.46.2
|
|
4
|
+
|
|
5
|
+
- `unused` option: delete computed keys of concise methods and getters/setters.
|
|
6
|
+
- `Error.cause` added to DOM properties list
|
|
7
|
+
- Don't consider `foo.bar` and `foo["bar"]` to be equivalent when property mangler is enabled with `keep_quoted=strict` option.
|
|
8
|
+
|
|
9
|
+
## v5.46.1
|
|
10
|
+
|
|
11
|
+
- Fix extremely slow (seemed like a freeze) `evaluate` of method chains
|
|
12
|
+
- Parse extremely large floating-point number literals as `Infinity`
|
|
13
|
+
- Remove parens from comma expressions in computed property access (`foo[(1, 2)]`)
|
|
14
|
+
|
|
3
15
|
## v5.46.0
|
|
4
16
|
|
|
5
17
|
- Add "observedAttributes" domprop (#1652)
|
package/dist/bundle.min.js
CHANGED
|
@@ -2464,12 +2464,20 @@ function parse($TEXT, options) {
|
|
|
2464
2464
|
ret = _make_symbol(AST_SymbolRef);
|
|
2465
2465
|
break;
|
|
2466
2466
|
case "num":
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2467
|
+
if (tok.value === Infinity) {
|
|
2468
|
+
// very large float values are parsed as Infinity
|
|
2469
|
+
ret = new AST_Infinity({
|
|
2470
|
+
start: tok,
|
|
2471
|
+
end: tok,
|
|
2472
|
+
});
|
|
2473
|
+
} else {
|
|
2474
|
+
ret = new AST_Number({
|
|
2475
|
+
start: tok,
|
|
2476
|
+
end: tok,
|
|
2477
|
+
value: tok.value,
|
|
2478
|
+
raw: LATEST_RAW
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2473
2481
|
break;
|
|
2474
2482
|
case "big_int":
|
|
2475
2483
|
ret = new AST_BigInt({
|
|
@@ -10272,21 +10280,21 @@ function OutputStream(options) {
|
|
|
10272
10280
|
|
|
10273
10281
|
PARENS(AST_Sequence, function(output) {
|
|
10274
10282
|
var p = output.parent();
|
|
10275
|
-
return p instanceof AST_Call
|
|
10276
|
-
|| p instanceof AST_Unary
|
|
10277
|
-
|| p instanceof AST_Binary
|
|
10278
|
-
|| p instanceof AST_VarDefLike
|
|
10279
|
-
|| p instanceof AST_PropAccess
|
|
10280
|
-
|| p instanceof AST_Array
|
|
10281
|
-
|| p instanceof AST_ObjectProperty
|
|
10282
|
-
|| p instanceof AST_Conditional
|
|
10283
|
-
|
|
10284
|
-
|| p instanceof AST_Arrow
|
|
10285
|
-
|| p instanceof AST_DefaultAssign
|
|
10286
|
-
|| p instanceof AST_Expansion
|
|
10287
|
-
|| p instanceof AST_ForOf && this === p.object
|
|
10288
|
-
|| p instanceof AST_Yield
|
|
10289
|
-
|| p instanceof AST_Export
|
|
10283
|
+
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
|
10284
|
+
|| p instanceof AST_Unary // !(foo, bar, baz)
|
|
10285
|
+
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
|
10286
|
+
|| p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4
|
|
10287
|
+
|| p instanceof AST_PropAccess && this !== p.property // (1, {foo:2}).foo, (1, {foo:2})["foo"], not foo[1, 2]
|
|
10288
|
+
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
|
10289
|
+
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
|
10290
|
+
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
|
10291
|
+
* ==> 20 (side effect, set a := 10 and b := 20) */
|
|
10292
|
+
|| p instanceof AST_Arrow // x => (x, x)
|
|
10293
|
+
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
|
10294
|
+
|| p instanceof AST_Expansion // [...(a, b)]
|
|
10295
|
+
|| p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
|
|
10296
|
+
|| p instanceof AST_Yield // yield (foo, bar)
|
|
10297
|
+
|| p instanceof AST_Export // export default (foo, bar)
|
|
10290
10298
|
;
|
|
10291
10299
|
});
|
|
10292
10300
|
|
|
@@ -11905,7 +11913,10 @@ AST_PropAccess.prototype.shallow_cmp = pass_through;
|
|
|
11905
11913
|
AST_Chain.prototype.shallow_cmp = pass_through;
|
|
11906
11914
|
|
|
11907
11915
|
AST_Dot.prototype.shallow_cmp = function(other) {
|
|
11908
|
-
return
|
|
11916
|
+
return (
|
|
11917
|
+
this.property === other.property
|
|
11918
|
+
&& !!this.quote === !!other.quote
|
|
11919
|
+
);
|
|
11909
11920
|
};
|
|
11910
11921
|
|
|
11911
11922
|
AST_DotHash.prototype.shallow_cmp = function(other) {
|
|
@@ -14869,10 +14880,13 @@ var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date e
|
|
|
14869
14880
|
AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
|
|
14870
14881
|
if (compressor.option("unsafe")) {
|
|
14871
14882
|
var expr = this.expression;
|
|
14872
|
-
var first_arg
|
|
14883
|
+
var first_arg;
|
|
14873
14884
|
if (
|
|
14874
14885
|
expr.expression && expr.expression.name === "hasOwnProperty" &&
|
|
14875
|
-
(
|
|
14886
|
+
(
|
|
14887
|
+
(first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor))) == null
|
|
14888
|
+
|| first_arg.thedef && first_arg.thedef.undeclared
|
|
14889
|
+
)
|
|
14876
14890
|
) {
|
|
14877
14891
|
return false;
|
|
14878
14892
|
}
|
|
@@ -15375,6 +15389,15 @@ def_eval(AST_SymbolRef, function (compressor, depth) {
|
|
|
15375
15389
|
return value;
|
|
15376
15390
|
});
|
|
15377
15391
|
|
|
15392
|
+
def_eval(AST_Chain, function (compressor, depth) {
|
|
15393
|
+
const evaluated = this.expression._eval(compressor, depth, /*ast_chain=*/true);
|
|
15394
|
+
return evaluated === nullish
|
|
15395
|
+
? undefined
|
|
15396
|
+
: evaluated === this.expression
|
|
15397
|
+
? this
|
|
15398
|
+
: evaluated;
|
|
15399
|
+
});
|
|
15400
|
+
|
|
15378
15401
|
const global_objs = { Array, Math, Number, Object, String };
|
|
15379
15402
|
|
|
15380
15403
|
const regexp_flags = new Set([
|
|
@@ -15386,9 +15409,13 @@ const regexp_flags = new Set([
|
|
|
15386
15409
|
"unicode",
|
|
15387
15410
|
]);
|
|
15388
15411
|
|
|
15389
|
-
def_eval(AST_PropAccess, function (compressor, depth) {
|
|
15390
|
-
let obj = this.
|
|
15391
|
-
|
|
15412
|
+
def_eval(AST_PropAccess, function (compressor, depth, ast_chain) {
|
|
15413
|
+
let obj = (ast_chain || this.property === "length" || compressor.option("unsafe"))
|
|
15414
|
+
&& this.expression._eval(compressor, depth + 1, ast_chain);
|
|
15415
|
+
|
|
15416
|
+
if (ast_chain) {
|
|
15417
|
+
if (obj === nullish || (this.optional && obj == null)) return nullish;
|
|
15418
|
+
}
|
|
15392
15419
|
|
|
15393
15420
|
// `.length` of strings and arrays is always safe
|
|
15394
15421
|
if (this.property === "length") {
|
|
@@ -15459,26 +15486,19 @@ def_eval(AST_PropAccess, function (compressor, depth) {
|
|
|
15459
15486
|
return this;
|
|
15460
15487
|
});
|
|
15461
15488
|
|
|
15462
|
-
def_eval(
|
|
15463
|
-
const evaluated = this.expression._eval(compressor, depth);
|
|
15464
|
-
return evaluated === nullish
|
|
15465
|
-
? undefined
|
|
15466
|
-
: evaluated === this.expression
|
|
15467
|
-
? this
|
|
15468
|
-
: evaluated;
|
|
15469
|
-
});
|
|
15470
|
-
|
|
15471
|
-
def_eval(AST_Call, function (compressor, depth) {
|
|
15489
|
+
def_eval(AST_Call, function (compressor, depth, ast_chain) {
|
|
15472
15490
|
var exp = this.expression;
|
|
15473
15491
|
|
|
15474
|
-
|
|
15475
|
-
|
|
15492
|
+
if (ast_chain) {
|
|
15493
|
+
const callee = exp._eval(compressor, depth, ast_chain);
|
|
15494
|
+
if (callee === nullish || (this.optional && callee == null)) return nullish;
|
|
15495
|
+
}
|
|
15476
15496
|
|
|
15477
15497
|
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
|
15478
15498
|
var key = exp.property;
|
|
15479
15499
|
if (key instanceof AST_Node) {
|
|
15480
15500
|
key = key._eval(compressor, depth);
|
|
15481
|
-
if (key
|
|
15501
|
+
if (typeof key !== "string" && typeof key !== "number")
|
|
15482
15502
|
return this;
|
|
15483
15503
|
}
|
|
15484
15504
|
var val;
|
|
@@ -15496,7 +15516,8 @@ def_eval(AST_Call, function (compressor, depth) {
|
|
|
15496
15516
|
if (!is_pure_native_fn(e.name, key)) return this;
|
|
15497
15517
|
val = global_objs[e.name];
|
|
15498
15518
|
} else {
|
|
15499
|
-
val = e._eval(compressor, depth + 1);
|
|
15519
|
+
val = e._eval(compressor, depth + 1, /* don't pass ast_chain (exponential work) */);
|
|
15520
|
+
|
|
15500
15521
|
if (val === e || !val)
|
|
15501
15522
|
return this;
|
|
15502
15523
|
if (!is_pure_native_method(val.constructor.name, key))
|
|
@@ -15791,8 +15812,8 @@ def_drop_side_effect_free([
|
|
|
15791
15812
|
AST_ConciseMethod,
|
|
15792
15813
|
AST_ObjectGetter,
|
|
15793
15814
|
AST_ObjectSetter,
|
|
15794
|
-
], function () {
|
|
15795
|
-
return this.computed_key() ? this.key : null;
|
|
15815
|
+
], function (compressor, first_in_statement) {
|
|
15816
|
+
return this.computed_key() ? this.key.drop_side_effect_free(compressor, first_in_statement) : null;
|
|
15796
15817
|
});
|
|
15797
15818
|
|
|
15798
15819
|
def_drop_side_effect_free([
|
|
@@ -16014,6 +16035,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
|
16014
16035
|
return scan_ref_scoped(node, descend);
|
|
16015
16036
|
});
|
|
16016
16037
|
self.walk(tw);
|
|
16038
|
+
|
|
16017
16039
|
// pass 2: for every used symbol we need to walk its
|
|
16018
16040
|
// initialization code to figure out if it uses other
|
|
16019
16041
|
// symbols (that may not be in_use).
|
|
@@ -16024,6 +16046,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
|
16024
16046
|
init.walk(tw);
|
|
16025
16047
|
});
|
|
16026
16048
|
});
|
|
16049
|
+
|
|
16027
16050
|
// pass 3: we should drop declarations not in_use
|
|
16028
16051
|
var tt = new TreeTransformer(
|
|
16029
16052
|
function before(node, descend, in_list) {
|
|
@@ -27110,6 +27133,7 @@ var domprops = [
|
|
|
27110
27133
|
"cast",
|
|
27111
27134
|
"catch",
|
|
27112
27135
|
"category",
|
|
27136
|
+
"cause",
|
|
27113
27137
|
"cbrt",
|
|
27114
27138
|
"cd",
|
|
27115
27139
|
"ceil",
|
|
@@ -312,8 +312,8 @@ def_drop_side_effect_free([
|
|
|
312
312
|
AST_ConciseMethod,
|
|
313
313
|
AST_ObjectGetter,
|
|
314
314
|
AST_ObjectSetter,
|
|
315
|
-
], function () {
|
|
316
|
-
return this.computed_key() ? this.key : null;
|
|
315
|
+
], function (compressor, first_in_statement) {
|
|
316
|
+
return this.computed_key() ? this.key.drop_side_effect_free(compressor, first_in_statement) : null;
|
|
317
317
|
});
|
|
318
318
|
|
|
319
319
|
def_drop_side_effect_free([
|
|
@@ -212,6 +212,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
|
212
212
|
return scan_ref_scoped(node, descend);
|
|
213
213
|
});
|
|
214
214
|
self.walk(tw);
|
|
215
|
+
|
|
215
216
|
// pass 2: for every used symbol we need to walk its
|
|
216
217
|
// initialization code to figure out if it uses other
|
|
217
218
|
// symbols (that may not be in_use).
|
|
@@ -222,6 +223,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
|
222
223
|
init.walk(tw);
|
|
223
224
|
});
|
|
224
225
|
});
|
|
226
|
+
|
|
225
227
|
// pass 3: we should drop declarations not in_use
|
|
226
228
|
var tt = new TreeTransformer(
|
|
227
229
|
function before(node, descend, in_list) {
|
package/lib/compress/evaluate.js
CHANGED
|
@@ -371,6 +371,15 @@ def_eval(AST_SymbolRef, function (compressor, depth) {
|
|
|
371
371
|
return value;
|
|
372
372
|
});
|
|
373
373
|
|
|
374
|
+
def_eval(AST_Chain, function (compressor, depth) {
|
|
375
|
+
const evaluated = this.expression._eval(compressor, depth, /*ast_chain=*/true);
|
|
376
|
+
return evaluated === nullish
|
|
377
|
+
? undefined
|
|
378
|
+
: evaluated === this.expression
|
|
379
|
+
? this
|
|
380
|
+
: evaluated;
|
|
381
|
+
});
|
|
382
|
+
|
|
374
383
|
const global_objs = { Array, Math, Number, Object, String };
|
|
375
384
|
|
|
376
385
|
const regexp_flags = new Set([
|
|
@@ -382,9 +391,13 @@ const regexp_flags = new Set([
|
|
|
382
391
|
"unicode",
|
|
383
392
|
]);
|
|
384
393
|
|
|
385
|
-
def_eval(AST_PropAccess, function (compressor, depth) {
|
|
386
|
-
let obj = this.
|
|
387
|
-
|
|
394
|
+
def_eval(AST_PropAccess, function (compressor, depth, ast_chain) {
|
|
395
|
+
let obj = (ast_chain || this.property === "length" || compressor.option("unsafe"))
|
|
396
|
+
&& this.expression._eval(compressor, depth + 1, ast_chain);
|
|
397
|
+
|
|
398
|
+
if (ast_chain) {
|
|
399
|
+
if (obj === nullish || (this.optional && obj == null)) return nullish;
|
|
400
|
+
}
|
|
388
401
|
|
|
389
402
|
// `.length` of strings and arrays is always safe
|
|
390
403
|
if (this.property === "length") {
|
|
@@ -455,26 +468,19 @@ def_eval(AST_PropAccess, function (compressor, depth) {
|
|
|
455
468
|
return this;
|
|
456
469
|
});
|
|
457
470
|
|
|
458
|
-
def_eval(
|
|
459
|
-
const evaluated = this.expression._eval(compressor, depth);
|
|
460
|
-
return evaluated === nullish
|
|
461
|
-
? undefined
|
|
462
|
-
: evaluated === this.expression
|
|
463
|
-
? this
|
|
464
|
-
: evaluated;
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
def_eval(AST_Call, function (compressor, depth) {
|
|
471
|
+
def_eval(AST_Call, function (compressor, depth, ast_chain) {
|
|
468
472
|
var exp = this.expression;
|
|
469
473
|
|
|
470
|
-
|
|
471
|
-
|
|
474
|
+
if (ast_chain) {
|
|
475
|
+
const callee = exp._eval(compressor, depth, ast_chain);
|
|
476
|
+
if (callee === nullish || (this.optional && callee == null)) return nullish;
|
|
477
|
+
}
|
|
472
478
|
|
|
473
479
|
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
|
474
480
|
var key = exp.property;
|
|
475
481
|
if (key instanceof AST_Node) {
|
|
476
482
|
key = key._eval(compressor, depth);
|
|
477
|
-
if (key
|
|
483
|
+
if (typeof key !== "string" && typeof key !== "number")
|
|
478
484
|
return this;
|
|
479
485
|
}
|
|
480
486
|
var val;
|
|
@@ -492,7 +498,8 @@ def_eval(AST_Call, function (compressor, depth) {
|
|
|
492
498
|
if (!is_pure_native_fn(e.name, key)) return this;
|
|
493
499
|
val = global_objs[e.name];
|
|
494
500
|
} else {
|
|
495
|
-
val = e._eval(compressor, depth + 1);
|
|
501
|
+
val = e._eval(compressor, depth + 1, /* don't pass ast_chain (exponential work) */);
|
|
502
|
+
|
|
496
503
|
if (val === e || !val)
|
|
497
504
|
return this;
|
|
498
505
|
if (!is_pure_native_method(val.constructor.name, key))
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AST_Export,
|
|
3
|
+
AST_Import,
|
|
4
|
+
AST_Toplevel,
|
|
5
|
+
} from "../ast.js";
|
|
6
|
+
|
|
7
|
+
AST_Toplevel.DEFMETHOD("optimize_import_export", function(compressor) {
|
|
8
|
+
if (!compressor.option("import_export")) return;
|
|
9
|
+
|
|
10
|
+
// We will compare `stat` against `prev` to see if it's a compatible import/export
|
|
11
|
+
// When compatible, merge!
|
|
12
|
+
let stat_i = 1;
|
|
13
|
+
|
|
14
|
+
while (stat_i < this.body.length) {
|
|
15
|
+
const stat = this.body[stat_i];
|
|
16
|
+
const prev = this.body[stat_i - 1];
|
|
17
|
+
|
|
18
|
+
const merged_import =
|
|
19
|
+
(stat instanceof AST_Import && prev instanceof AST_Import)
|
|
20
|
+
&& merge_imports(prev, stat);
|
|
21
|
+
const merged_export =
|
|
22
|
+
(stat instanceof AST_Export && prev instanceof AST_Export)
|
|
23
|
+
&& merge_exports(prev, stat);
|
|
24
|
+
|
|
25
|
+
if (merged_import || merged_export) {
|
|
26
|
+
this.body.splice(stat_i, 1);
|
|
27
|
+
// Don't stat_i++. We can stay here.
|
|
28
|
+
} else {
|
|
29
|
+
stat_i++;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/** Merge a compatible import statement. Or return false */
|
|
35
|
+
function merge_imports(into, merge_from) {
|
|
36
|
+
if (
|
|
37
|
+
// same "from"
|
|
38
|
+
into.module_name.value === merge_from.module_name.value
|
|
39
|
+
// only one can have a default import
|
|
40
|
+
&& !(into.imported_name && merge_from.imported_name)
|
|
41
|
+
// "*" not supported
|
|
42
|
+
&& can_merge_name_mappings(into.imported_names, merge_from.imported_names)
|
|
43
|
+
// "with" not supported
|
|
44
|
+
&& !into.attributes && !merge_from.attributes
|
|
45
|
+
) {
|
|
46
|
+
into.imported_name = into.imported_name || merge_from.imported_name;
|
|
47
|
+
into.imported_names = merge_name_mappings(into.imported_names, merge_from.imported_names);
|
|
48
|
+
|
|
49
|
+
return true; // `merge_from` can be safely removed
|
|
50
|
+
} else {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Merge a compatible export statement. Or return false */
|
|
56
|
+
function merge_exports(into, merge_from) {
|
|
57
|
+
if (
|
|
58
|
+
// "export function" not supported
|
|
59
|
+
!into.exported_value && !merge_from.exported_value
|
|
60
|
+
// "export from" not supported
|
|
61
|
+
&& !into.module_name && !merge_from.module_name
|
|
62
|
+
// "export default" not supported
|
|
63
|
+
&& !into.is_default && !merge_from.is_default
|
|
64
|
+
// "with" not supported
|
|
65
|
+
&& !into.attributes && !merge_from.attributes
|
|
66
|
+
) {
|
|
67
|
+
if (
|
|
68
|
+
// "export { a, b, c }"
|
|
69
|
+
into.exported_names && merge_from.exported_names
|
|
70
|
+
&& can_merge_name_mappings(into.exported_names, merge_from.exported_names)
|
|
71
|
+
) {
|
|
72
|
+
into.exported_names = merge_name_mappings(into.exported_names, merge_from.exported_names);
|
|
73
|
+
|
|
74
|
+
return true;
|
|
75
|
+
} else if (
|
|
76
|
+
// "export var xx"
|
|
77
|
+
into.exported_definition && merge_from.exported_definition
|
|
78
|
+
&& can_merge_definitions(into.exported_definition, merge_from.exported_definition)
|
|
79
|
+
) {
|
|
80
|
+
merge_definitions(into.exported_definition, merge_from.exported_definition);
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
} else {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Make sure a and b are optional AST_NameMapping*? arrays without the same names */
|
|
92
|
+
function can_merge_name_mappings(a, b) {
|
|
93
|
+
for (const mapping_array of [a, b]) {
|
|
94
|
+
for (const mapping of (mapping_array || [])) {
|
|
95
|
+
if (mapping.name.name === "*") return false;
|
|
96
|
+
if (mapping.foreign_name.name === "*") return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function merge_name_mappings(our_names, their_names) {
|
|
104
|
+
const arr_our_names = our_names || [];
|
|
105
|
+
const arr_their_names = their_names || [];
|
|
106
|
+
|
|
107
|
+
if (arr_our_names.length + arr_their_names.length > 0) {
|
|
108
|
+
return arr_our_names.concat(arr_their_names);
|
|
109
|
+
} else {
|
|
110
|
+
return our_names;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function can_merge_definitions(our_defs, their_defs) {
|
|
115
|
+
return our_defs.TYPE === their_defs.TYPE;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Merge two AST_Definitions */
|
|
119
|
+
function merge_definitions(our_defs, their_defs) {
|
|
120
|
+
our_defs.definitions.push(...their_defs.definitions);
|
|
121
|
+
}
|
|
@@ -958,10 +958,13 @@ var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date e
|
|
|
958
958
|
AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
|
|
959
959
|
if (compressor.option("unsafe")) {
|
|
960
960
|
var expr = this.expression;
|
|
961
|
-
var first_arg
|
|
961
|
+
var first_arg;
|
|
962
962
|
if (
|
|
963
963
|
expr.expression && expr.expression.name === "hasOwnProperty" &&
|
|
964
|
-
(
|
|
964
|
+
(
|
|
965
|
+
(first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor))) == null
|
|
966
|
+
|| first_arg.thedef && first_arg.thedef.undeclared
|
|
967
|
+
)
|
|
965
968
|
) {
|
|
966
969
|
return false;
|
|
967
970
|
}
|
package/lib/equivalent-to.js
CHANGED
|
@@ -211,7 +211,10 @@ AST_PropAccess.prototype.shallow_cmp = pass_through;
|
|
|
211
211
|
AST_Chain.prototype.shallow_cmp = pass_through;
|
|
212
212
|
|
|
213
213
|
AST_Dot.prototype.shallow_cmp = function(other) {
|
|
214
|
-
return
|
|
214
|
+
return (
|
|
215
|
+
this.property === other.property
|
|
216
|
+
&& !!this.quote === !!other.quote
|
|
217
|
+
);
|
|
215
218
|
};
|
|
216
219
|
|
|
217
220
|
AST_DotHash.prototype.shallow_cmp = function(other) {
|
package/lib/output.js
CHANGED
|
@@ -1043,21 +1043,21 @@ function OutputStream(options) {
|
|
|
1043
1043
|
|
|
1044
1044
|
PARENS(AST_Sequence, function(output) {
|
|
1045
1045
|
var p = output.parent();
|
|
1046
|
-
return p instanceof AST_Call
|
|
1047
|
-
|| p instanceof AST_Unary
|
|
1048
|
-
|| p instanceof AST_Binary
|
|
1049
|
-
|| p instanceof AST_VarDefLike
|
|
1050
|
-
|| p instanceof AST_PropAccess
|
|
1051
|
-
|| p instanceof AST_Array
|
|
1052
|
-
|| p instanceof AST_ObjectProperty
|
|
1053
|
-
|| p instanceof AST_Conditional
|
|
1054
|
-
|
|
1055
|
-
|| p instanceof AST_Arrow
|
|
1056
|
-
|| p instanceof AST_DefaultAssign
|
|
1057
|
-
|| p instanceof AST_Expansion
|
|
1058
|
-
|| p instanceof AST_ForOf && this === p.object
|
|
1059
|
-
|| p instanceof AST_Yield
|
|
1060
|
-
|| p instanceof AST_Export
|
|
1046
|
+
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
|
1047
|
+
|| p instanceof AST_Unary // !(foo, bar, baz)
|
|
1048
|
+
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
|
1049
|
+
|| p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4
|
|
1050
|
+
|| p instanceof AST_PropAccess && this !== p.property // (1, {foo:2}).foo, (1, {foo:2})["foo"], not foo[1, 2]
|
|
1051
|
+
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
|
1052
|
+
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
|
1053
|
+
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
|
1054
|
+
* ==> 20 (side effect, set a := 10 and b := 20) */
|
|
1055
|
+
|| p instanceof AST_Arrow // x => (x, x)
|
|
1056
|
+
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
|
1057
|
+
|| p instanceof AST_Expansion // [...(a, b)]
|
|
1058
|
+
|| p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
|
|
1059
|
+
|| p instanceof AST_Yield // yield (foo, bar)
|
|
1060
|
+
|| p instanceof AST_Export // export default (foo, bar)
|
|
1061
1061
|
;
|
|
1062
1062
|
});
|
|
1063
1063
|
|
package/lib/parse.js
CHANGED
|
@@ -101,6 +101,7 @@ import {
|
|
|
101
101
|
AST_If,
|
|
102
102
|
AST_Import,
|
|
103
103
|
AST_ImportMeta,
|
|
104
|
+
AST_Infinity,
|
|
104
105
|
AST_IterationStatement,
|
|
105
106
|
AST_Label,
|
|
106
107
|
AST_LabeledStatement,
|
|
@@ -2313,12 +2314,20 @@ function parse($TEXT, options) {
|
|
|
2313
2314
|
ret = _make_symbol(AST_SymbolRef);
|
|
2314
2315
|
break;
|
|
2315
2316
|
case "num":
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2317
|
+
if (tok.value === Infinity) {
|
|
2318
|
+
// very large float values are parsed as Infinity
|
|
2319
|
+
ret = new AST_Infinity({
|
|
2320
|
+
start: tok,
|
|
2321
|
+
end: tok,
|
|
2322
|
+
});
|
|
2323
|
+
} else {
|
|
2324
|
+
ret = new AST_Number({
|
|
2325
|
+
start: tok,
|
|
2326
|
+
end: tok,
|
|
2327
|
+
value: tok.value,
|
|
2328
|
+
raw: LATEST_RAW
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2322
2331
|
break;
|
|
2323
2332
|
case "big_int":
|
|
2324
2333
|
ret = new AST_BigInt({
|
package/package.json
CHANGED