terser 5.15.0 → 5.16.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 +13 -0
- package/PATRONS.md +1 -1
- package/README.md +2 -2
- package/dist/bundle.min.js +137 -26
- package/lib/ast.js +39 -0
- package/lib/compress/common.js +3 -2
- package/lib/compress/index.js +2 -11
- package/lib/compress/inline.js +1 -1
- package/lib/compress/tighten-body.js +2 -3
- package/lib/mozilla-ast.js +26 -1
- package/lib/output.js +17 -2
- package/lib/parse.js +43 -6
- package/lib/propmangle.js +2 -0
- package/lib/size.js +5 -0
- package/lib/transform.js +6 -0
- package/lib/utils/first_in_statement.js +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.16.1
|
4
|
+
|
5
|
+
- Disallow private fields in object bodies (#1011)
|
6
|
+
- Parse `#privatefield in object` (#1279)
|
7
|
+
- Compress `#privatefield in object`
|
8
|
+
|
9
|
+
## v5.15.1
|
10
|
+
|
11
|
+
- Fixed missing parentheses around optional chains
|
12
|
+
- Avoid bare `let` or `const` as the bodies of `if` statements (#1253)
|
13
|
+
- Small internal fixes (#1271)
|
14
|
+
- Avoid inlining a class twice and creating two equivalent but `!==` classes.
|
15
|
+
|
3
16
|
## v5.15.0
|
4
17
|
- Basic support for ES2022 class static initializer blocks.
|
5
18
|
- Add `AudioWorkletNode` constructor options to domprops list (#1230)
|
package/PATRONS.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Our patrons
|
2
2
|
|
3
|
-
These are the first-tier patrons from
|
3
|
+
These are the first-tier patrons from Patreon (notice: **The Terser Patreon is shutting down in favor of opencollective**). My appreciation goes to everyone on this list for supporting the project!
|
4
4
|
|
5
5
|
* 38elements
|
6
6
|
* Alan Orozco
|
package/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
A JavaScript mangler/compressor toolkit for ES6+.
|
9
9
|
|
10
|
-
*note*: You can support this project on patreon:
|
10
|
+
*note*: <s>You can support this project on patreon: [link]</s> **The Terser Patreon is shutting down in favor of opencollective**. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons.
|
11
11
|
|
12
12
|
Terser recommends you use RollupJS to bundle your modules, as that produces smaller code overall.
|
13
13
|
|
@@ -1336,7 +1336,7 @@ If you're not sure how to set an environment variable on your shell (the above e
|
|
1336
1336
|
|
1337
1337
|
# README.md Patrons:
|
1338
1338
|
|
1339
|
-
*note*: You can support this project on patreon:
|
1339
|
+
*note*: <s>You can support this project on patreon: [link]</s> **The Terser Patreon is shutting down in favor of opencollective**. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons.
|
1340
1340
|
|
1341
1341
|
These are the second-tier patrons. Great thanks for your support!
|
1342
1342
|
|
package/dist/bundle.min.js
CHANGED
@@ -1209,7 +1209,7 @@ var PRECEDENCE = (function(a, ret) {
|
|
1209
1209
|
{}
|
1210
1210
|
);
|
1211
1211
|
|
1212
|
-
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"
|
1212
|
+
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]);
|
1213
1213
|
|
1214
1214
|
/* -----[ Parser ]----- */
|
1215
1215
|
|
@@ -1381,6 +1381,10 @@ function parse($TEXT, options) {
|
|
1381
1381
|
return simple_statement();
|
1382
1382
|
|
1383
1383
|
case "name":
|
1384
|
+
case "privatename":
|
1385
|
+
if(is("privatename") && !S.in_class)
|
1386
|
+
croak("Private field must be used in an enclosing class");
|
1387
|
+
|
1384
1388
|
if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
|
1385
1389
|
next();
|
1386
1390
|
next();
|
@@ -2525,6 +2529,29 @@ function parse($TEXT, options) {
|
|
2525
2529
|
if (is("template_head")) {
|
2526
2530
|
return subscripts(template_string(), allow_calls);
|
2527
2531
|
}
|
2532
|
+
if (is("privatename")) {
|
2533
|
+
if(!S.in_class) {
|
2534
|
+
croak("Private field must be used in an enclosing class");
|
2535
|
+
}
|
2536
|
+
|
2537
|
+
const start = S.token;
|
2538
|
+
const key = new AST_SymbolPrivateProperty({
|
2539
|
+
start,
|
2540
|
+
name: start.value,
|
2541
|
+
end: start
|
2542
|
+
});
|
2543
|
+
next();
|
2544
|
+
expect_token("operator", "in");
|
2545
|
+
|
2546
|
+
const private_in = new AST_PrivateIn({
|
2547
|
+
start,
|
2548
|
+
key,
|
2549
|
+
value: subscripts(as_atom_node(), allow_calls),
|
2550
|
+
end: prev()
|
2551
|
+
});
|
2552
|
+
|
2553
|
+
return subscripts(private_in, allow_calls);
|
2554
|
+
}
|
2528
2555
|
if (ATOMIC_START_TOKEN.has(S.token.type)) {
|
2529
2556
|
return subscripts(as_atom_node(), allow_calls);
|
2530
2557
|
}
|
@@ -2610,7 +2637,9 @@ function parse($TEXT, options) {
|
|
2610
2637
|
}));
|
2611
2638
|
continue;
|
2612
2639
|
}
|
2613
|
-
|
2640
|
+
if(is("privatename")) {
|
2641
|
+
croak("private fields are not allowed in an object");
|
2642
|
+
}
|
2614
2643
|
var name = as_property_name();
|
2615
2644
|
var value;
|
2616
2645
|
|
@@ -2684,7 +2713,8 @@ function parse($TEXT, options) {
|
|
2684
2713
|
}
|
2685
2714
|
|
2686
2715
|
expect("{");
|
2687
|
-
|
2716
|
+
// mark in class feild,
|
2717
|
+
S.in_class = true;
|
2688
2718
|
while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
|
2689
2719
|
while (!is("punc", "}")) {
|
2690
2720
|
start = S.token;
|
@@ -2693,6 +2723,8 @@ function parse($TEXT, options) {
|
|
2693
2723
|
a.push(method);
|
2694
2724
|
while (is("punc", ";")) { next(); }
|
2695
2725
|
}
|
2726
|
+
// mark in class feild,
|
2727
|
+
S.in_class = false;
|
2696
2728
|
|
2697
2729
|
S.input.pop_directives_stack();
|
2698
2730
|
|
@@ -2969,14 +3001,14 @@ function parse($TEXT, options) {
|
|
2969
3001
|
var end = prev();
|
2970
3002
|
|
2971
3003
|
name = name || new type({
|
2972
|
-
name: "*",
|
2973
3004
|
start: start,
|
3005
|
+
name: "*",
|
2974
3006
|
end: end,
|
2975
3007
|
});
|
2976
3008
|
|
2977
3009
|
foreign_name = new foreign_type({
|
2978
|
-
name: "*",
|
2979
3010
|
start: start,
|
3011
|
+
name: "*",
|
2980
3012
|
end: end,
|
2981
3013
|
});
|
2982
3014
|
|
@@ -3199,6 +3231,8 @@ function parse($TEXT, options) {
|
|
3199
3231
|
var start = expr.start;
|
3200
3232
|
if (is("punc", ".")) {
|
3201
3233
|
next();
|
3234
|
+
if(is("privatename") && !S.in_class)
|
3235
|
+
croak("Private field must be used in an enclosing class");
|
3202
3236
|
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
3203
3237
|
return subscripts(new AST_DotVariant({
|
3204
3238
|
start : start,
|
@@ -3252,6 +3286,8 @@ function parse($TEXT, options) {
|
|
3252
3286
|
|
3253
3287
|
chain_contents = subscripts(call, true, true);
|
3254
3288
|
} else if (is("name") || is("privatename")) {
|
3289
|
+
if(is("privatename") && !S.in_class)
|
3290
|
+
croak("Private field must be used in an enclosing class");
|
3255
3291
|
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
3256
3292
|
chain_contents = subscripts(new AST_DotVariant({
|
3257
3293
|
start,
|
@@ -3297,7 +3333,6 @@ function parse($TEXT, options) {
|
|
3297
3333
|
end: prev()
|
3298
3334
|
}), allow_calls);
|
3299
3335
|
}
|
3300
|
-
|
3301
3336
|
return expr;
|
3302
3337
|
};
|
3303
3338
|
|
@@ -5785,6 +5820,29 @@ var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_
|
|
5785
5820
|
$documentation: "A class property for a private property",
|
5786
5821
|
}, AST_ClassProperty);
|
5787
5822
|
|
5823
|
+
var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) {
|
5824
|
+
if (props) {
|
5825
|
+
this.key = props.key;
|
5826
|
+
this.value = props.value;
|
5827
|
+
this.start = props.start;
|
5828
|
+
this.end = props.end;
|
5829
|
+
}
|
5830
|
+
|
5831
|
+
this.flags = 0;
|
5832
|
+
}, {
|
5833
|
+
$documentation: "An `in` binop when the key is private, eg #x in this",
|
5834
|
+
_walk: function(visitor) {
|
5835
|
+
return visitor._visit(this, function() {
|
5836
|
+
this.key._walk(visitor);
|
5837
|
+
this.value._walk(visitor);
|
5838
|
+
});
|
5839
|
+
},
|
5840
|
+
_children_backwards(push) {
|
5841
|
+
push(this.value);
|
5842
|
+
push(this.key);
|
5843
|
+
},
|
5844
|
+
});
|
5845
|
+
|
5788
5846
|
var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
|
5789
5847
|
if (props) {
|
5790
5848
|
this.name = props.name;
|
@@ -6188,6 +6246,20 @@ var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) {
|
|
6188
6246
|
$documentation: "Reference to a label symbol",
|
6189
6247
|
}, AST_Symbol);
|
6190
6248
|
|
6249
|
+
var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) {
|
6250
|
+
if (props) {
|
6251
|
+
this.scope = props.scope;
|
6252
|
+
this.name = props.name;
|
6253
|
+
this.thedef = props.thedef;
|
6254
|
+
this.start = props.start;
|
6255
|
+
this.end = props.end;
|
6256
|
+
}
|
6257
|
+
|
6258
|
+
this.flags = 0;
|
6259
|
+
}, {
|
6260
|
+
$documentation: "A symbol that refers to a private property",
|
6261
|
+
}, AST_Symbol);
|
6262
|
+
|
6191
6263
|
var AST_This = DEFNODE("This", null, function AST_This(props) {
|
6192
6264
|
if (props) {
|
6193
6265
|
this.scope = props.scope;
|
@@ -6818,6 +6890,11 @@ def_transform(AST_Binary, function(self, tw) {
|
|
6818
6890
|
self.right = self.right.transform(tw);
|
6819
6891
|
});
|
6820
6892
|
|
6893
|
+
def_transform(AST_PrivateIn, function(self, tw) {
|
6894
|
+
self.key = self.key.transform(tw);
|
6895
|
+
self.value = self.value.transform(tw);
|
6896
|
+
});
|
6897
|
+
|
6821
6898
|
def_transform(AST_Conditional, function(self, tw) {
|
6822
6899
|
self.condition = self.condition.transform(tw);
|
6823
6900
|
self.consequent = self.consequent.transform(tw);
|
@@ -7195,7 +7272,9 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7195
7272
|
if (M.computed) {
|
7196
7273
|
key = from_moz(M.key);
|
7197
7274
|
} else {
|
7198
|
-
if (M.key.type !== "Identifier"
|
7275
|
+
if (M.key.type !== "Identifier" && M.key.type !== "PrivateIdentifier") {
|
7276
|
+
throw new Error("Non-Identifier key in PropertyDefinition");
|
7277
|
+
}
|
7199
7278
|
key = from_moz(M.key);
|
7200
7279
|
}
|
7201
7280
|
|
@@ -7630,6 +7709,18 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7630
7709
|
},
|
7631
7710
|
|
7632
7711
|
BinaryExpression: function(M) {
|
7712
|
+
if (M.left.type === "PrivateIdentifier") {
|
7713
|
+
return new AST_PrivateIn({
|
7714
|
+
start: my_start_token(M),
|
7715
|
+
end: my_end_token(M),
|
7716
|
+
key: new AST_SymbolPrivateProperty({
|
7717
|
+
start: my_start_token(M.left),
|
7718
|
+
end: my_end_token(M.left),
|
7719
|
+
name: M.left.name
|
7720
|
+
}),
|
7721
|
+
value: from_moz(M.right),
|
7722
|
+
});
|
7723
|
+
}
|
7633
7724
|
return new AST_Binary({
|
7634
7725
|
start: my_start_token(M),
|
7635
7726
|
end: my_end_token(M),
|
@@ -8214,6 +8305,15 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
8214
8305
|
};
|
8215
8306
|
});
|
8216
8307
|
|
8308
|
+
def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) {
|
8309
|
+
return {
|
8310
|
+
type: "BinaryExpression",
|
8311
|
+
left: { type: "PrivateIdentifier", name: M.key.name },
|
8312
|
+
operator: "in",
|
8313
|
+
right: to_moz(M.value),
|
8314
|
+
};
|
8315
|
+
});
|
8316
|
+
|
8217
8317
|
def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
|
8218
8318
|
return {
|
8219
8319
|
type: "ArrayExpression",
|
@@ -8560,6 +8660,7 @@ function first_in_statement(stack) {
|
|
8560
8660
|
(p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
|
8561
8661
|
(p instanceof AST_Dot && p.expression === node) ||
|
8562
8662
|
(p instanceof AST_Sub && p.expression === node) ||
|
8663
|
+
(p instanceof AST_Chain && p.expression === node) ||
|
8563
8664
|
(p instanceof AST_Conditional && p.condition === node) ||
|
8564
8665
|
(p instanceof AST_Binary && p.left === node) ||
|
8565
8666
|
(p instanceof AST_UnaryPostfix && p.expression === node)
|
@@ -8578,6 +8679,7 @@ function left_is_object(node) {
|
|
8578
8679
|
if (node.TYPE === "Call") return left_is_object(node.expression);
|
8579
8680
|
if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
|
8580
8681
|
if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
|
8682
|
+
if (node instanceof AST_Chain) return left_is_object(node.expression);
|
8581
8683
|
if (node instanceof AST_Conditional) return left_is_object(node.condition);
|
8582
8684
|
if (node instanceof AST_Binary) return left_is_object(node.left);
|
8583
8685
|
if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
|
@@ -8719,7 +8821,7 @@ function OutputStream(options) {
|
|
8719
8821
|
if (options.shorthand === undefined)
|
8720
8822
|
options.shorthand = options.ecma > 5;
|
8721
8823
|
|
8722
|
-
// Convert comment option to RegExp if
|
8824
|
+
// Convert comment option to RegExp if necessary and set up comments filter
|
8723
8825
|
var comment_filter = return_false; // Default case, throw all comments away
|
8724
8826
|
if (options.comments) {
|
8725
8827
|
let comments = options.comments;
|
@@ -10259,7 +10361,10 @@ function OutputStream(options) {
|
|
10259
10361
|
if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
|
10260
10362
|
return true;
|
10261
10363
|
}
|
10262
|
-
if (
|
10364
|
+
if (
|
10365
|
+
node instanceof AST_Binary && node.operator == "in"
|
10366
|
+
|| node instanceof AST_PrivateIn
|
10367
|
+
) {
|
10263
10368
|
return walk_abort; // makes walk() return true
|
10264
10369
|
}
|
10265
10370
|
});
|
@@ -10648,6 +10753,16 @@ function OutputStream(options) {
|
|
10648
10753
|
}
|
10649
10754
|
self._print_getter_setter(type, true, output);
|
10650
10755
|
});
|
10756
|
+
DEFPRINT(AST_PrivateIn, function(self, output) {
|
10757
|
+
self.key.print(output);
|
10758
|
+
output.space();
|
10759
|
+
output.print("in");
|
10760
|
+
output.space();
|
10761
|
+
self.value.print(output);
|
10762
|
+
});
|
10763
|
+
DEFPRINT(AST_SymbolPrivateProperty, function(self, output) {
|
10764
|
+
output.print("#" + self.name);
|
10765
|
+
});
|
10651
10766
|
DEFPRINT(AST_ConciseMethod, function(self, output) {
|
10652
10767
|
var type;
|
10653
10768
|
if (self.is_generator && self.async) {
|
@@ -12330,6 +12445,10 @@ AST_PrivateGetter.prototype._size = AST_PrivateSetter.prototype._size = function
|
|
12330
12445
|
return AST_ConciseMethod.prototype._size.call(this) + 4;
|
12331
12446
|
};
|
12332
12447
|
|
12448
|
+
AST_PrivateIn.prototype._size = function () {
|
12449
|
+
return 5; // "#", and " in "
|
12450
|
+
};
|
12451
|
+
|
12333
12452
|
AST_Class.prototype._size = function () {
|
12334
12453
|
return (
|
12335
12454
|
(this.name ? 8 : 7)
|
@@ -12718,8 +12837,9 @@ function is_ref_of(ref, type) {
|
|
12718
12837
|
}
|
12719
12838
|
}
|
12720
12839
|
|
12721
|
-
|
12722
|
-
|
12840
|
+
/**Can we turn { block contents... } into just the block contents ?
|
12841
|
+
* Not if one of these is inside.
|
12842
|
+
**/
|
12723
12843
|
function can_be_evicted_from_block(node) {
|
12724
12844
|
return !(
|
12725
12845
|
node instanceof AST_DefClass ||
|
@@ -16306,8 +16426,7 @@ function tighten_body(statements, compressor) {
|
|
16306
16426
|
}
|
16307
16427
|
|
16308
16428
|
function declarations_only(node) {
|
16309
|
-
return node.definitions.every((var_def) => !var_def.value
|
16310
|
-
);
|
16429
|
+
return node.definitions.every((var_def) => !var_def.value);
|
16311
16430
|
}
|
16312
16431
|
|
16313
16432
|
function sequencesize(statements, compressor) {
|
@@ -16353,7 +16472,7 @@ function tighten_body(statements, compressor) {
|
|
16353
16472
|
var line = block.body[i];
|
16354
16473
|
if (line instanceof AST_Var && declarations_only(line)) {
|
16355
16474
|
decls.push(line);
|
16356
|
-
} else if (stat) {
|
16475
|
+
} else if (stat || line instanceof AST_Const || line instanceof AST_Let) {
|
16357
16476
|
return false;
|
16358
16477
|
} else {
|
16359
16478
|
stat = line;
|
@@ -16713,7 +16832,7 @@ function inline_into_symbolref(self, compressor) {
|
|
16713
16832
|
}
|
16714
16833
|
}
|
16715
16834
|
|
16716
|
-
if (single_use && fixed instanceof AST_Lambda) {
|
16835
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
16717
16836
|
single_use =
|
16718
16837
|
def.scope === self.scope
|
16719
16838
|
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
@@ -18929,16 +19048,6 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
18929
19048
|
right : def.value
|
18930
19049
|
}));
|
18931
19050
|
if (reduce_vars) name.definition().fixed = false;
|
18932
|
-
} else if (def.value) {
|
18933
|
-
// Because it's a destructuring, do not turn into an assignment.
|
18934
|
-
var varDef = make_node(AST_VarDef, def, {
|
18935
|
-
name: def.name,
|
18936
|
-
value: def.value
|
18937
|
-
});
|
18938
|
-
var var_ = make_node(AST_Var, def, {
|
18939
|
-
definitions: [ varDef ]
|
18940
|
-
});
|
18941
|
-
assignments.push(var_);
|
18942
19051
|
}
|
18943
19052
|
const thedef = def.name.definition();
|
18944
19053
|
thedef.eliminated++;
|
@@ -18950,8 +19059,9 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
18950
19059
|
});
|
18951
19060
|
|
18952
19061
|
def_optimize(AST_Definitions, function(self) {
|
18953
|
-
if (self.definitions.length == 0)
|
19062
|
+
if (self.definitions.length == 0) {
|
18954
19063
|
return make_node(AST_EmptyStatement, self);
|
19064
|
+
}
|
18955
19065
|
return self;
|
18956
19066
|
});
|
18957
19067
|
|
@@ -29166,6 +29276,7 @@ function mangle_private_properties(ast, options) {
|
|
29166
29276
|
|| node instanceof AST_PrivateMethod
|
29167
29277
|
|| node instanceof AST_PrivateGetter
|
29168
29278
|
|| node instanceof AST_PrivateSetter
|
29279
|
+
|| node instanceof AST_PrivateIn
|
29169
29280
|
) {
|
29170
29281
|
node.key.name = mangle_private(node.key.name);
|
29171
29282
|
} else if (node instanceof AST_DotHash) {
|
package/lib/ast.js
CHANGED
@@ -2250,6 +2250,29 @@ var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_
|
|
2250
2250
|
$documentation: "A class property for a private property",
|
2251
2251
|
}, AST_ClassProperty);
|
2252
2252
|
|
2253
|
+
var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) {
|
2254
|
+
if (props) {
|
2255
|
+
this.key = props.key;
|
2256
|
+
this.value = props.value;
|
2257
|
+
this.start = props.start;
|
2258
|
+
this.end = props.end;
|
2259
|
+
}
|
2260
|
+
|
2261
|
+
this.flags = 0;
|
2262
|
+
}, {
|
2263
|
+
$documentation: "An `in` binop when the key is private, eg #x in this",
|
2264
|
+
_walk: function(visitor) {
|
2265
|
+
return visitor._visit(this, function() {
|
2266
|
+
this.key._walk(visitor);
|
2267
|
+
this.value._walk(visitor);
|
2268
|
+
});
|
2269
|
+
},
|
2270
|
+
_children_backwards(push) {
|
2271
|
+
push(this.value);
|
2272
|
+
push(this.key);
|
2273
|
+
},
|
2274
|
+
});
|
2275
|
+
|
2253
2276
|
var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
|
2254
2277
|
if (props) {
|
2255
2278
|
this.name = props.name;
|
@@ -2653,6 +2676,20 @@ var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) {
|
|
2653
2676
|
$documentation: "Reference to a label symbol",
|
2654
2677
|
}, AST_Symbol);
|
2655
2678
|
|
2679
|
+
var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) {
|
2680
|
+
if (props) {
|
2681
|
+
this.scope = props.scope;
|
2682
|
+
this.name = props.name;
|
2683
|
+
this.thedef = props.thedef;
|
2684
|
+
this.start = props.start;
|
2685
|
+
this.end = props.end;
|
2686
|
+
}
|
2687
|
+
|
2688
|
+
this.flags = 0;
|
2689
|
+
}, {
|
2690
|
+
$documentation: "A symbol that refers to a private property",
|
2691
|
+
}, AST_Symbol);
|
2692
|
+
|
2656
2693
|
var AST_This = DEFNODE("This", null, function AST_This(props) {
|
2657
2694
|
if (props) {
|
2658
2695
|
this.scope = props.scope;
|
@@ -3093,6 +3130,7 @@ export {
|
|
3093
3130
|
AST_Class,
|
3094
3131
|
AST_ClassExpression,
|
3095
3132
|
AST_ClassPrivateProperty,
|
3133
|
+
AST_PrivateIn,
|
3096
3134
|
AST_ClassProperty,
|
3097
3135
|
AST_ClassStaticBlock,
|
3098
3136
|
AST_ConciseMethod,
|
@@ -3185,6 +3223,7 @@ export {
|
|
3185
3223
|
AST_SymbolVar,
|
3186
3224
|
AST_TemplateSegment,
|
3187
3225
|
AST_TemplateString,
|
3226
|
+
AST_SymbolPrivateProperty,
|
3188
3227
|
AST_This,
|
3189
3228
|
AST_Throw,
|
3190
3229
|
AST_Token,
|
package/lib/compress/common.js
CHANGED
@@ -271,8 +271,9 @@ export function is_ref_of(ref, type) {
|
|
271
271
|
}
|
272
272
|
}
|
273
273
|
|
274
|
-
|
275
|
-
|
274
|
+
/**Can we turn { block contents... } into just the block contents ?
|
275
|
+
* Not if one of these is inside.
|
276
|
+
**/
|
276
277
|
export function can_be_evicted_from_block(node) {
|
277
278
|
return !(
|
278
279
|
node instanceof AST_DefClass ||
|
package/lib/compress/index.js
CHANGED
@@ -1965,16 +1965,6 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
1965
1965
|
right : def.value
|
1966
1966
|
}));
|
1967
1967
|
if (reduce_vars) name.definition().fixed = false;
|
1968
|
-
} else if (def.value) {
|
1969
|
-
// Because it's a destructuring, do not turn into an assignment.
|
1970
|
-
var varDef = make_node(AST_VarDef, def, {
|
1971
|
-
name: def.name,
|
1972
|
-
value: def.value
|
1973
|
-
});
|
1974
|
-
var var_ = make_node(AST_Var, def, {
|
1975
|
-
definitions: [ varDef ]
|
1976
|
-
});
|
1977
|
-
assignments.push(var_);
|
1978
1968
|
}
|
1979
1969
|
const thedef = def.name.definition();
|
1980
1970
|
thedef.eliminated++;
|
@@ -1986,8 +1976,9 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
1986
1976
|
});
|
1987
1977
|
|
1988
1978
|
def_optimize(AST_Definitions, function(self) {
|
1989
|
-
if (self.definitions.length == 0)
|
1979
|
+
if (self.definitions.length == 0) {
|
1990
1980
|
return make_node(AST_EmptyStatement, self);
|
1981
|
+
}
|
1991
1982
|
return self;
|
1992
1983
|
});
|
1993
1984
|
|
package/lib/compress/inline.js
CHANGED
@@ -210,7 +210,7 @@ export function inline_into_symbolref(self, compressor) {
|
|
210
210
|
}
|
211
211
|
}
|
212
212
|
|
213
|
-
if (single_use && fixed instanceof AST_Lambda) {
|
213
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
214
214
|
single_use =
|
215
215
|
def.scope === self.scope
|
216
216
|
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
@@ -1189,8 +1189,7 @@ export function tighten_body(statements, compressor) {
|
|
1189
1189
|
}
|
1190
1190
|
|
1191
1191
|
function declarations_only(node) {
|
1192
|
-
return node.definitions.every((var_def) => !var_def.value
|
1193
|
-
);
|
1192
|
+
return node.definitions.every((var_def) => !var_def.value);
|
1194
1193
|
}
|
1195
1194
|
|
1196
1195
|
function sequencesize(statements, compressor) {
|
@@ -1236,7 +1235,7 @@ export function tighten_body(statements, compressor) {
|
|
1236
1235
|
var line = block.body[i];
|
1237
1236
|
if (line instanceof AST_Var && declarations_only(line)) {
|
1238
1237
|
decls.push(line);
|
1239
|
-
} else if (stat) {
|
1238
|
+
} else if (stat || line instanceof AST_Const || line instanceof AST_Let) {
|
1240
1239
|
return false;
|
1241
1240
|
} else {
|
1242
1241
|
stat = line;
|
package/lib/mozilla-ast.js
CHANGED
@@ -113,6 +113,7 @@ import {
|
|
113
113
|
AST_PrivateGetter,
|
114
114
|
AST_PrivateMethod,
|
115
115
|
AST_PrivateSetter,
|
116
|
+
AST_PrivateIn,
|
116
117
|
AST_PropAccess,
|
117
118
|
AST_RegExp,
|
118
119
|
AST_Return,
|
@@ -128,6 +129,7 @@ import {
|
|
128
129
|
AST_SymbolCatch,
|
129
130
|
AST_SymbolClass,
|
130
131
|
AST_SymbolClassProperty,
|
132
|
+
AST_SymbolPrivateProperty,
|
131
133
|
AST_SymbolConst,
|
132
134
|
AST_SymbolDefClass,
|
133
135
|
AST_SymbolDefun,
|
@@ -432,7 +434,9 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
432
434
|
if (M.computed) {
|
433
435
|
key = from_moz(M.key);
|
434
436
|
} else {
|
435
|
-
if (M.key.type !== "Identifier"
|
437
|
+
if (M.key.type !== "Identifier" && M.key.type !== "PrivateIdentifier") {
|
438
|
+
throw new Error("Non-Identifier key in PropertyDefinition");
|
439
|
+
}
|
436
440
|
key = from_moz(M.key);
|
437
441
|
}
|
438
442
|
|
@@ -867,6 +871,18 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
867
871
|
},
|
868
872
|
|
869
873
|
BinaryExpression: function(M) {
|
874
|
+
if (M.left.type === "PrivateIdentifier") {
|
875
|
+
return new AST_PrivateIn({
|
876
|
+
start: my_start_token(M),
|
877
|
+
end: my_end_token(M),
|
878
|
+
key: new AST_SymbolPrivateProperty({
|
879
|
+
start: my_start_token(M.left),
|
880
|
+
end: my_end_token(M.left),
|
881
|
+
name: M.left.name
|
882
|
+
}),
|
883
|
+
value: from_moz(M.right),
|
884
|
+
});
|
885
|
+
}
|
870
886
|
return new AST_Binary({
|
871
887
|
start: my_start_token(M),
|
872
888
|
end: my_end_token(M),
|
@@ -1451,6 +1467,15 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
1451
1467
|
};
|
1452
1468
|
});
|
1453
1469
|
|
1470
|
+
def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) {
|
1471
|
+
return {
|
1472
|
+
type: "BinaryExpression",
|
1473
|
+
left: { type: "PrivateIdentifier", name: M.key.name },
|
1474
|
+
operator: "in",
|
1475
|
+
right: to_moz(M.value),
|
1476
|
+
};
|
1477
|
+
});
|
1478
|
+
|
1454
1479
|
def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
|
1455
1480
|
return {
|
1456
1481
|
type: "ArrayExpression",
|
package/lib/output.js
CHANGED
@@ -74,7 +74,9 @@ import {
|
|
74
74
|
AST_ConciseMethod,
|
75
75
|
AST_PrivateGetter,
|
76
76
|
AST_PrivateMethod,
|
77
|
+
AST_SymbolPrivateProperty,
|
77
78
|
AST_PrivateSetter,
|
79
|
+
AST_PrivateIn,
|
78
80
|
AST_Conditional,
|
79
81
|
AST_Const,
|
80
82
|
AST_Constant,
|
@@ -255,7 +257,7 @@ function OutputStream(options) {
|
|
255
257
|
if (options.shorthand === undefined)
|
256
258
|
options.shorthand = options.ecma > 5;
|
257
259
|
|
258
|
-
// Convert comment option to RegExp if
|
260
|
+
// Convert comment option to RegExp if necessary and set up comments filter
|
259
261
|
var comment_filter = return_false; // Default case, throw all comments away
|
260
262
|
if (options.comments) {
|
261
263
|
let comments = options.comments;
|
@@ -1795,7 +1797,10 @@ function OutputStream(options) {
|
|
1795
1797
|
if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
|
1796
1798
|
return true;
|
1797
1799
|
}
|
1798
|
-
if (
|
1800
|
+
if (
|
1801
|
+
node instanceof AST_Binary && node.operator == "in"
|
1802
|
+
|| node instanceof AST_PrivateIn
|
1803
|
+
) {
|
1799
1804
|
return walk_abort; // makes walk() return true
|
1800
1805
|
}
|
1801
1806
|
});
|
@@ -2184,6 +2189,16 @@ function OutputStream(options) {
|
|
2184
2189
|
}
|
2185
2190
|
self._print_getter_setter(type, true, output);
|
2186
2191
|
});
|
2192
|
+
DEFPRINT(AST_PrivateIn, function(self, output) {
|
2193
|
+
self.key.print(output);
|
2194
|
+
output.space();
|
2195
|
+
output.print("in");
|
2196
|
+
output.space();
|
2197
|
+
self.value.print(output);
|
2198
|
+
});
|
2199
|
+
DEFPRINT(AST_SymbolPrivateProperty, function(self, output) {
|
2200
|
+
output.print("#" + self.name);
|
2201
|
+
});
|
2187
2202
|
DEFPRINT(AST_ConciseMethod, function(self, output) {
|
2188
2203
|
var type;
|
2189
2204
|
if (self.is_generator && self.async) {
|
package/lib/parse.js
CHANGED
@@ -69,6 +69,7 @@ import {
|
|
69
69
|
AST_ClassProperty,
|
70
70
|
AST_ClassStaticBlock,
|
71
71
|
AST_ConciseMethod,
|
72
|
+
AST_PrivateIn,
|
72
73
|
AST_PrivateGetter,
|
73
74
|
AST_PrivateMethod,
|
74
75
|
AST_PrivateSetter,
|
@@ -145,6 +146,7 @@ import {
|
|
145
146
|
AST_TemplateSegment,
|
146
147
|
AST_TemplateString,
|
147
148
|
AST_This,
|
149
|
+
AST_SymbolPrivateProperty,
|
148
150
|
AST_Throw,
|
149
151
|
AST_Token,
|
150
152
|
AST_Toplevel,
|
@@ -1041,7 +1043,7 @@ var PRECEDENCE = (function(a, ret) {
|
|
1041
1043
|
{}
|
1042
1044
|
);
|
1043
1045
|
|
1044
|
-
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"
|
1046
|
+
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]);
|
1045
1047
|
|
1046
1048
|
/* -----[ Parser ]----- */
|
1047
1049
|
|
@@ -1213,6 +1215,10 @@ function parse($TEXT, options) {
|
|
1213
1215
|
return simple_statement();
|
1214
1216
|
|
1215
1217
|
case "name":
|
1218
|
+
case "privatename":
|
1219
|
+
if(is("privatename") && !S.in_class)
|
1220
|
+
croak("Private field must be used in an enclosing class");
|
1221
|
+
|
1216
1222
|
if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
|
1217
1223
|
next();
|
1218
1224
|
next();
|
@@ -2357,6 +2363,29 @@ function parse($TEXT, options) {
|
|
2357
2363
|
if (is("template_head")) {
|
2358
2364
|
return subscripts(template_string(), allow_calls);
|
2359
2365
|
}
|
2366
|
+
if (is("privatename")) {
|
2367
|
+
if(!S.in_class) {
|
2368
|
+
croak("Private field must be used in an enclosing class");
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
const start = S.token;
|
2372
|
+
const key = new AST_SymbolPrivateProperty({
|
2373
|
+
start,
|
2374
|
+
name: start.value,
|
2375
|
+
end: start
|
2376
|
+
});
|
2377
|
+
next();
|
2378
|
+
expect_token("operator", "in");
|
2379
|
+
|
2380
|
+
const private_in = new AST_PrivateIn({
|
2381
|
+
start,
|
2382
|
+
key,
|
2383
|
+
value: subscripts(as_atom_node(), allow_calls),
|
2384
|
+
end: prev()
|
2385
|
+
});
|
2386
|
+
|
2387
|
+
return subscripts(private_in, allow_calls);
|
2388
|
+
}
|
2360
2389
|
if (ATOMIC_START_TOKEN.has(S.token.type)) {
|
2361
2390
|
return subscripts(as_atom_node(), allow_calls);
|
2362
2391
|
}
|
@@ -2442,7 +2471,9 @@ function parse($TEXT, options) {
|
|
2442
2471
|
}));
|
2443
2472
|
continue;
|
2444
2473
|
}
|
2445
|
-
|
2474
|
+
if(is("privatename")) {
|
2475
|
+
croak("private fields are not allowed in an object");
|
2476
|
+
}
|
2446
2477
|
var name = as_property_name();
|
2447
2478
|
var value;
|
2448
2479
|
|
@@ -2516,7 +2547,8 @@ function parse($TEXT, options) {
|
|
2516
2547
|
}
|
2517
2548
|
|
2518
2549
|
expect("{");
|
2519
|
-
|
2550
|
+
// mark in class feild,
|
2551
|
+
S.in_class = true;
|
2520
2552
|
while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
|
2521
2553
|
while (!is("punc", "}")) {
|
2522
2554
|
start = S.token;
|
@@ -2525,6 +2557,8 @@ function parse($TEXT, options) {
|
|
2525
2557
|
a.push(method);
|
2526
2558
|
while (is("punc", ";")) { next(); }
|
2527
2559
|
}
|
2560
|
+
// mark in class feild,
|
2561
|
+
S.in_class = false;
|
2528
2562
|
|
2529
2563
|
S.input.pop_directives_stack();
|
2530
2564
|
|
@@ -2801,14 +2835,14 @@ function parse($TEXT, options) {
|
|
2801
2835
|
var end = prev();
|
2802
2836
|
|
2803
2837
|
name = name || new type({
|
2804
|
-
name: "*",
|
2805
2838
|
start: start,
|
2839
|
+
name: "*",
|
2806
2840
|
end: end,
|
2807
2841
|
});
|
2808
2842
|
|
2809
2843
|
foreign_name = new foreign_type({
|
2810
|
-
name: "*",
|
2811
2844
|
start: start,
|
2845
|
+
name: "*",
|
2812
2846
|
end: end,
|
2813
2847
|
});
|
2814
2848
|
|
@@ -3031,6 +3065,8 @@ function parse($TEXT, options) {
|
|
3031
3065
|
var start = expr.start;
|
3032
3066
|
if (is("punc", ".")) {
|
3033
3067
|
next();
|
3068
|
+
if(is("privatename") && !S.in_class)
|
3069
|
+
croak("Private field must be used in an enclosing class");
|
3034
3070
|
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
3035
3071
|
return subscripts(new AST_DotVariant({
|
3036
3072
|
start : start,
|
@@ -3084,6 +3120,8 @@ function parse($TEXT, options) {
|
|
3084
3120
|
|
3085
3121
|
chain_contents = subscripts(call, true, true);
|
3086
3122
|
} else if (is("name") || is("privatename")) {
|
3123
|
+
if(is("privatename") && !S.in_class)
|
3124
|
+
croak("Private field must be used in an enclosing class");
|
3087
3125
|
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
3088
3126
|
chain_contents = subscripts(new AST_DotVariant({
|
3089
3127
|
start,
|
@@ -3129,7 +3167,6 @@ function parse($TEXT, options) {
|
|
3129
3167
|
end: prev()
|
3130
3168
|
}), allow_calls);
|
3131
3169
|
}
|
3132
|
-
|
3133
3170
|
return expr;
|
3134
3171
|
};
|
3135
3172
|
|
package/lib/propmangle.js
CHANGED
@@ -61,6 +61,7 @@ import {
|
|
61
61
|
AST_PrivateMethod,
|
62
62
|
AST_PrivateGetter,
|
63
63
|
AST_PrivateSetter,
|
64
|
+
AST_PrivateIn,
|
64
65
|
AST_Sequence,
|
65
66
|
AST_String,
|
66
67
|
AST_Sub,
|
@@ -153,6 +154,7 @@ function mangle_private_properties(ast, options) {
|
|
153
154
|
|| node instanceof AST_PrivateMethod
|
154
155
|
|| node instanceof AST_PrivateGetter
|
155
156
|
|| node instanceof AST_PrivateSetter
|
157
|
+
|| node instanceof AST_PrivateIn
|
156
158
|
) {
|
157
159
|
node.key.name = mangle_private(node.key.name);
|
158
160
|
} else if (node instanceof AST_DotHash) {
|
package/lib/size.js
CHANGED
@@ -53,6 +53,7 @@ import {
|
|
53
53
|
AST_PrivateGetter,
|
54
54
|
AST_PrivateMethod,
|
55
55
|
AST_PrivateSetter,
|
56
|
+
AST_PrivateIn,
|
56
57
|
AST_RegExp,
|
57
58
|
AST_Return,
|
58
59
|
AST_Sequence,
|
@@ -395,6 +396,10 @@ AST_PrivateGetter.prototype._size = AST_PrivateSetter.prototype._size = function
|
|
395
396
|
return AST_ConciseMethod.prototype._size.call(this) + 4;
|
396
397
|
};
|
397
398
|
|
399
|
+
AST_PrivateIn.prototype._size = function () {
|
400
|
+
return 5; // "#", and " in "
|
401
|
+
};
|
402
|
+
|
398
403
|
AST_Class.prototype._size = function () {
|
399
404
|
return (
|
400
405
|
(this.name ? 8 : 7)
|
package/lib/transform.js
CHANGED
@@ -47,6 +47,7 @@ import {
|
|
47
47
|
AST_Array,
|
48
48
|
AST_Await,
|
49
49
|
AST_Binary,
|
50
|
+
AST_PrivateIn,
|
50
51
|
AST_Block,
|
51
52
|
AST_Call,
|
52
53
|
AST_Case,
|
@@ -259,6 +260,11 @@ def_transform(AST_Binary, function(self, tw) {
|
|
259
260
|
self.right = self.right.transform(tw);
|
260
261
|
});
|
261
262
|
|
263
|
+
def_transform(AST_PrivateIn, function(self, tw) {
|
264
|
+
self.key = self.key.transform(tw);
|
265
|
+
self.value = self.value.transform(tw);
|
266
|
+
});
|
267
|
+
|
262
268
|
def_transform(AST_Conditional, function(self, tw) {
|
263
269
|
self.condition = self.condition.transform(tw);
|
264
270
|
self.consequent = self.consequent.transform(tw);
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import {
|
2
2
|
AST_Binary,
|
3
3
|
AST_Conditional,
|
4
|
+
AST_Chain,
|
4
5
|
AST_Dot,
|
5
6
|
AST_Object,
|
6
7
|
AST_Sequence,
|
@@ -23,6 +24,7 @@ function first_in_statement(stack) {
|
|
23
24
|
(p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
|
24
25
|
(p instanceof AST_Dot && p.expression === node) ||
|
25
26
|
(p instanceof AST_Sub && p.expression === node) ||
|
27
|
+
(p instanceof AST_Chain && p.expression === node) ||
|
26
28
|
(p instanceof AST_Conditional && p.condition === node) ||
|
27
29
|
(p instanceof AST_Binary && p.left === node) ||
|
28
30
|
(p instanceof AST_UnaryPostfix && p.expression === node)
|
@@ -41,6 +43,7 @@ function left_is_object(node) {
|
|
41
43
|
if (node.TYPE === "Call") return left_is_object(node.expression);
|
42
44
|
if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
|
43
45
|
if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
|
46
|
+
if (node instanceof AST_Chain) return left_is_object(node.expression);
|
44
47
|
if (node instanceof AST_Conditional) return left_is_object(node.condition);
|
45
48
|
if (node instanceof AST_Binary) return left_is_object(node.left);
|
46
49
|
if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
|