terser 5.17.4 → 5.17.6
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 +8 -0
- package/dist/bundle.min.js +160 -91
- package/lib/ast.js +35 -0
- package/lib/compress/drop-side-effect-free.js +31 -28
- package/lib/compress/drop-unused.js +29 -30
- package/lib/compress/index.js +0 -2
- package/lib/mozilla-ast.js +33 -5
- package/lib/output.js +33 -26
- package/package.json +1 -1
- package/tools/domprops.js +2 -0
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.17.6
|
4
|
+
- Fixes to mozilla AST input and output, for class properties, private properties and static blocks
|
5
|
+
- Fix outputting a shorthand property in quotes when safari10 and ecma=2015 options are enabled
|
6
|
+
- `configurable` and `enumerable`, used in Object.defineProperty, added to domprops (#1393)
|
7
|
+
|
8
|
+
## v5.17.5
|
9
|
+
- Take into account the non-deferred bits of a class, such as static properties, while dropping unused code.
|
10
|
+
|
3
11
|
## v5.17.4
|
4
12
|
|
5
13
|
- Fix crash when trying to negate a class (`!class{}`)
|
package/dist/bundle.min.js
CHANGED
@@ -5840,6 +5840,40 @@ var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(p
|
|
5840
5840
|
if (this.extends) push(this.extends);
|
5841
5841
|
if (this.name) push(this.name);
|
5842
5842
|
},
|
5843
|
+
/** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */
|
5844
|
+
visit_nondeferred_class_parts(visitor) {
|
5845
|
+
if (this.extends) {
|
5846
|
+
this.extends._walk(visitor);
|
5847
|
+
}
|
5848
|
+
this.properties.forEach((prop) => {
|
5849
|
+
if (prop instanceof AST_ClassStaticBlock) {
|
5850
|
+
prop._walk(visitor);
|
5851
|
+
return;
|
5852
|
+
}
|
5853
|
+
if (prop.computed_key()) {
|
5854
|
+
visitor.push(prop);
|
5855
|
+
prop.key._walk(visitor);
|
5856
|
+
visitor.pop();
|
5857
|
+
}
|
5858
|
+
if ((prop instanceof AST_ClassPrivateProperty || prop instanceof AST_ClassProperty) && prop.static && prop.value) {
|
5859
|
+
visitor.push(prop);
|
5860
|
+
prop.value._walk(visitor);
|
5861
|
+
visitor.pop();
|
5862
|
+
}
|
5863
|
+
});
|
5864
|
+
},
|
5865
|
+
/** go through the bits that are executed later, when the class is `new`'d or a static method is called */
|
5866
|
+
visit_deferred_class_parts(visitor) {
|
5867
|
+
this.properties.forEach((prop) => {
|
5868
|
+
if (prop instanceof AST_ConciseMethod) {
|
5869
|
+
prop.walk(visitor);
|
5870
|
+
} else if (prop instanceof AST_ClassProperty && !prop.static && prop.value) {
|
5871
|
+
visitor.push(prop);
|
5872
|
+
prop.value._walk(visitor);
|
5873
|
+
visitor.pop();
|
5874
|
+
}
|
5875
|
+
});
|
5876
|
+
},
|
5843
5877
|
}, AST_Scope /* TODO a class might have a scope but it's not a scope */);
|
5844
5878
|
|
5845
5879
|
var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) {
|
@@ -5956,6 +5990,7 @@ var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", funct
|
|
5956
5990
|
while (i--) push(this.body[i]);
|
5957
5991
|
},
|
5958
5992
|
clone: clone_block_scope,
|
5993
|
+
computed_key: () => false
|
5959
5994
|
}, AST_Scope);
|
5960
5995
|
|
5961
5996
|
var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) {
|
@@ -7303,22 +7338,25 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7303
7338
|
},
|
7304
7339
|
|
7305
7340
|
MethodDefinition: function(M) {
|
7341
|
+
const is_private = M.key.type === "PrivateIdentifier";
|
7342
|
+
const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || M.key.value });
|
7343
|
+
|
7306
7344
|
var args = {
|
7307
7345
|
start : my_start_token(M),
|
7308
7346
|
end : my_end_token(M),
|
7309
|
-
key
|
7347
|
+
key,
|
7310
7348
|
value : from_moz(M.value),
|
7311
7349
|
static : M.static,
|
7312
7350
|
};
|
7313
7351
|
if (M.kind == "get") {
|
7314
|
-
return new AST_ObjectGetter(args);
|
7352
|
+
return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args);
|
7315
7353
|
}
|
7316
7354
|
if (M.kind == "set") {
|
7317
|
-
return new AST_ObjectSetter(args);
|
7355
|
+
return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args);
|
7318
7356
|
}
|
7319
7357
|
args.is_generator = M.value.generator;
|
7320
7358
|
args.async = M.value.async;
|
7321
|
-
return new AST_ConciseMethod(args);
|
7359
|
+
return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args);
|
7322
7360
|
},
|
7323
7361
|
|
7324
7362
|
FieldDefinition: function(M) {
|
@@ -7342,8 +7380,16 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7342
7380
|
let key;
|
7343
7381
|
if (M.computed) {
|
7344
7382
|
key = from_moz(M.key);
|
7383
|
+
} else if (M.key.type === "PrivateIdentifier") {
|
7384
|
+
return new AST_ClassPrivateProperty({
|
7385
|
+
start : my_start_token(M),
|
7386
|
+
end : my_end_token(M),
|
7387
|
+
key : from_moz(M.key),
|
7388
|
+
value : from_moz(M.value),
|
7389
|
+
static : M.static,
|
7390
|
+
});
|
7345
7391
|
} else {
|
7346
|
-
if (M.key.type !== "Identifier"
|
7392
|
+
if (M.key.type !== "Identifier") {
|
7347
7393
|
throw new Error("Non-Identifier key in PropertyDefinition");
|
7348
7394
|
}
|
7349
7395
|
key = from_moz(M.key);
|
@@ -7358,6 +7404,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7358
7404
|
});
|
7359
7405
|
},
|
7360
7406
|
|
7407
|
+
PrivateIdentifier: function (M) {
|
7408
|
+
return new AST_SymbolPrivateProperty({
|
7409
|
+
start: my_start_token(M),
|
7410
|
+
end: my_end_token(M),
|
7411
|
+
name: M.name
|
7412
|
+
});
|
7413
|
+
},
|
7414
|
+
|
7361
7415
|
StaticBlock: function(M) {
|
7362
7416
|
return new AST_ClassStaticBlock({
|
7363
7417
|
start : my_start_token(M),
|
@@ -7399,6 +7453,15 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
7399
7453
|
},
|
7400
7454
|
|
7401
7455
|
MemberExpression: function(M) {
|
7456
|
+
if (M.property.type === "PrivateIdentifier") {
|
7457
|
+
return new AST_DotHash({
|
7458
|
+
start : my_start_token(M),
|
7459
|
+
end : my_end_token(M),
|
7460
|
+
property : M.property.name,
|
7461
|
+
expression : from_moz(M.object),
|
7462
|
+
optional : M.optional || false
|
7463
|
+
});
|
7464
|
+
}
|
7402
7465
|
return new (M.computed ? AST_Sub : AST_Dot)({
|
7403
7466
|
start : my_start_token(M),
|
7404
7467
|
end : my_end_token(M),
|
@@ -10600,7 +10663,7 @@ function OutputStream(options) {
|
|
10600
10663
|
? output.option("ie8")
|
10601
10664
|
: !is_identifier_string(
|
10602
10665
|
prop,
|
10603
|
-
output.option("ecma") >= 2015
|
10666
|
+
output.option("ecma") >= 2015 && !output.option("safari10")
|
10604
10667
|
);
|
10605
10668
|
|
10606
10669
|
if (self.optional) output.print("?.");
|
@@ -10768,15 +10831,19 @@ function OutputStream(options) {
|
|
10768
10831
|
output.print("new.target");
|
10769
10832
|
});
|
10770
10833
|
|
10834
|
+
/** Prints a prop name. Returns whether it can be used as a shorthand. */
|
10771
10835
|
function print_property_name(key, quote, output) {
|
10772
10836
|
if (output.option("quote_keys")) {
|
10773
|
-
|
10837
|
+
output.print_string(key);
|
10838
|
+
return false;
|
10774
10839
|
}
|
10775
10840
|
if ("" + +key == key && key >= 0) {
|
10776
10841
|
if (output.option("keep_numbers")) {
|
10777
|
-
|
10842
|
+
output.print(key);
|
10843
|
+
return false;
|
10778
10844
|
}
|
10779
|
-
|
10845
|
+
output.print(make_num(key));
|
10846
|
+
return false;
|
10780
10847
|
}
|
10781
10848
|
var print_string = ALL_RESERVED_WORDS.has(key)
|
10782
10849
|
? output.option("ie8")
|
@@ -10786,9 +10853,11 @@ function OutputStream(options) {
|
|
10786
10853
|
: !is_identifier_string(key, true)
|
10787
10854
|
);
|
10788
10855
|
if (print_string || (quote && output.option("keep_quoted_props"))) {
|
10789
|
-
|
10856
|
+
output.print_string(key, quote);
|
10857
|
+
return false;
|
10790
10858
|
}
|
10791
|
-
|
10859
|
+
output.print_name(key);
|
10860
|
+
return true;
|
10792
10861
|
}
|
10793
10862
|
|
10794
10863
|
DEFPRINT(AST_ObjectKeyVal, function(self, output) {
|
@@ -10797,28 +10866,29 @@ function OutputStream(options) {
|
|
10797
10866
|
return def ? def.mangled_name || def.name : self.name;
|
10798
10867
|
}
|
10799
10868
|
|
10800
|
-
|
10801
|
-
if (
|
10802
|
-
|
10803
|
-
|
10804
|
-
|
10805
|
-
|
10806
|
-
) &&
|
10807
|
-
get_name(self.value) === self.key &&
|
10808
|
-
!ALL_RESERVED_WORDS.has(self.key)
|
10869
|
+
const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node);
|
10870
|
+
if (
|
10871
|
+
try_shorthand
|
10872
|
+
&& self.value instanceof AST_Symbol
|
10873
|
+
&& get_name(self.value) === self.key
|
10874
|
+
&& !ALL_RESERVED_WORDS.has(self.key)
|
10809
10875
|
) {
|
10810
|
-
print_property_name(self.key, self.quote, output);
|
10811
|
-
|
10812
|
-
|
10813
|
-
|
10814
|
-
|
10815
|
-
|
10816
|
-
|
10817
|
-
|
10818
|
-
|
10819
|
-
get_name(self.value.left) === self.key
|
10876
|
+
const was_shorthand = print_property_name(self.key, self.quote, output);
|
10877
|
+
if (!was_shorthand) {
|
10878
|
+
output.colon();
|
10879
|
+
self.value.print(output);
|
10880
|
+
}
|
10881
|
+
} else if (
|
10882
|
+
try_shorthand
|
10883
|
+
&& self.value instanceof AST_DefaultAssign
|
10884
|
+
&& self.value.left instanceof AST_Symbol
|
10885
|
+
&& get_name(self.value.left) === self.key
|
10820
10886
|
) {
|
10821
|
-
print_property_name(self.key, self.quote, output);
|
10887
|
+
const was_shorthand = print_property_name(self.key, self.quote, output);
|
10888
|
+
if (!was_shorthand) {
|
10889
|
+
output.colon();
|
10890
|
+
self.value.left.print(output);
|
10891
|
+
}
|
10822
10892
|
output.space();
|
10823
10893
|
output.print("=");
|
10824
10894
|
output.space();
|
@@ -14772,31 +14842,43 @@ def_drop_side_effect_free(AST_Class, function (compressor) {
|
|
14772
14842
|
const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
|
14773
14843
|
if (trimmed_extends)
|
14774
14844
|
with_effects.push(trimmed_extends);
|
14845
|
+
|
14775
14846
|
for (const prop of this.properties) {
|
14776
14847
|
if (prop instanceof AST_ClassStaticBlock) {
|
14777
|
-
if (prop.
|
14778
|
-
return this;
|
14779
|
-
} else {
|
14780
|
-
continue;
|
14848
|
+
if (prop.has_side_effects(compressor)) {
|
14849
|
+
return this; // Be cautious about these
|
14781
14850
|
}
|
14782
|
-
}
|
14851
|
+
} else {
|
14852
|
+
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
14853
|
+
if (trimmed_prop) {
|
14854
|
+
if (trimmed_prop.contains_this()) return this;
|
14783
14855
|
|
14784
|
-
|
14785
|
-
|
14786
|
-
&& prop.static
|
14787
|
-
&& prop.value.has_side_effects(compressor)
|
14788
|
-
&& prop.contains_this()
|
14789
|
-
) {
|
14790
|
-
return this;
|
14856
|
+
with_effects.push(trimmed_prop);
|
14857
|
+
}
|
14791
14858
|
}
|
14792
|
-
|
14793
|
-
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
14794
|
-
if (trimmed_prop)
|
14795
|
-
with_effects.push(trimmed_prop);
|
14796
14859
|
}
|
14860
|
+
|
14797
14861
|
if (!with_effects.length)
|
14798
14862
|
return null;
|
14799
|
-
|
14863
|
+
|
14864
|
+
const exprs = make_sequence(this, with_effects);
|
14865
|
+
if (this instanceof AST_DefClass) {
|
14866
|
+
// We want a statement
|
14867
|
+
return make_node(AST_SimpleStatement, this, { body: exprs });
|
14868
|
+
} else {
|
14869
|
+
return exprs;
|
14870
|
+
}
|
14871
|
+
});
|
14872
|
+
|
14873
|
+
def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
|
14874
|
+
const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
|
14875
|
+
|
14876
|
+
const value = this.static && this.value
|
14877
|
+
&& this.value.drop_side_effect_free(compressor);
|
14878
|
+
|
14879
|
+
if (key && value)
|
14880
|
+
return make_sequence(this, [key, value]);
|
14881
|
+
return key || value || null;
|
14800
14882
|
});
|
14801
14883
|
|
14802
14884
|
def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) {
|
@@ -14902,17 +14984,6 @@ def_drop_side_effect_free(AST_ObjectProperty, function (compressor, first_in_sta
|
|
14902
14984
|
return key || value;
|
14903
14985
|
});
|
14904
14986
|
|
14905
|
-
def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
|
14906
|
-
const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
|
14907
|
-
|
14908
|
-
const value = this.static && this.value
|
14909
|
-
&& this.value.drop_side_effect_free(compressor);
|
14910
|
-
|
14911
|
-
if (key && value)
|
14912
|
-
return make_sequence(this, [key, value]);
|
14913
|
-
return key || value || null;
|
14914
|
-
});
|
14915
|
-
|
14916
14987
|
def_drop_side_effect_free(AST_ConciseMethod, function () {
|
14917
14988
|
return this.computed_key() ? this.key : null;
|
14918
14989
|
});
|
@@ -15072,6 +15143,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15072
15143
|
});
|
15073
15144
|
}
|
15074
15145
|
if (node === self) return;
|
15146
|
+
if (node instanceof AST_Class) {
|
15147
|
+
if (node.has_side_effects(compressor)) {
|
15148
|
+
node.visit_nondeferred_class_parts(tw);
|
15149
|
+
}
|
15150
|
+
}
|
15075
15151
|
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
15076
15152
|
var node_def = node.name.definition();
|
15077
15153
|
const in_export = tw.parent() instanceof AST_Export;
|
@@ -15080,23 +15156,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15080
15156
|
in_use_ids.set(node_def.id, node_def);
|
15081
15157
|
}
|
15082
15158
|
}
|
15083
|
-
|
15084
|
-
if (
|
15085
|
-
node.extends
|
15086
|
-
&& (node.extends.has_side_effects(compressor)
|
15087
|
-
|| node.extends.may_throw(compressor))
|
15088
|
-
) {
|
15089
|
-
node.extends.walk(tw);
|
15090
|
-
}
|
15091
|
-
for (const prop of node.properties) {
|
15092
|
-
if (
|
15093
|
-
prop.has_side_effects(compressor) ||
|
15094
|
-
prop.may_throw(compressor)
|
15095
|
-
) {
|
15096
|
-
prop.walk(tw);
|
15097
|
-
}
|
15098
|
-
}
|
15099
|
-
}
|
15159
|
+
|
15100
15160
|
map_add(initializations, node_def.id, node);
|
15101
15161
|
return true; // don't go in nested scopes
|
15102
15162
|
}
|
@@ -15161,9 +15221,9 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15161
15221
|
if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
|
15162
15222
|
return maintain_this_binding(parent, node, node.right.transform(tt));
|
15163
15223
|
}
|
15164
|
-
} else if (!in_use)
|
15165
|
-
value: 0
|
15166
|
-
}
|
15224
|
+
} else if (!in_use) {
|
15225
|
+
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
15226
|
+
}
|
15167
15227
|
}
|
15168
15228
|
}
|
15169
15229
|
if (scope !== self) return;
|
@@ -15206,11 +15266,18 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15206
15266
|
if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
|
15207
15267
|
const def = node.name.definition();
|
15208
15268
|
const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
|
15209
|
-
|
15210
|
-
|
15211
|
-
|
15212
|
-
|
15213
|
-
|
15269
|
+
if (!keep) {
|
15270
|
+
// Class "extends" and static blocks may have side effects
|
15271
|
+
if (node instanceof AST_Class) {
|
15272
|
+
const kept = node.drop_side_effect_free(compressor);
|
15273
|
+
if (kept !== node) {
|
15274
|
+
def.eliminated++;
|
15275
|
+
if (kept) return kept;
|
15276
|
+
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
15277
|
+
} else {
|
15278
|
+
return kept;
|
15279
|
+
}
|
15280
|
+
}
|
15214
15281
|
def.eliminated++;
|
15215
15282
|
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
15216
15283
|
}
|
@@ -15306,9 +15373,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15306
15373
|
case 1:
|
15307
15374
|
return body[0];
|
15308
15375
|
default:
|
15309
|
-
return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
|
15310
|
-
body: body
|
15311
|
-
});
|
15376
|
+
return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body });
|
15312
15377
|
}
|
15313
15378
|
}
|
15314
15379
|
// certain combination of unused name + side effect leads to:
|
@@ -15351,7 +15416,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15351
15416
|
}
|
15352
15417
|
return node;
|
15353
15418
|
}
|
15354
|
-
if (node instanceof AST_Scope) {
|
15419
|
+
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
15355
15420
|
const save_scope = scope;
|
15356
15421
|
scope = node;
|
15357
15422
|
descend(node, this);
|
@@ -15390,7 +15455,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15390
15455
|
}
|
15391
15456
|
return true;
|
15392
15457
|
}
|
15393
|
-
if (node instanceof
|
15458
|
+
if (node instanceof AST_Class) {
|
15459
|
+
descend();
|
15460
|
+
return true;
|
15461
|
+
}
|
15462
|
+
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
15394
15463
|
var save_scope = scope;
|
15395
15464
|
scope = node;
|
15396
15465
|
descend();
|
@@ -18556,8 +18625,6 @@ def_optimize(AST_Lambda, opt_AST_Lambda);
|
|
18556
18625
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
18557
18626
|
var self = this;
|
18558
18627
|
if (compressor.has_directive("use asm")) return self;
|
18559
|
-
// Hoisting makes no sense in an arrow func
|
18560
|
-
if (!Array.isArray(self.body)) return self;
|
18561
18628
|
|
18562
18629
|
var hoist_funs = compressor.option("hoist_funs");
|
18563
18630
|
var hoist_vars = compressor.option("hoist_vars");
|
@@ -25381,6 +25448,7 @@ var domprops = [
|
|
25381
25448
|
"coneInnerAngle",
|
25382
25449
|
"coneOuterAngle",
|
25383
25450
|
"coneOuterGain",
|
25451
|
+
"configurable",
|
25384
25452
|
"configuration",
|
25385
25453
|
"configurationName",
|
25386
25454
|
"configurationValue",
|
@@ -25890,6 +25958,7 @@ var domprops = [
|
|
25890
25958
|
"entities",
|
25891
25959
|
"entries",
|
25892
25960
|
"entryType",
|
25961
|
+
"enumerable",
|
25893
25962
|
"enumerate",
|
25894
25963
|
"enumerateDevices",
|
25895
25964
|
"enumerateEditable",
|
package/lib/ast.js
CHANGED
@@ -2230,6 +2230,40 @@ var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(p
|
|
2230
2230
|
if (this.extends) push(this.extends);
|
2231
2231
|
if (this.name) push(this.name);
|
2232
2232
|
},
|
2233
|
+
/** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */
|
2234
|
+
visit_nondeferred_class_parts(visitor) {
|
2235
|
+
if (this.extends) {
|
2236
|
+
this.extends._walk(visitor);
|
2237
|
+
}
|
2238
|
+
this.properties.forEach((prop) => {
|
2239
|
+
if (prop instanceof AST_ClassStaticBlock) {
|
2240
|
+
prop._walk(visitor);
|
2241
|
+
return;
|
2242
|
+
}
|
2243
|
+
if (prop.computed_key()) {
|
2244
|
+
visitor.push(prop);
|
2245
|
+
prop.key._walk(visitor);
|
2246
|
+
visitor.pop();
|
2247
|
+
}
|
2248
|
+
if ((prop instanceof AST_ClassPrivateProperty || prop instanceof AST_ClassProperty) && prop.static && prop.value) {
|
2249
|
+
visitor.push(prop);
|
2250
|
+
prop.value._walk(visitor);
|
2251
|
+
visitor.pop();
|
2252
|
+
}
|
2253
|
+
});
|
2254
|
+
},
|
2255
|
+
/** go through the bits that are executed later, when the class is `new`'d or a static method is called */
|
2256
|
+
visit_deferred_class_parts(visitor) {
|
2257
|
+
this.properties.forEach((prop) => {
|
2258
|
+
if (prop instanceof AST_ConciseMethod) {
|
2259
|
+
prop.walk(visitor);
|
2260
|
+
} else if (prop instanceof AST_ClassProperty && !prop.static && prop.value) {
|
2261
|
+
visitor.push(prop);
|
2262
|
+
prop.value._walk(visitor);
|
2263
|
+
visitor.pop();
|
2264
|
+
}
|
2265
|
+
});
|
2266
|
+
},
|
2233
2267
|
}, AST_Scope /* TODO a class might have a scope but it's not a scope */);
|
2234
2268
|
|
2235
2269
|
var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) {
|
@@ -2346,6 +2380,7 @@ var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", funct
|
|
2346
2380
|
while (i--) push(this.body[i]);
|
2347
2381
|
},
|
2348
2382
|
clone: clone_block_scope,
|
2383
|
+
computed_key: () => false
|
2349
2384
|
}, AST_Scope);
|
2350
2385
|
|
2351
2386
|
var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) {
|
@@ -55,6 +55,7 @@ import {
|
|
55
55
|
AST_ConciseMethod,
|
56
56
|
AST_Conditional,
|
57
57
|
AST_Constant,
|
58
|
+
AST_DefClass,
|
58
59
|
AST_Dot,
|
59
60
|
AST_Expansion,
|
60
61
|
AST_Function,
|
@@ -68,6 +69,7 @@ import {
|
|
68
69
|
AST_PropAccess,
|
69
70
|
AST_Scope,
|
70
71
|
AST_Sequence,
|
72
|
+
AST_SimpleStatement,
|
71
73
|
AST_Sub,
|
72
74
|
AST_SymbolRef,
|
73
75
|
AST_TemplateSegment,
|
@@ -156,31 +158,43 @@ def_drop_side_effect_free(AST_Class, function (compressor) {
|
|
156
158
|
const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
|
157
159
|
if (trimmed_extends)
|
158
160
|
with_effects.push(trimmed_extends);
|
161
|
+
|
159
162
|
for (const prop of this.properties) {
|
160
163
|
if (prop instanceof AST_ClassStaticBlock) {
|
161
|
-
if (prop.
|
162
|
-
return this;
|
163
|
-
} else {
|
164
|
-
continue;
|
164
|
+
if (prop.has_side_effects(compressor)) {
|
165
|
+
return this; // Be cautious about these
|
165
166
|
}
|
166
|
-
}
|
167
|
+
} else {
|
168
|
+
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
169
|
+
if (trimmed_prop) {
|
170
|
+
if (trimmed_prop.contains_this()) return this;
|
167
171
|
|
168
|
-
|
169
|
-
|
170
|
-
&& prop.static
|
171
|
-
&& prop.value.has_side_effects(compressor)
|
172
|
-
&& prop.contains_this()
|
173
|
-
) {
|
174
|
-
return this;
|
172
|
+
with_effects.push(trimmed_prop);
|
173
|
+
}
|
175
174
|
}
|
176
|
-
|
177
|
-
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
178
|
-
if (trimmed_prop)
|
179
|
-
with_effects.push(trimmed_prop);
|
180
175
|
}
|
176
|
+
|
181
177
|
if (!with_effects.length)
|
182
178
|
return null;
|
183
|
-
|
179
|
+
|
180
|
+
const exprs = make_sequence(this, with_effects);
|
181
|
+
if (this instanceof AST_DefClass) {
|
182
|
+
// We want a statement
|
183
|
+
return make_node(AST_SimpleStatement, this, { body: exprs });
|
184
|
+
} else {
|
185
|
+
return exprs;
|
186
|
+
}
|
187
|
+
});
|
188
|
+
|
189
|
+
def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
|
190
|
+
const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
|
191
|
+
|
192
|
+
const value = this.static && this.value
|
193
|
+
&& this.value.drop_side_effect_free(compressor);
|
194
|
+
|
195
|
+
if (key && value)
|
196
|
+
return make_sequence(this, [key, value]);
|
197
|
+
return key || value || null;
|
184
198
|
});
|
185
199
|
|
186
200
|
def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) {
|
@@ -286,17 +300,6 @@ def_drop_side_effect_free(AST_ObjectProperty, function (compressor, first_in_sta
|
|
286
300
|
return key || value;
|
287
301
|
});
|
288
302
|
|
289
|
-
def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
|
290
|
-
const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
|
291
|
-
|
292
|
-
const value = this.static && this.value
|
293
|
-
&& this.value.drop_side_effect_free(compressor);
|
294
|
-
|
295
|
-
if (key && value)
|
296
|
-
return make_sequence(this, [key, value]);
|
297
|
-
return key || value || null;
|
298
|
-
});
|
299
|
-
|
300
303
|
def_drop_side_effect_free(AST_ConciseMethod, function () {
|
301
304
|
return this.computed_key() ? this.key : null;
|
302
305
|
});
|
@@ -47,6 +47,7 @@ import {
|
|
47
47
|
AST_BlockStatement,
|
48
48
|
AST_Class,
|
49
49
|
AST_ClassExpression,
|
50
|
+
AST_ClassStaticBlock,
|
50
51
|
AST_DefaultAssign,
|
51
52
|
AST_DefClass,
|
52
53
|
AST_Definitions,
|
@@ -152,6 +153,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
152
153
|
});
|
153
154
|
}
|
154
155
|
if (node === self) return;
|
156
|
+
if (node instanceof AST_Class) {
|
157
|
+
if (node.has_side_effects(compressor)) {
|
158
|
+
node.visit_nondeferred_class_parts(tw);
|
159
|
+
}
|
160
|
+
}
|
155
161
|
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
156
162
|
var node_def = node.name.definition();
|
157
163
|
const in_export = tw.parent() instanceof AST_Export;
|
@@ -160,23 +166,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
160
166
|
in_use_ids.set(node_def.id, node_def);
|
161
167
|
}
|
162
168
|
}
|
163
|
-
|
164
|
-
if (
|
165
|
-
node.extends
|
166
|
-
&& (node.extends.has_side_effects(compressor)
|
167
|
-
|| node.extends.may_throw(compressor))
|
168
|
-
) {
|
169
|
-
node.extends.walk(tw);
|
170
|
-
}
|
171
|
-
for (const prop of node.properties) {
|
172
|
-
if (
|
173
|
-
prop.has_side_effects(compressor) ||
|
174
|
-
prop.may_throw(compressor)
|
175
|
-
) {
|
176
|
-
prop.walk(tw);
|
177
|
-
}
|
178
|
-
}
|
179
|
-
}
|
169
|
+
|
180
170
|
map_add(initializations, node_def.id, node);
|
181
171
|
return true; // don't go in nested scopes
|
182
172
|
}
|
@@ -241,9 +231,9 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
241
231
|
if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
|
242
232
|
return maintain_this_binding(parent, node, node.right.transform(tt));
|
243
233
|
}
|
244
|
-
} else if (!in_use)
|
245
|
-
value: 0
|
246
|
-
}
|
234
|
+
} else if (!in_use) {
|
235
|
+
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
236
|
+
}
|
247
237
|
}
|
248
238
|
}
|
249
239
|
if (scope !== self) return;
|
@@ -286,11 +276,18 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
286
276
|
if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
|
287
277
|
const def = node.name.definition();
|
288
278
|
const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
279
|
+
if (!keep) {
|
280
|
+
// Class "extends" and static blocks may have side effects
|
281
|
+
if (node instanceof AST_Class) {
|
282
|
+
const kept = node.drop_side_effect_free(compressor);
|
283
|
+
if (kept !== node) {
|
284
|
+
def.eliminated++;
|
285
|
+
if (kept) return kept;
|
286
|
+
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
287
|
+
} else {
|
288
|
+
return kept;
|
289
|
+
}
|
290
|
+
}
|
294
291
|
def.eliminated++;
|
295
292
|
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
296
293
|
}
|
@@ -386,9 +383,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
386
383
|
case 1:
|
387
384
|
return body[0];
|
388
385
|
default:
|
389
|
-
return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
|
390
|
-
body: body
|
391
|
-
});
|
386
|
+
return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body });
|
392
387
|
}
|
393
388
|
}
|
394
389
|
// certain combination of unused name + side effect leads to:
|
@@ -431,7 +426,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
431
426
|
}
|
432
427
|
return node;
|
433
428
|
}
|
434
|
-
if (node instanceof AST_Scope) {
|
429
|
+
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
435
430
|
const save_scope = scope;
|
436
431
|
scope = node;
|
437
432
|
descend(node, this);
|
@@ -470,7 +465,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
470
465
|
}
|
471
466
|
return true;
|
472
467
|
}
|
473
|
-
if (node instanceof
|
468
|
+
if (node instanceof AST_Class) {
|
469
|
+
descend();
|
470
|
+
return true;
|
471
|
+
}
|
472
|
+
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
474
473
|
var save_scope = scope;
|
475
474
|
scope = node;
|
476
475
|
descend();
|
package/lib/compress/index.js
CHANGED
@@ -655,8 +655,6 @@ def_optimize(AST_Lambda, opt_AST_Lambda);
|
|
655
655
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
656
656
|
var self = this;
|
657
657
|
if (compressor.has_directive("use asm")) return self;
|
658
|
-
// Hoisting makes no sense in an arrow func
|
659
|
-
if (!Array.isArray(self.body)) return self;
|
660
658
|
|
661
659
|
var hoist_funs = compressor.option("hoist_funs");
|
662
660
|
var hoist_vars = compressor.option("hoist_vars");
|
package/lib/mozilla-ast.js
CHANGED
@@ -395,22 +395,25 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
395
395
|
},
|
396
396
|
|
397
397
|
MethodDefinition: function(M) {
|
398
|
+
const is_private = M.key.type === "PrivateIdentifier";
|
399
|
+
const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || M.key.value });
|
400
|
+
|
398
401
|
var args = {
|
399
402
|
start : my_start_token(M),
|
400
403
|
end : my_end_token(M),
|
401
|
-
key
|
404
|
+
key,
|
402
405
|
value : from_moz(M.value),
|
403
406
|
static : M.static,
|
404
407
|
};
|
405
408
|
if (M.kind == "get") {
|
406
|
-
return new AST_ObjectGetter(args);
|
409
|
+
return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args);
|
407
410
|
}
|
408
411
|
if (M.kind == "set") {
|
409
|
-
return new AST_ObjectSetter(args);
|
412
|
+
return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args);
|
410
413
|
}
|
411
414
|
args.is_generator = M.value.generator;
|
412
415
|
args.async = M.value.async;
|
413
|
-
return new AST_ConciseMethod(args);
|
416
|
+
return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args);
|
414
417
|
},
|
415
418
|
|
416
419
|
FieldDefinition: function(M) {
|
@@ -434,8 +437,16 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
434
437
|
let key;
|
435
438
|
if (M.computed) {
|
436
439
|
key = from_moz(M.key);
|
440
|
+
} else if (M.key.type === "PrivateIdentifier") {
|
441
|
+
return new AST_ClassPrivateProperty({
|
442
|
+
start : my_start_token(M),
|
443
|
+
end : my_end_token(M),
|
444
|
+
key : from_moz(M.key),
|
445
|
+
value : from_moz(M.value),
|
446
|
+
static : M.static,
|
447
|
+
});
|
437
448
|
} else {
|
438
|
-
if (M.key.type !== "Identifier"
|
449
|
+
if (M.key.type !== "Identifier") {
|
439
450
|
throw new Error("Non-Identifier key in PropertyDefinition");
|
440
451
|
}
|
441
452
|
key = from_moz(M.key);
|
@@ -450,6 +461,14 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
450
461
|
});
|
451
462
|
},
|
452
463
|
|
464
|
+
PrivateIdentifier: function (M) {
|
465
|
+
return new AST_SymbolPrivateProperty({
|
466
|
+
start: my_start_token(M),
|
467
|
+
end: my_end_token(M),
|
468
|
+
name: M.name
|
469
|
+
});
|
470
|
+
},
|
471
|
+
|
453
472
|
StaticBlock: function(M) {
|
454
473
|
return new AST_ClassStaticBlock({
|
455
474
|
start : my_start_token(M),
|
@@ -491,6 +510,15 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
491
510
|
},
|
492
511
|
|
493
512
|
MemberExpression: function(M) {
|
513
|
+
if (M.property.type === "PrivateIdentifier") {
|
514
|
+
return new AST_DotHash({
|
515
|
+
start : my_start_token(M),
|
516
|
+
end : my_end_token(M),
|
517
|
+
property : M.property.name,
|
518
|
+
expression : from_moz(M.object),
|
519
|
+
optional : M.optional || false
|
520
|
+
});
|
521
|
+
}
|
494
522
|
return new (M.computed ? AST_Sub : AST_Dot)({
|
495
523
|
start : my_start_token(M),
|
496
524
|
end : my_end_token(M),
|
package/lib/output.js
CHANGED
@@ -1917,7 +1917,7 @@ function OutputStream(options) {
|
|
1917
1917
|
? output.option("ie8")
|
1918
1918
|
: !is_identifier_string(
|
1919
1919
|
prop,
|
1920
|
-
output.option("ecma") >= 2015
|
1920
|
+
output.option("ecma") >= 2015 && !output.option("safari10")
|
1921
1921
|
);
|
1922
1922
|
|
1923
1923
|
if (self.optional) output.print("?.");
|
@@ -2085,15 +2085,19 @@ function OutputStream(options) {
|
|
2085
2085
|
output.print("new.target");
|
2086
2086
|
});
|
2087
2087
|
|
2088
|
+
/** Prints a prop name. Returns whether it can be used as a shorthand. */
|
2088
2089
|
function print_property_name(key, quote, output) {
|
2089
2090
|
if (output.option("quote_keys")) {
|
2090
|
-
|
2091
|
+
output.print_string(key);
|
2092
|
+
return false;
|
2091
2093
|
}
|
2092
2094
|
if ("" + +key == key && key >= 0) {
|
2093
2095
|
if (output.option("keep_numbers")) {
|
2094
|
-
|
2096
|
+
output.print(key);
|
2097
|
+
return false;
|
2095
2098
|
}
|
2096
|
-
|
2099
|
+
output.print(make_num(key));
|
2100
|
+
return false;
|
2097
2101
|
}
|
2098
2102
|
var print_string = ALL_RESERVED_WORDS.has(key)
|
2099
2103
|
? output.option("ie8")
|
@@ -2103,9 +2107,11 @@ function OutputStream(options) {
|
|
2103
2107
|
: !is_identifier_string(key, true)
|
2104
2108
|
);
|
2105
2109
|
if (print_string || (quote && output.option("keep_quoted_props"))) {
|
2106
|
-
|
2110
|
+
output.print_string(key, quote);
|
2111
|
+
return false;
|
2107
2112
|
}
|
2108
|
-
|
2113
|
+
output.print_name(key);
|
2114
|
+
return true;
|
2109
2115
|
}
|
2110
2116
|
|
2111
2117
|
DEFPRINT(AST_ObjectKeyVal, function(self, output) {
|
@@ -2114,28 +2120,29 @@ function OutputStream(options) {
|
|
2114
2120
|
return def ? def.mangled_name || def.name : self.name;
|
2115
2121
|
}
|
2116
2122
|
|
2117
|
-
|
2118
|
-
if (
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
) &&
|
2124
|
-
get_name(self.value) === self.key &&
|
2125
|
-
!ALL_RESERVED_WORDS.has(self.key)
|
2123
|
+
const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node);
|
2124
|
+
if (
|
2125
|
+
try_shorthand
|
2126
|
+
&& self.value instanceof AST_Symbol
|
2127
|
+
&& get_name(self.value) === self.key
|
2128
|
+
&& !ALL_RESERVED_WORDS.has(self.key)
|
2126
2129
|
) {
|
2127
|
-
print_property_name(self.key, self.quote, output);
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
get_name(self.value.left) === self.key
|
2130
|
+
const was_shorthand = print_property_name(self.key, self.quote, output);
|
2131
|
+
if (!was_shorthand) {
|
2132
|
+
output.colon();
|
2133
|
+
self.value.print(output);
|
2134
|
+
}
|
2135
|
+
} else if (
|
2136
|
+
try_shorthand
|
2137
|
+
&& self.value instanceof AST_DefaultAssign
|
2138
|
+
&& self.value.left instanceof AST_Symbol
|
2139
|
+
&& get_name(self.value.left) === self.key
|
2137
2140
|
) {
|
2138
|
-
print_property_name(self.key, self.quote, output);
|
2141
|
+
const was_shorthand = print_property_name(self.key, self.quote, output);
|
2142
|
+
if (!was_shorthand) {
|
2143
|
+
output.colon();
|
2144
|
+
self.value.left.print(output);
|
2145
|
+
}
|
2139
2146
|
output.space();
|
2140
2147
|
output.print("=");
|
2141
2148
|
output.space();
|
package/package.json
CHANGED
package/tools/domprops.js
CHANGED
@@ -3575,6 +3575,7 @@ export var domprops = [
|
|
3575
3575
|
"coneInnerAngle",
|
3576
3576
|
"coneOuterAngle",
|
3577
3577
|
"coneOuterGain",
|
3578
|
+
"configurable",
|
3578
3579
|
"configuration",
|
3579
3580
|
"configurationName",
|
3580
3581
|
"configurationValue",
|
@@ -4084,6 +4085,7 @@ export var domprops = [
|
|
4084
4085
|
"entities",
|
4085
4086
|
"entries",
|
4086
4087
|
"entryType",
|
4088
|
+
"enumerable",
|
4087
4089
|
"enumerate",
|
4088
4090
|
"enumerateDevices",
|
4089
4091
|
"enumerateEditable",
|