terser 5.9.0 → 5.10.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/bin/terser.mjs +19 -0
- package/dist/bundle.min.js +186 -54
- package/lib/ast.js +5 -3
- package/lib/compress/index.js +35 -14
- package/lib/compress/native-objects.js +1 -0
- package/lib/mozilla-ast.js +48 -6
- package/lib/output.js +69 -19
- package/lib/parse.js +24 -8
- package/lib/scope.js +5 -4
- package/package.json +9 -2
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.10.0
|
4
|
+
|
5
|
+
- Massive optimization to max_line_len (#1109)
|
6
|
+
- Basic support for import assertions
|
7
|
+
- Marked ES2022 Object.hasOwn as a pure function
|
8
|
+
- Fix `delete optional?.property`
|
9
|
+
- New CI/CD pipeline with github actions (#1057)
|
10
|
+
- Fix reordering of switch branches (#1092), (#1084)
|
11
|
+
- Fix error when creating a class property called `get`
|
12
|
+
- Acorn dependency is now an optional peerDependency
|
13
|
+
- Fix mangling collision with exported variables (#1072)
|
14
|
+
- Fix an issue with `return someVariable = (async () => { ... })()` (#1073)
|
15
|
+
|
3
16
|
## v5.9.0
|
4
17
|
|
5
18
|
- Collapsing switch cases with the same bodies (even if they're not next to each other) (#1070).
|
package/bin/terser.mjs
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
import '../tools/exit.cjs'
|
6
|
+
import fs from 'fs'
|
7
|
+
import path from 'path'
|
8
|
+
import program from 'commander'
|
9
|
+
|
10
|
+
import { _run_cli as run_cli } from '../main.js'
|
11
|
+
|
12
|
+
const packageJson = {
|
13
|
+
name: 'terser',
|
14
|
+
version: 'development-cli'
|
15
|
+
}
|
16
|
+
run_cli({ program, packageJson, fs, path }).catch((error) => {
|
17
|
+
console.error(error);
|
18
|
+
process.exitCode = 1;
|
19
|
+
});
|
package/dist/bundle.min.js
CHANGED
@@ -1387,7 +1387,7 @@ function parse($TEXT, options) {
|
|
1387
1387
|
}
|
1388
1388
|
if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
|
1389
1389
|
next();
|
1390
|
-
var node =
|
1390
|
+
var node = import_statement();
|
1391
1391
|
semicolon();
|
1392
1392
|
return node;
|
1393
1393
|
}
|
@@ -1539,7 +1539,7 @@ function parse($TEXT, options) {
|
|
1539
1539
|
case "export":
|
1540
1540
|
if (!is_token(peek(), "punc", "(")) {
|
1541
1541
|
next();
|
1542
|
-
var node =
|
1542
|
+
var node = export_statement();
|
1543
1543
|
if (is("punc", ";")) semicolon();
|
1544
1544
|
return node;
|
1545
1545
|
}
|
@@ -2716,7 +2716,7 @@ function parse($TEXT, options) {
|
|
2716
2716
|
};
|
2717
2717
|
|
2718
2718
|
const is_not_method_start = () =>
|
2719
|
-
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=");
|
2719
|
+
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=");
|
2720
2720
|
|
2721
2721
|
var is_async = false;
|
2722
2722
|
var is_static = false;
|
@@ -2831,7 +2831,15 @@ function parse($TEXT, options) {
|
|
2831
2831
|
}
|
2832
2832
|
}
|
2833
2833
|
|
2834
|
-
function
|
2834
|
+
function maybe_import_assertion() {
|
2835
|
+
if (is("name", "assert") && !has_newline_before(S.token)) {
|
2836
|
+
next();
|
2837
|
+
return object_or_destructuring_();
|
2838
|
+
}
|
2839
|
+
return null;
|
2840
|
+
}
|
2841
|
+
|
2842
|
+
function import_statement() {
|
2835
2843
|
var start = prev();
|
2836
2844
|
|
2837
2845
|
var imported_name;
|
@@ -2854,16 +2862,20 @@ function parse($TEXT, options) {
|
|
2854
2862
|
unexpected();
|
2855
2863
|
}
|
2856
2864
|
next();
|
2865
|
+
|
2866
|
+
const assert_clause = maybe_import_assertion();
|
2867
|
+
|
2857
2868
|
return new AST_Import({
|
2858
|
-
start
|
2859
|
-
imported_name
|
2860
|
-
imported_names
|
2869
|
+
start,
|
2870
|
+
imported_name,
|
2871
|
+
imported_names,
|
2861
2872
|
module_name: new AST_String({
|
2862
2873
|
start: mod_str,
|
2863
2874
|
value: mod_str.value,
|
2864
2875
|
quote: mod_str.quote,
|
2865
2876
|
end: mod_str,
|
2866
2877
|
}),
|
2878
|
+
assert_clause,
|
2867
2879
|
end: S.token,
|
2868
2880
|
});
|
2869
2881
|
}
|
@@ -2971,7 +2983,7 @@ function parse($TEXT, options) {
|
|
2971
2983
|
return names;
|
2972
2984
|
}
|
2973
2985
|
|
2974
|
-
function
|
2986
|
+
function export_statement() {
|
2975
2987
|
var start = S.token;
|
2976
2988
|
var is_default;
|
2977
2989
|
var exported_names;
|
@@ -2989,6 +3001,8 @@ function parse($TEXT, options) {
|
|
2989
3001
|
}
|
2990
3002
|
next();
|
2991
3003
|
|
3004
|
+
const assert_clause = maybe_import_assertion();
|
3005
|
+
|
2992
3006
|
return new AST_Export({
|
2993
3007
|
start: start,
|
2994
3008
|
is_default: is_default,
|
@@ -3000,6 +3014,7 @@ function parse($TEXT, options) {
|
|
3000
3014
|
end: mod_str,
|
3001
3015
|
}),
|
3002
3016
|
end: prev(),
|
3017
|
+
assert_clause
|
3003
3018
|
});
|
3004
3019
|
} else {
|
3005
3020
|
return new AST_Export({
|
@@ -3045,6 +3060,7 @@ function parse($TEXT, options) {
|
|
3045
3060
|
exported_value: exported_value,
|
3046
3061
|
exported_definition: exported_definition,
|
3047
3062
|
end: prev(),
|
3063
|
+
assert_clause: null
|
3048
3064
|
});
|
3049
3065
|
}
|
3050
3066
|
|
@@ -4378,12 +4394,13 @@ var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", {
|
|
4378
4394
|
},
|
4379
4395
|
});
|
4380
4396
|
|
4381
|
-
var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
4397
|
+
var AST_Import = DEFNODE("Import", "imported_name imported_names module_name assert_clause", {
|
4382
4398
|
$documentation: "An `import` statement",
|
4383
4399
|
$propdoc: {
|
4384
4400
|
imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
|
4385
4401
|
imported_names: "[AST_NameMapping*] The names of non-default imported variables",
|
4386
4402
|
module_name: "[AST_String] String literal describing where this module came from",
|
4403
|
+
assert_clause: "[AST_Object?] The import assertion"
|
4387
4404
|
},
|
4388
4405
|
_walk: function(visitor) {
|
4389
4406
|
return visitor._visit(this, function() {
|
@@ -4412,14 +4429,15 @@ var AST_ImportMeta = DEFNODE("ImportMeta", null, {
|
|
4412
4429
|
$documentation: "A reference to import.meta",
|
4413
4430
|
});
|
4414
4431
|
|
4415
|
-
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
|
4432
|
+
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name assert_clause", {
|
4416
4433
|
$documentation: "An `export` statement",
|
4417
4434
|
$propdoc: {
|
4418
4435
|
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
|
4419
4436
|
exported_value: "[AST_Node?] An exported value",
|
4420
4437
|
exported_names: "[AST_NameMapping*?] List of exported names",
|
4421
4438
|
module_name: "[AST_String?] Name of the file to load exports from",
|
4422
|
-
is_default: "[Boolean] Whether this is the default exported value of this module"
|
4439
|
+
is_default: "[Boolean] Whether this is the default exported value of this module",
|
4440
|
+
assert_clause: "[AST_Object?] The import assertion"
|
4423
4441
|
},
|
4424
4442
|
_walk: function (visitor) {
|
4425
4443
|
return visitor._visit(this, function () {
|
@@ -5672,6 +5690,24 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
5672
5690
|
return body;
|
5673
5691
|
};
|
5674
5692
|
|
5693
|
+
const assert_clause_from_moz = (assertions) => {
|
5694
|
+
if (assertions && assertions.length > 0) {
|
5695
|
+
return new AST_Object({
|
5696
|
+
start: my_start_token(assertions),
|
5697
|
+
end: my_end_token(assertions),
|
5698
|
+
properties: assertions.map((assertion_kv) =>
|
5699
|
+
new AST_ObjectKeyVal({
|
5700
|
+
start: my_start_token(assertion_kv),
|
5701
|
+
end: my_end_token(assertion_kv),
|
5702
|
+
key: assertion_kv.key.name || assertion_kv.key.value,
|
5703
|
+
value: from_moz(assertion_kv.value)
|
5704
|
+
})
|
5705
|
+
)
|
5706
|
+
});
|
5707
|
+
}
|
5708
|
+
return null;
|
5709
|
+
};
|
5710
|
+
|
5675
5711
|
var MOZ_TO_ME = {
|
5676
5712
|
Program: function(M) {
|
5677
5713
|
return new AST_Toplevel({
|
@@ -5992,7 +6028,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
5992
6028
|
end : my_end_token(M),
|
5993
6029
|
imported_name: imported_name,
|
5994
6030
|
imported_names : imported_names,
|
5995
|
-
module_name : from_moz(M.source)
|
6031
|
+
module_name : from_moz(M.source),
|
6032
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
5996
6033
|
});
|
5997
6034
|
},
|
5998
6035
|
ExportAllDeclaration: function(M) {
|
@@ -6005,7 +6042,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6005
6042
|
foreign_name: new AST_SymbolExportForeign({ name: "*" })
|
6006
6043
|
})
|
6007
6044
|
],
|
6008
|
-
module_name: from_moz(M.source)
|
6045
|
+
module_name: from_moz(M.source),
|
6046
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
6009
6047
|
});
|
6010
6048
|
},
|
6011
6049
|
ExportNamedDeclaration: function(M) {
|
@@ -6019,7 +6057,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6019
6057
|
name: from_moz(specifier.local)
|
6020
6058
|
});
|
6021
6059
|
}) : null,
|
6022
|
-
module_name: from_moz(M.source)
|
6060
|
+
module_name: from_moz(M.source),
|
6061
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
6023
6062
|
});
|
6024
6063
|
},
|
6025
6064
|
ExportDefaultDeclaration: function(M) {
|
@@ -6311,12 +6350,30 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6311
6350
|
};
|
6312
6351
|
});
|
6313
6352
|
|
6353
|
+
const assert_clause_to_moz = assert_clause => {
|
6354
|
+
const assertions = [];
|
6355
|
+
if (assert_clause) {
|
6356
|
+
for (const { key, value } of assert_clause.properties) {
|
6357
|
+
const key_moz = is_basic_identifier_string(key)
|
6358
|
+
? { type: "Identifier", name: key }
|
6359
|
+
: { type: "Literal", value: key, raw: JSON.stringify(key) };
|
6360
|
+
assertions.push({
|
6361
|
+
type: "ImportAttribute",
|
6362
|
+
key: key_moz,
|
6363
|
+
value: to_moz(value)
|
6364
|
+
});
|
6365
|
+
}
|
6366
|
+
}
|
6367
|
+
return assertions;
|
6368
|
+
};
|
6369
|
+
|
6314
6370
|
def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
|
6315
6371
|
if (M.exported_names) {
|
6316
6372
|
if (M.exported_names[0].name.name === "*") {
|
6317
6373
|
return {
|
6318
6374
|
type: "ExportAllDeclaration",
|
6319
|
-
source: to_moz(M.module_name)
|
6375
|
+
source: to_moz(M.module_name),
|
6376
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
6320
6377
|
};
|
6321
6378
|
}
|
6322
6379
|
return {
|
@@ -6329,7 +6386,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6329
6386
|
};
|
6330
6387
|
}),
|
6331
6388
|
declaration: to_moz(M.exported_definition),
|
6332
|
-
source: to_moz(M.module_name)
|
6389
|
+
source: to_moz(M.module_name),
|
6390
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
6333
6391
|
};
|
6334
6392
|
}
|
6335
6393
|
return {
|
@@ -6363,7 +6421,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
|
6363
6421
|
return {
|
6364
6422
|
type: "ImportDeclaration",
|
6365
6423
|
specifiers: specifiers,
|
6366
|
-
source: to_moz(M.module_name)
|
6424
|
+
source: to_moz(M.module_name),
|
6425
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
6367
6426
|
};
|
6368
6427
|
});
|
6369
6428
|
|
@@ -6920,6 +6979,48 @@ function is_some_comments(comment) {
|
|
6920
6979
|
);
|
6921
6980
|
}
|
6922
6981
|
|
6982
|
+
class Rope {
|
6983
|
+
constructor() {
|
6984
|
+
this.committed = "";
|
6985
|
+
this.current = "";
|
6986
|
+
}
|
6987
|
+
|
6988
|
+
append(str) {
|
6989
|
+
this.current += str;
|
6990
|
+
}
|
6991
|
+
|
6992
|
+
insertAt(char, index) {
|
6993
|
+
const { committed, current } = this;
|
6994
|
+
if (index < committed.length) {
|
6995
|
+
this.committed = committed.slice(0, index) + char + committed.slice(index);
|
6996
|
+
} else if (index === committed.length) {
|
6997
|
+
this.committed += char;
|
6998
|
+
} else {
|
6999
|
+
index -= committed.length;
|
7000
|
+
this.committed += current.slice(0, index) + char;
|
7001
|
+
this.current = current.slice(index);
|
7002
|
+
}
|
7003
|
+
}
|
7004
|
+
|
7005
|
+
charAt(index) {
|
7006
|
+
const { committed } = this;
|
7007
|
+
if (index < committed.length) return committed[index];
|
7008
|
+
return this.current[index - committed.length];
|
7009
|
+
}
|
7010
|
+
|
7011
|
+
curLength() {
|
7012
|
+
return this.current.length;
|
7013
|
+
}
|
7014
|
+
|
7015
|
+
length() {
|
7016
|
+
return this.committed.length + this.current.length;
|
7017
|
+
}
|
7018
|
+
|
7019
|
+
toString() {
|
7020
|
+
return this.committed + this.current;
|
7021
|
+
}
|
7022
|
+
}
|
7023
|
+
|
6923
7024
|
function OutputStream(options) {
|
6924
7025
|
|
6925
7026
|
var readonly = !options;
|
@@ -6984,7 +7085,7 @@ function OutputStream(options) {
|
|
6984
7085
|
var current_col = 0;
|
6985
7086
|
var current_line = 1;
|
6986
7087
|
var current_pos = 0;
|
6987
|
-
var OUTPUT =
|
7088
|
+
var OUTPUT = new Rope();
|
6988
7089
|
let printed_comments = new Set();
|
6989
7090
|
|
6990
7091
|
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
@@ -7115,19 +7216,18 @@ function OutputStream(options) {
|
|
7115
7216
|
var ensure_line_len = options.max_line_len ? function() {
|
7116
7217
|
if (current_col > options.max_line_len) {
|
7117
7218
|
if (might_add_newline) {
|
7118
|
-
|
7119
|
-
|
7219
|
+
OUTPUT.insertAt("\n", might_add_newline);
|
7220
|
+
const curLength = OUTPUT.curLength();
|
7120
7221
|
if (mappings) {
|
7121
|
-
var delta =
|
7222
|
+
var delta = curLength - current_col;
|
7122
7223
|
mappings.forEach(function(mapping) {
|
7123
7224
|
mapping.line++;
|
7124
7225
|
mapping.col += delta;
|
7125
7226
|
});
|
7126
7227
|
}
|
7127
|
-
OUTPUT = left + "\n" + right;
|
7128
7228
|
current_line++;
|
7129
7229
|
current_pos++;
|
7130
|
-
current_col =
|
7230
|
+
current_col = curLength;
|
7131
7231
|
}
|
7132
7232
|
}
|
7133
7233
|
if (might_add_newline) {
|
@@ -7161,13 +7261,13 @@ function OutputStream(options) {
|
|
7161
7261
|
|
7162
7262
|
if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
|
7163
7263
|
if (options.semicolons || requireSemicolonChars.has(ch)) {
|
7164
|
-
OUTPUT
|
7264
|
+
OUTPUT.append(";");
|
7165
7265
|
current_col++;
|
7166
7266
|
current_pos++;
|
7167
7267
|
} else {
|
7168
7268
|
ensure_line_len();
|
7169
7269
|
if (current_col > 0) {
|
7170
|
-
OUTPUT
|
7270
|
+
OUTPUT.append("\n");
|
7171
7271
|
current_pos++;
|
7172
7272
|
current_line++;
|
7173
7273
|
current_col = 0;
|
@@ -7191,7 +7291,7 @@ function OutputStream(options) {
|
|
7191
7291
|
|| (ch == "/" && ch == prev)
|
7192
7292
|
|| ((ch == "+" || ch == "-") && ch == last)
|
7193
7293
|
) {
|
7194
|
-
OUTPUT
|
7294
|
+
OUTPUT.append(" ");
|
7195
7295
|
current_col++;
|
7196
7296
|
current_pos++;
|
7197
7297
|
}
|
@@ -7209,7 +7309,7 @@ function OutputStream(options) {
|
|
7209
7309
|
if (!might_add_newline) do_add_mapping();
|
7210
7310
|
}
|
7211
7311
|
|
7212
|
-
OUTPUT
|
7312
|
+
OUTPUT.append(str);
|
7213
7313
|
has_parens = str[str.length - 1] == "(";
|
7214
7314
|
current_pos += str.length;
|
7215
7315
|
var a = str.split(/\r?\n/), n = a.length - 1;
|
@@ -7249,15 +7349,15 @@ function OutputStream(options) {
|
|
7249
7349
|
|
7250
7350
|
var newline = options.beautify ? function() {
|
7251
7351
|
if (newline_insert < 0) return print("\n");
|
7252
|
-
if (OUTPUT
|
7253
|
-
OUTPUT
|
7352
|
+
if (OUTPUT.charAt(newline_insert) != "\n") {
|
7353
|
+
OUTPUT.insertAt("\n", newline_insert);
|
7254
7354
|
current_pos++;
|
7255
7355
|
current_line++;
|
7256
7356
|
}
|
7257
7357
|
newline_insert++;
|
7258
7358
|
} : options.max_line_len ? function() {
|
7259
7359
|
ensure_line_len();
|
7260
|
-
might_add_newline = OUTPUT.length;
|
7360
|
+
might_add_newline = OUTPUT.length();
|
7261
7361
|
} : noop;
|
7262
7362
|
|
7263
7363
|
var semicolon = options.beautify ? function() {
|
@@ -7323,13 +7423,14 @@ function OutputStream(options) {
|
|
7323
7423
|
if (might_add_newline) {
|
7324
7424
|
ensure_line_len();
|
7325
7425
|
}
|
7326
|
-
return OUTPUT;
|
7426
|
+
return OUTPUT.toString();
|
7327
7427
|
}
|
7328
7428
|
|
7329
7429
|
function has_nlb() {
|
7330
|
-
|
7430
|
+
const output = OUTPUT.toString();
|
7431
|
+
let n = output.length - 1;
|
7331
7432
|
while (n >= 0) {
|
7332
|
-
const code =
|
7433
|
+
const code = output.charCodeAt(n);
|
7333
7434
|
if (code === CODE_LINE_BREAK) {
|
7334
7435
|
return true;
|
7335
7436
|
}
|
@@ -7466,7 +7567,7 @@ function OutputStream(options) {
|
|
7466
7567
|
!/comment[134]/.test(c.type)
|
7467
7568
|
))) return;
|
7468
7569
|
printed_comments.add(comments);
|
7469
|
-
var insert = OUTPUT.length;
|
7570
|
+
var insert = OUTPUT.length();
|
7470
7571
|
comments.filter(comment_filter, node).forEach(function(c, i) {
|
7471
7572
|
if (printed_comments.has(c)) return;
|
7472
7573
|
printed_comments.add(c);
|
@@ -7495,7 +7596,7 @@ function OutputStream(options) {
|
|
7495
7596
|
need_space = true;
|
7496
7597
|
}
|
7497
7598
|
});
|
7498
|
-
if (OUTPUT.length > insert) newline_insert = insert;
|
7599
|
+
if (OUTPUT.length() > insert) newline_insert = insert;
|
7499
7600
|
}
|
7500
7601
|
|
7501
7602
|
var stack = [];
|
@@ -7525,7 +7626,7 @@ function OutputStream(options) {
|
|
7525
7626
|
var encoded = encode_string(str, quote);
|
7526
7627
|
if (escape_directive === true && !encoded.includes("\\")) {
|
7527
7628
|
// Insert semicolons to break directive prologue
|
7528
|
-
if (!EXPECT_DIRECTIVE.test(OUTPUT)) {
|
7629
|
+
if (!EXPECT_DIRECTIVE.test(OUTPUT.toString())) {
|
7529
7630
|
force_semicolon();
|
7530
7631
|
}
|
7531
7632
|
force_semicolon();
|
@@ -8381,6 +8482,10 @@ function OutputStream(options) {
|
|
8381
8482
|
output.space();
|
8382
8483
|
}
|
8383
8484
|
self.module_name.print(output);
|
8485
|
+
if (self.assert_clause) {
|
8486
|
+
output.print("assert");
|
8487
|
+
self.assert_clause.print(output);
|
8488
|
+
}
|
8384
8489
|
output.semicolon();
|
8385
8490
|
});
|
8386
8491
|
DEFPRINT(AST_ImportMeta, function(self, output) {
|
@@ -8446,6 +8551,10 @@ function OutputStream(options) {
|
|
8446
8551
|
output.space();
|
8447
8552
|
self.module_name.print(output);
|
8448
8553
|
}
|
8554
|
+
if (self.assert_clause) {
|
8555
|
+
output.print("assert");
|
8556
|
+
self.assert_clause.print(output);
|
8557
|
+
}
|
8449
8558
|
if (self.exported_value
|
8450
8559
|
&& !(self.exported_value instanceof AST_Defun ||
|
8451
8560
|
self.exported_value instanceof AST_Function ||
|
@@ -9996,6 +10105,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
9996
10105
|
}
|
9997
10106
|
|
9998
10107
|
const mangled_names = this.mangled_names = new Set();
|
10108
|
+
unmangleable_names = new Set();
|
10109
|
+
|
9999
10110
|
if (options.cache) {
|
10000
10111
|
this.globals.forEach(collect);
|
10001
10112
|
if (options.cache.props) {
|
@@ -10048,7 +10159,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
10048
10159
|
this.walk(tw);
|
10049
10160
|
|
10050
10161
|
if (options.keep_fnames || options.keep_classnames) {
|
10051
|
-
unmangleable_names = new Set();
|
10052
10162
|
// Collect a set of short names which are unmangleable,
|
10053
10163
|
// for use in avoiding collisions in next_mangled.
|
10054
10164
|
to_mangle.forEach(def => {
|
@@ -10064,9 +10174,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
10064
10174
|
unmangleable_names = null;
|
10065
10175
|
|
10066
10176
|
function collect(symbol) {
|
10067
|
-
|
10068
|
-
|
10069
|
-
if (
|
10177
|
+
if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
|
10178
|
+
unmangleable_names.add(symbol.name);
|
10179
|
+
} else if (!options.reserved.has(symbol.name)) {
|
10070
10180
|
to_mangle.push(symbol);
|
10071
10181
|
}
|
10072
10182
|
}
|
@@ -11104,6 +11214,7 @@ const is_pure_native_fn = make_nested_lookup({
|
|
11104
11214
|
"isExtensible",
|
11105
11215
|
"isFrozen",
|
11106
11216
|
"isSealed",
|
11217
|
+
"hasOwn",
|
11107
11218
|
"keys",
|
11108
11219
|
],
|
11109
11220
|
String: [
|
@@ -16131,7 +16242,7 @@ def_optimize(AST_Switch, function(self, compressor) {
|
|
16131
16242
|
// that way the next micro-optimization will merge them.
|
16132
16243
|
// ** bail micro-optimization if not a simple switch case with breaks
|
16133
16244
|
if (body.every((branch, i) =>
|
16134
|
-
(branch === default_or_exact ||
|
16245
|
+
(branch === default_or_exact || branch.expression instanceof AST_Constant)
|
16135
16246
|
&& (branch.body.length === 0 || aborts(branch) || body.length - 1 === i))
|
16136
16247
|
) {
|
16137
16248
|
for (let i = 0; i < body.length; i++) {
|
@@ -16219,12 +16330,16 @@ def_optimize(AST_Switch, function(self, compressor) {
|
|
16219
16330
|
|
16220
16331
|
|
16221
16332
|
// Prune side-effect free branches that fall into default.
|
16222
|
-
if (default_or_exact) {
|
16333
|
+
DEFAULT: if (default_or_exact) {
|
16223
16334
|
let default_index = body.indexOf(default_or_exact);
|
16224
16335
|
let default_body_index = default_index;
|
16225
16336
|
for (; default_body_index < body.length - 1; default_body_index++) {
|
16226
16337
|
if (!is_inert_body(body[default_body_index])) break;
|
16227
16338
|
}
|
16339
|
+
if (default_body_index < body.length - 1) {
|
16340
|
+
break DEFAULT;
|
16341
|
+
}
|
16342
|
+
|
16228
16343
|
let side_effect_index = body.length - 1;
|
16229
16344
|
for (; side_effect_index >= 0; side_effect_index--) {
|
16230
16345
|
let branch = body[side_effect_index];
|
@@ -17271,16 +17386,16 @@ def_optimize(AST_UnaryPostfix, function(self, compressor) {
|
|
17271
17386
|
|
17272
17387
|
def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
17273
17388
|
var e = self.expression;
|
17274
|
-
if (
|
17275
|
-
|
17276
|
-
|
17277
|
-
|
17278
|
-
|
17279
|
-
|
17280
|
-
|
17281
|
-
|
17282
|
-
|
17283
|
-
return make_sequence(self, [
|
17389
|
+
if (
|
17390
|
+
self.operator == "delete" &&
|
17391
|
+
!(
|
17392
|
+
e instanceof AST_SymbolRef ||
|
17393
|
+
e instanceof AST_PropAccess ||
|
17394
|
+
e instanceof AST_Chain ||
|
17395
|
+
is_identifier_atom(e)
|
17396
|
+
)
|
17397
|
+
) {
|
17398
|
+
return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor);
|
17284
17399
|
}
|
17285
17400
|
var seq = self.lift_sequences(compressor);
|
17286
17401
|
if (seq !== self) {
|
@@ -18112,7 +18227,15 @@ function is_reachable(self, defs) {
|
|
18112
18227
|
if (node instanceof AST_Scope && node !== self) {
|
18113
18228
|
var parent = info.parent();
|
18114
18229
|
|
18115
|
-
if (
|
18230
|
+
if (
|
18231
|
+
parent instanceof AST_Call
|
18232
|
+
&& parent.expression === node
|
18233
|
+
// Async/Generators aren't guaranteed to sync evaluate all of
|
18234
|
+
// their body steps, so it's possible they close over the variable.
|
18235
|
+
&& !(node.async || node.is_generator)
|
18236
|
+
) {
|
18237
|
+
return;
|
18238
|
+
}
|
18116
18239
|
|
18117
18240
|
if (walk(node, find_ref)) return walk_abort;
|
18118
18241
|
|
@@ -18764,7 +18887,16 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
18764
18887
|
});
|
18765
18888
|
|
18766
18889
|
def_optimize(AST_Chain, function (self, compressor) {
|
18767
|
-
if (is_nullish(self.expression, compressor))
|
18890
|
+
if (is_nullish(self.expression, compressor)) {
|
18891
|
+
let parent = compressor.parent();
|
18892
|
+
// It's valid to delete a nullish optional chain, but if we optimized
|
18893
|
+
// this to `delete undefined` then it would appear to be a syntax error
|
18894
|
+
// when we try to optimize the delete. Thankfully, `delete 0` is fine.
|
18895
|
+
if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") {
|
18896
|
+
return make_node_from_constant(0, self);
|
18897
|
+
}
|
18898
|
+
return make_node(AST_Undefined, self);
|
18899
|
+
}
|
18768
18900
|
return self;
|
18769
18901
|
});
|
18770
18902
|
|
package/lib/ast.js
CHANGED
@@ -889,12 +889,13 @@ var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", {
|
|
889
889
|
},
|
890
890
|
});
|
891
891
|
|
892
|
-
var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
892
|
+
var AST_Import = DEFNODE("Import", "imported_name imported_names module_name assert_clause", {
|
893
893
|
$documentation: "An `import` statement",
|
894
894
|
$propdoc: {
|
895
895
|
imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
|
896
896
|
imported_names: "[AST_NameMapping*] The names of non-default imported variables",
|
897
897
|
module_name: "[AST_String] String literal describing where this module came from",
|
898
|
+
assert_clause: "[AST_Object?] The import assertion"
|
898
899
|
},
|
899
900
|
_walk: function(visitor) {
|
900
901
|
return visitor._visit(this, function() {
|
@@ -923,14 +924,15 @@ var AST_ImportMeta = DEFNODE("ImportMeta", null, {
|
|
923
924
|
$documentation: "A reference to import.meta",
|
924
925
|
});
|
925
926
|
|
926
|
-
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
|
927
|
+
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name assert_clause", {
|
927
928
|
$documentation: "An `export` statement",
|
928
929
|
$propdoc: {
|
929
930
|
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
|
930
931
|
exported_value: "[AST_Node?] An exported value",
|
931
932
|
exported_names: "[AST_NameMapping*?] List of exported names",
|
932
933
|
module_name: "[AST_String?] Name of the file to load exports from",
|
933
|
-
is_default: "[Boolean] Whether this is the default exported value of this module"
|
934
|
+
is_default: "[Boolean] Whether this is the default exported value of this module",
|
935
|
+
assert_clause: "[AST_Object?] The import assertion"
|
934
936
|
},
|
935
937
|
_walk: function (visitor) {
|
936
938
|
return visitor._visit(this, function () {
|
package/lib/compress/index.js
CHANGED
@@ -1606,7 +1606,7 @@ def_optimize(AST_Switch, function(self, compressor) {
|
|
1606
1606
|
// that way the next micro-optimization will merge them.
|
1607
1607
|
// ** bail micro-optimization if not a simple switch case with breaks
|
1608
1608
|
if (body.every((branch, i) =>
|
1609
|
-
(branch === default_or_exact ||
|
1609
|
+
(branch === default_or_exact || branch.expression instanceof AST_Constant)
|
1610
1610
|
&& (branch.body.length === 0 || aborts(branch) || body.length - 1 === i))
|
1611
1611
|
) {
|
1612
1612
|
for (let i = 0; i < body.length; i++) {
|
@@ -1694,12 +1694,16 @@ def_optimize(AST_Switch, function(self, compressor) {
|
|
1694
1694
|
|
1695
1695
|
|
1696
1696
|
// Prune side-effect free branches that fall into default.
|
1697
|
-
if (default_or_exact) {
|
1697
|
+
DEFAULT: if (default_or_exact) {
|
1698
1698
|
let default_index = body.indexOf(default_or_exact);
|
1699
1699
|
let default_body_index = default_index;
|
1700
1700
|
for (; default_body_index < body.length - 1; default_body_index++) {
|
1701
1701
|
if (!is_inert_body(body[default_body_index])) break;
|
1702
1702
|
}
|
1703
|
+
if (default_body_index < body.length - 1) {
|
1704
|
+
break DEFAULT;
|
1705
|
+
}
|
1706
|
+
|
1703
1707
|
let side_effect_index = body.length - 1;
|
1704
1708
|
for (; side_effect_index >= 0; side_effect_index--) {
|
1705
1709
|
let branch = body[side_effect_index];
|
@@ -2746,16 +2750,16 @@ def_optimize(AST_UnaryPostfix, function(self, compressor) {
|
|
2746
2750
|
|
2747
2751
|
def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
2748
2752
|
var e = self.expression;
|
2749
|
-
if (
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
return make_sequence(self, [
|
2753
|
+
if (
|
2754
|
+
self.operator == "delete" &&
|
2755
|
+
!(
|
2756
|
+
e instanceof AST_SymbolRef ||
|
2757
|
+
e instanceof AST_PropAccess ||
|
2758
|
+
e instanceof AST_Chain ||
|
2759
|
+
is_identifier_atom(e)
|
2760
|
+
)
|
2761
|
+
) {
|
2762
|
+
return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor);
|
2759
2763
|
}
|
2760
2764
|
var seq = self.lift_sequences(compressor);
|
2761
2765
|
if (seq !== self) {
|
@@ -3587,7 +3591,15 @@ function is_reachable(self, defs) {
|
|
3587
3591
|
if (node instanceof AST_Scope && node !== self) {
|
3588
3592
|
var parent = info.parent();
|
3589
3593
|
|
3590
|
-
if (
|
3594
|
+
if (
|
3595
|
+
parent instanceof AST_Call
|
3596
|
+
&& parent.expression === node
|
3597
|
+
// Async/Generators aren't guaranteed to sync evaluate all of
|
3598
|
+
// their body steps, so it's possible they close over the variable.
|
3599
|
+
&& !(node.async || node.is_generator)
|
3600
|
+
) {
|
3601
|
+
return;
|
3602
|
+
}
|
3591
3603
|
|
3592
3604
|
if (walk(node, find_ref)) return walk_abort;
|
3593
3605
|
|
@@ -4239,7 +4251,16 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
4239
4251
|
});
|
4240
4252
|
|
4241
4253
|
def_optimize(AST_Chain, function (self, compressor) {
|
4242
|
-
if (is_nullish(self.expression, compressor))
|
4254
|
+
if (is_nullish(self.expression, compressor)) {
|
4255
|
+
let parent = compressor.parent();
|
4256
|
+
// It's valid to delete a nullish optional chain, but if we optimized
|
4257
|
+
// this to `delete undefined` then it would appear to be a syntax error
|
4258
|
+
// when we try to optimize the delete. Thankfully, `delete 0` is fine.
|
4259
|
+
if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") {
|
4260
|
+
return make_node_from_constant(0, self);
|
4261
|
+
}
|
4262
|
+
return make_node(AST_Undefined, self);
|
4263
|
+
}
|
4243
4264
|
return self;
|
4244
4265
|
});
|
4245
4266
|
|
package/lib/mozilla-ast.js
CHANGED
@@ -158,6 +158,7 @@ import {
|
|
158
158
|
AST_With,
|
159
159
|
AST_Yield,
|
160
160
|
} from "./ast.js";
|
161
|
+
import { is_basic_identifier_string } from "./parse.js";
|
161
162
|
|
162
163
|
(function() {
|
163
164
|
|
@@ -179,6 +180,24 @@ import {
|
|
179
180
|
return body;
|
180
181
|
};
|
181
182
|
|
183
|
+
const assert_clause_from_moz = (assertions) => {
|
184
|
+
if (assertions && assertions.length > 0) {
|
185
|
+
return new AST_Object({
|
186
|
+
start: my_start_token(assertions),
|
187
|
+
end: my_end_token(assertions),
|
188
|
+
properties: assertions.map((assertion_kv) =>
|
189
|
+
new AST_ObjectKeyVal({
|
190
|
+
start: my_start_token(assertion_kv),
|
191
|
+
end: my_end_token(assertion_kv),
|
192
|
+
key: assertion_kv.key.name || assertion_kv.key.value,
|
193
|
+
value: from_moz(assertion_kv.value)
|
194
|
+
})
|
195
|
+
)
|
196
|
+
});
|
197
|
+
}
|
198
|
+
return null;
|
199
|
+
};
|
200
|
+
|
182
201
|
var MOZ_TO_ME = {
|
183
202
|
Program: function(M) {
|
184
203
|
return new AST_Toplevel({
|
@@ -499,7 +518,8 @@ import {
|
|
499
518
|
end : my_end_token(M),
|
500
519
|
imported_name: imported_name,
|
501
520
|
imported_names : imported_names,
|
502
|
-
module_name : from_moz(M.source)
|
521
|
+
module_name : from_moz(M.source),
|
522
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
503
523
|
});
|
504
524
|
},
|
505
525
|
ExportAllDeclaration: function(M) {
|
@@ -512,7 +532,8 @@ import {
|
|
512
532
|
foreign_name: new AST_SymbolExportForeign({ name: "*" })
|
513
533
|
})
|
514
534
|
],
|
515
|
-
module_name: from_moz(M.source)
|
535
|
+
module_name: from_moz(M.source),
|
536
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
516
537
|
});
|
517
538
|
},
|
518
539
|
ExportNamedDeclaration: function(M) {
|
@@ -526,7 +547,8 @@ import {
|
|
526
547
|
name: from_moz(specifier.local)
|
527
548
|
});
|
528
549
|
}) : null,
|
529
|
-
module_name: from_moz(M.source)
|
550
|
+
module_name: from_moz(M.source),
|
551
|
+
assert_clause: assert_clause_from_moz(M.assertions)
|
530
552
|
});
|
531
553
|
},
|
532
554
|
ExportDefaultDeclaration: function(M) {
|
@@ -818,12 +840,30 @@ import {
|
|
818
840
|
};
|
819
841
|
});
|
820
842
|
|
843
|
+
const assert_clause_to_moz = assert_clause => {
|
844
|
+
const assertions = [];
|
845
|
+
if (assert_clause) {
|
846
|
+
for (const { key, value } of assert_clause.properties) {
|
847
|
+
const key_moz = is_basic_identifier_string(key)
|
848
|
+
? { type: "Identifier", name: key }
|
849
|
+
: { type: "Literal", value: key, raw: JSON.stringify(key) };
|
850
|
+
assertions.push({
|
851
|
+
type: "ImportAttribute",
|
852
|
+
key: key_moz,
|
853
|
+
value: to_moz(value)
|
854
|
+
});
|
855
|
+
}
|
856
|
+
}
|
857
|
+
return assertions;
|
858
|
+
};
|
859
|
+
|
821
860
|
def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
|
822
861
|
if (M.exported_names) {
|
823
862
|
if (M.exported_names[0].name.name === "*") {
|
824
863
|
return {
|
825
864
|
type: "ExportAllDeclaration",
|
826
|
-
source: to_moz(M.module_name)
|
865
|
+
source: to_moz(M.module_name),
|
866
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
827
867
|
};
|
828
868
|
}
|
829
869
|
return {
|
@@ -836,7 +876,8 @@ import {
|
|
836
876
|
};
|
837
877
|
}),
|
838
878
|
declaration: to_moz(M.exported_definition),
|
839
|
-
source: to_moz(M.module_name)
|
879
|
+
source: to_moz(M.module_name),
|
880
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
840
881
|
};
|
841
882
|
}
|
842
883
|
return {
|
@@ -870,7 +911,8 @@ import {
|
|
870
911
|
return {
|
871
912
|
type: "ImportDeclaration",
|
872
913
|
specifiers: specifiers,
|
873
|
-
source: to_moz(M.module_name)
|
914
|
+
source: to_moz(M.module_name),
|
915
|
+
assertions: assert_clause_to_moz(M.assert_clause)
|
874
916
|
};
|
875
917
|
});
|
876
918
|
|
package/lib/output.js
CHANGED
@@ -176,6 +176,48 @@ function is_some_comments(comment) {
|
|
176
176
|
);
|
177
177
|
}
|
178
178
|
|
179
|
+
class Rope {
|
180
|
+
constructor() {
|
181
|
+
this.committed = "";
|
182
|
+
this.current = "";
|
183
|
+
}
|
184
|
+
|
185
|
+
append(str) {
|
186
|
+
this.current += str;
|
187
|
+
}
|
188
|
+
|
189
|
+
insertAt(char, index) {
|
190
|
+
const { committed, current } = this;
|
191
|
+
if (index < committed.length) {
|
192
|
+
this.committed = committed.slice(0, index) + char + committed.slice(index);
|
193
|
+
} else if (index === committed.length) {
|
194
|
+
this.committed += char;
|
195
|
+
} else {
|
196
|
+
index -= committed.length;
|
197
|
+
this.committed += current.slice(0, index) + char;
|
198
|
+
this.current = current.slice(index);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
charAt(index) {
|
203
|
+
const { committed } = this;
|
204
|
+
if (index < committed.length) return committed[index];
|
205
|
+
return this.current[index - committed.length];
|
206
|
+
}
|
207
|
+
|
208
|
+
curLength() {
|
209
|
+
return this.current.length;
|
210
|
+
}
|
211
|
+
|
212
|
+
length() {
|
213
|
+
return this.committed.length + this.current.length;
|
214
|
+
}
|
215
|
+
|
216
|
+
toString() {
|
217
|
+
return this.committed + this.current;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
179
221
|
function OutputStream(options) {
|
180
222
|
|
181
223
|
var readonly = !options;
|
@@ -240,7 +282,7 @@ function OutputStream(options) {
|
|
240
282
|
var current_col = 0;
|
241
283
|
var current_line = 1;
|
242
284
|
var current_pos = 0;
|
243
|
-
var OUTPUT =
|
285
|
+
var OUTPUT = new Rope();
|
244
286
|
let printed_comments = new Set();
|
245
287
|
|
246
288
|
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
@@ -371,19 +413,18 @@ function OutputStream(options) {
|
|
371
413
|
var ensure_line_len = options.max_line_len ? function() {
|
372
414
|
if (current_col > options.max_line_len) {
|
373
415
|
if (might_add_newline) {
|
374
|
-
|
375
|
-
|
416
|
+
OUTPUT.insertAt("\n", might_add_newline);
|
417
|
+
const curLength = OUTPUT.curLength();
|
376
418
|
if (mappings) {
|
377
|
-
var delta =
|
419
|
+
var delta = curLength - current_col;
|
378
420
|
mappings.forEach(function(mapping) {
|
379
421
|
mapping.line++;
|
380
422
|
mapping.col += delta;
|
381
423
|
});
|
382
424
|
}
|
383
|
-
OUTPUT = left + "\n" + right;
|
384
425
|
current_line++;
|
385
426
|
current_pos++;
|
386
|
-
current_col =
|
427
|
+
current_col = curLength;
|
387
428
|
}
|
388
429
|
}
|
389
430
|
if (might_add_newline) {
|
@@ -417,13 +458,13 @@ function OutputStream(options) {
|
|
417
458
|
|
418
459
|
if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
|
419
460
|
if (options.semicolons || requireSemicolonChars.has(ch)) {
|
420
|
-
OUTPUT
|
461
|
+
OUTPUT.append(";");
|
421
462
|
current_col++;
|
422
463
|
current_pos++;
|
423
464
|
} else {
|
424
465
|
ensure_line_len();
|
425
466
|
if (current_col > 0) {
|
426
|
-
OUTPUT
|
467
|
+
OUTPUT.append("\n");
|
427
468
|
current_pos++;
|
428
469
|
current_line++;
|
429
470
|
current_col = 0;
|
@@ -447,7 +488,7 @@ function OutputStream(options) {
|
|
447
488
|
|| (ch == "/" && ch == prev)
|
448
489
|
|| ((ch == "+" || ch == "-") && ch == last)
|
449
490
|
) {
|
450
|
-
OUTPUT
|
491
|
+
OUTPUT.append(" ");
|
451
492
|
current_col++;
|
452
493
|
current_pos++;
|
453
494
|
}
|
@@ -465,7 +506,7 @@ function OutputStream(options) {
|
|
465
506
|
if (!might_add_newline) do_add_mapping();
|
466
507
|
}
|
467
508
|
|
468
|
-
OUTPUT
|
509
|
+
OUTPUT.append(str);
|
469
510
|
has_parens = str[str.length - 1] == "(";
|
470
511
|
current_pos += str.length;
|
471
512
|
var a = str.split(/\r?\n/), n = a.length - 1;
|
@@ -505,15 +546,15 @@ function OutputStream(options) {
|
|
505
546
|
|
506
547
|
var newline = options.beautify ? function() {
|
507
548
|
if (newline_insert < 0) return print("\n");
|
508
|
-
if (OUTPUT
|
509
|
-
OUTPUT
|
549
|
+
if (OUTPUT.charAt(newline_insert) != "\n") {
|
550
|
+
OUTPUT.insertAt("\n", newline_insert);
|
510
551
|
current_pos++;
|
511
552
|
current_line++;
|
512
553
|
}
|
513
554
|
newline_insert++;
|
514
555
|
} : options.max_line_len ? function() {
|
515
556
|
ensure_line_len();
|
516
|
-
might_add_newline = OUTPUT.length;
|
557
|
+
might_add_newline = OUTPUT.length();
|
517
558
|
} : noop;
|
518
559
|
|
519
560
|
var semicolon = options.beautify ? function() {
|
@@ -579,13 +620,14 @@ function OutputStream(options) {
|
|
579
620
|
if (might_add_newline) {
|
580
621
|
ensure_line_len();
|
581
622
|
}
|
582
|
-
return OUTPUT;
|
623
|
+
return OUTPUT.toString();
|
583
624
|
}
|
584
625
|
|
585
626
|
function has_nlb() {
|
586
|
-
|
627
|
+
const output = OUTPUT.toString();
|
628
|
+
let n = output.length - 1;
|
587
629
|
while (n >= 0) {
|
588
|
-
const code =
|
630
|
+
const code = output.charCodeAt(n);
|
589
631
|
if (code === CODE_LINE_BREAK) {
|
590
632
|
return true;
|
591
633
|
}
|
@@ -722,7 +764,7 @@ function OutputStream(options) {
|
|
722
764
|
!/comment[134]/.test(c.type)
|
723
765
|
))) return;
|
724
766
|
printed_comments.add(comments);
|
725
|
-
var insert = OUTPUT.length;
|
767
|
+
var insert = OUTPUT.length();
|
726
768
|
comments.filter(comment_filter, node).forEach(function(c, i) {
|
727
769
|
if (printed_comments.has(c)) return;
|
728
770
|
printed_comments.add(c);
|
@@ -751,7 +793,7 @@ function OutputStream(options) {
|
|
751
793
|
need_space = true;
|
752
794
|
}
|
753
795
|
});
|
754
|
-
if (OUTPUT.length > insert) newline_insert = insert;
|
796
|
+
if (OUTPUT.length() > insert) newline_insert = insert;
|
755
797
|
}
|
756
798
|
|
757
799
|
var stack = [];
|
@@ -781,7 +823,7 @@ function OutputStream(options) {
|
|
781
823
|
var encoded = encode_string(str, quote);
|
782
824
|
if (escape_directive === true && !encoded.includes("\\")) {
|
783
825
|
// Insert semicolons to break directive prologue
|
784
|
-
if (!EXPECT_DIRECTIVE.test(OUTPUT)) {
|
826
|
+
if (!EXPECT_DIRECTIVE.test(OUTPUT.toString())) {
|
785
827
|
force_semicolon();
|
786
828
|
}
|
787
829
|
force_semicolon();
|
@@ -1637,6 +1679,10 @@ function OutputStream(options) {
|
|
1637
1679
|
output.space();
|
1638
1680
|
}
|
1639
1681
|
self.module_name.print(output);
|
1682
|
+
if (self.assert_clause) {
|
1683
|
+
output.print("assert");
|
1684
|
+
self.assert_clause.print(output);
|
1685
|
+
}
|
1640
1686
|
output.semicolon();
|
1641
1687
|
});
|
1642
1688
|
DEFPRINT(AST_ImportMeta, function(self, output) {
|
@@ -1702,6 +1748,10 @@ function OutputStream(options) {
|
|
1702
1748
|
output.space();
|
1703
1749
|
self.module_name.print(output);
|
1704
1750
|
}
|
1751
|
+
if (self.assert_clause) {
|
1752
|
+
output.print("assert");
|
1753
|
+
self.assert_clause.print(output);
|
1754
|
+
}
|
1705
1755
|
if (self.exported_value
|
1706
1756
|
&& !(self.exported_value instanceof AST_Defun ||
|
1707
1757
|
self.exported_value instanceof AST_Function ||
|
package/lib/parse.js
CHANGED
@@ -1222,7 +1222,7 @@ function parse($TEXT, options) {
|
|
1222
1222
|
}
|
1223
1223
|
if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
|
1224
1224
|
next();
|
1225
|
-
var node =
|
1225
|
+
var node = import_statement();
|
1226
1226
|
semicolon();
|
1227
1227
|
return node;
|
1228
1228
|
}
|
@@ -1374,7 +1374,7 @@ function parse($TEXT, options) {
|
|
1374
1374
|
case "export":
|
1375
1375
|
if (!is_token(peek(), "punc", "(")) {
|
1376
1376
|
next();
|
1377
|
-
var node =
|
1377
|
+
var node = export_statement();
|
1378
1378
|
if (is("punc", ";")) semicolon();
|
1379
1379
|
return node;
|
1380
1380
|
}
|
@@ -2551,7 +2551,7 @@ function parse($TEXT, options) {
|
|
2551
2551
|
};
|
2552
2552
|
|
2553
2553
|
const is_not_method_start = () =>
|
2554
|
-
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=");
|
2554
|
+
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=");
|
2555
2555
|
|
2556
2556
|
var is_async = false;
|
2557
2557
|
var is_static = false;
|
@@ -2666,7 +2666,15 @@ function parse($TEXT, options) {
|
|
2666
2666
|
}
|
2667
2667
|
}
|
2668
2668
|
|
2669
|
-
function
|
2669
|
+
function maybe_import_assertion() {
|
2670
|
+
if (is("name", "assert") && !has_newline_before(S.token)) {
|
2671
|
+
next();
|
2672
|
+
return object_or_destructuring_();
|
2673
|
+
}
|
2674
|
+
return null;
|
2675
|
+
}
|
2676
|
+
|
2677
|
+
function import_statement() {
|
2670
2678
|
var start = prev();
|
2671
2679
|
|
2672
2680
|
var imported_name;
|
@@ -2689,16 +2697,20 @@ function parse($TEXT, options) {
|
|
2689
2697
|
unexpected();
|
2690
2698
|
}
|
2691
2699
|
next();
|
2700
|
+
|
2701
|
+
const assert_clause = maybe_import_assertion();
|
2702
|
+
|
2692
2703
|
return new AST_Import({
|
2693
|
-
start
|
2694
|
-
imported_name
|
2695
|
-
imported_names
|
2704
|
+
start,
|
2705
|
+
imported_name,
|
2706
|
+
imported_names,
|
2696
2707
|
module_name: new AST_String({
|
2697
2708
|
start: mod_str,
|
2698
2709
|
value: mod_str.value,
|
2699
2710
|
quote: mod_str.quote,
|
2700
2711
|
end: mod_str,
|
2701
2712
|
}),
|
2713
|
+
assert_clause,
|
2702
2714
|
end: S.token,
|
2703
2715
|
});
|
2704
2716
|
}
|
@@ -2806,7 +2818,7 @@ function parse($TEXT, options) {
|
|
2806
2818
|
return names;
|
2807
2819
|
}
|
2808
2820
|
|
2809
|
-
function
|
2821
|
+
function export_statement() {
|
2810
2822
|
var start = S.token;
|
2811
2823
|
var is_default;
|
2812
2824
|
var exported_names;
|
@@ -2824,6 +2836,8 @@ function parse($TEXT, options) {
|
|
2824
2836
|
}
|
2825
2837
|
next();
|
2826
2838
|
|
2839
|
+
const assert_clause = maybe_import_assertion();
|
2840
|
+
|
2827
2841
|
return new AST_Export({
|
2828
2842
|
start: start,
|
2829
2843
|
is_default: is_default,
|
@@ -2835,6 +2849,7 @@ function parse($TEXT, options) {
|
|
2835
2849
|
end: mod_str,
|
2836
2850
|
}),
|
2837
2851
|
end: prev(),
|
2852
|
+
assert_clause
|
2838
2853
|
});
|
2839
2854
|
} else {
|
2840
2855
|
return new AST_Export({
|
@@ -2880,6 +2895,7 @@ function parse($TEXT, options) {
|
|
2880
2895
|
exported_value: exported_value,
|
2881
2896
|
exported_definition: exported_definition,
|
2882
2897
|
end: prev(),
|
2898
|
+
assert_clause: null
|
2883
2899
|
});
|
2884
2900
|
}
|
2885
2901
|
|
package/lib/scope.js
CHANGED
@@ -781,6 +781,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
781
781
|
}
|
782
782
|
|
783
783
|
const mangled_names = this.mangled_names = new Set();
|
784
|
+
unmangleable_names = new Set();
|
785
|
+
|
784
786
|
if (options.cache) {
|
785
787
|
this.globals.forEach(collect);
|
786
788
|
if (options.cache.props) {
|
@@ -833,7 +835,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
833
835
|
this.walk(tw);
|
834
836
|
|
835
837
|
if (options.keep_fnames || options.keep_classnames) {
|
836
|
-
unmangleable_names = new Set();
|
837
838
|
// Collect a set of short names which are unmangleable,
|
838
839
|
// for use in avoiding collisions in next_mangled.
|
839
840
|
to_mangle.forEach(def => {
|
@@ -849,9 +850,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
849
850
|
unmangleable_names = null;
|
850
851
|
|
851
852
|
function collect(symbol) {
|
852
|
-
|
853
|
-
|
854
|
-
if (
|
853
|
+
if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
|
854
|
+
unmangleable_names.add(symbol.name);
|
855
|
+
} else if (!options.reserved.has(symbol.name)) {
|
855
856
|
to_mangle.push(symbol);
|
856
857
|
}
|
857
858
|
}
|
package/package.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"homepage": "https://terser.org",
|
5
5
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
6
6
|
"license": "BSD-2-Clause",
|
7
|
-
"version": "5.
|
7
|
+
"version": "5.10.0",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=10"
|
10
10
|
},
|
@@ -49,7 +49,6 @@
|
|
49
49
|
},
|
50
50
|
"devDependencies": {
|
51
51
|
"@ls-lint/ls-lint": "^1.10.0",
|
52
|
-
"acorn": "^8.5.0",
|
53
52
|
"astring": "^1.7.5",
|
54
53
|
"eslint": "^7.32.0",
|
55
54
|
"eslump": "^3.0.0",
|
@@ -60,6 +59,14 @@
|
|
60
59
|
"rollup": "2.56.3",
|
61
60
|
"semver": "^7.3.4"
|
62
61
|
},
|
62
|
+
"peerDependencies": {
|
63
|
+
"acorn": "^8.5.0"
|
64
|
+
},
|
65
|
+
"peerDependenciesMeta": {
|
66
|
+
"acorn": {
|
67
|
+
"optional": true
|
68
|
+
}
|
69
|
+
},
|
63
70
|
"scripts": {
|
64
71
|
"test": "node test/compress.js && mocha test/mocha",
|
65
72
|
"test:compress": "node test/compress.js",
|