terser 5.9.0 → 5.12.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 +23 -0
- package/README.md +30 -8
- package/dist/bundle.min.js +252 -68
- package/lib/ast.js +5 -3
- package/lib/cli.js +13 -9
- package/lib/compress/index.js +35 -14
- package/lib/compress/native-objects.js +1 -0
- package/lib/minify.js +49 -1
- package/lib/mozilla-ast.js +48 -6
- package/lib/output.js +73 -23
- package/lib/parse.js +24 -8
- package/lib/scope.js +5 -4
- package/package.json +5 -3
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/cli.js
CHANGED
@@ -224,7 +224,7 @@ export async function run_cli({ program, packageJson, fs, path }) {
|
|
224
224
|
|
225
225
|
let result;
|
226
226
|
try {
|
227
|
-
result = await minify(files, options);
|
227
|
+
result = await minify(files, options, fs);
|
228
228
|
} catch (ex) {
|
229
229
|
if (ex.name == "SyntaxError") {
|
230
230
|
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
@@ -287,14 +287,18 @@ export async function run_cli({ program, packageJson, fs, path }) {
|
|
287
287
|
}, 2));
|
288
288
|
} else if (program.output == "spidermonkey") {
|
289
289
|
try {
|
290
|
-
const minified = await minify(
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
290
|
+
const minified = await minify(
|
291
|
+
result.code,
|
292
|
+
{
|
293
|
+
compress: false,
|
294
|
+
mangle: false,
|
295
|
+
format: {
|
296
|
+
ast: true,
|
297
|
+
code: false
|
298
|
+
}
|
299
|
+
},
|
300
|
+
fs
|
301
|
+
);
|
298
302
|
console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
|
299
303
|
} catch (ex) {
|
300
304
|
fatal(ex);
|
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/minify.js
CHANGED
@@ -61,7 +61,54 @@ function cache_to_json(cache) {
|
|
61
61
|
};
|
62
62
|
}
|
63
63
|
|
64
|
-
|
64
|
+
function log_input(files, options, fs, debug_folder) {
|
65
|
+
if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
try {
|
70
|
+
fs.mkdirSync(debug_folder);
|
71
|
+
} catch (e) {
|
72
|
+
if (e.code !== "EEXIST") throw e;
|
73
|
+
}
|
74
|
+
|
75
|
+
const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
|
76
|
+
|
77
|
+
options = options || {};
|
78
|
+
|
79
|
+
const options_str = JSON.stringify(options, (_key, thing) => {
|
80
|
+
if (typeof thing === "function") return "[Function " + thing.toString() + "]";
|
81
|
+
if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
|
82
|
+
return thing;
|
83
|
+
}, 4);
|
84
|
+
|
85
|
+
const files_str = (file) => {
|
86
|
+
if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
|
87
|
+
return JSON.stringify(file, null, 2);
|
88
|
+
} else if (typeof file === "object") {
|
89
|
+
return Object.keys(file)
|
90
|
+
.map((key) => key + ": " + files_str(file[key]))
|
91
|
+
.join("\n\n");
|
92
|
+
} else if (typeof file === "string") {
|
93
|
+
return "```\n" + file + "\n```";
|
94
|
+
} else {
|
95
|
+
return file; // What do?
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
|
100
|
+
}
|
101
|
+
|
102
|
+
async function minify(files, options, _fs_module) {
|
103
|
+
if (
|
104
|
+
_fs_module
|
105
|
+
&& typeof process === "object"
|
106
|
+
&& process.env
|
107
|
+
&& typeof process.env.TERSER_DEBUG_DIR === "string"
|
108
|
+
) {
|
109
|
+
log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
|
110
|
+
}
|
111
|
+
|
65
112
|
options = defaults(options, {
|
66
113
|
compress: {},
|
67
114
|
ecma: undefined,
|
@@ -84,6 +131,7 @@ async function minify(files, options) {
|
|
84
131
|
warnings: false,
|
85
132
|
wrap: false,
|
86
133
|
}, true);
|
134
|
+
|
87
135
|
var timings = options.timings && {
|
88
136
|
start: Date.now()
|
89
137
|
};
|
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
@@ -172,10 +172,52 @@ function is_some_comments(comment) {
|
|
172
172
|
// multiline comment
|
173
173
|
return (
|
174
174
|
(comment.type === "comment2" || comment.type === "comment1")
|
175
|
-
&& /@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
|
175
|
+
&& /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
|
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,11 +282,11 @@ 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
|
-
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
247
|
-
if (options.ecma >= 2015 && !options.safari10) {
|
288
|
+
var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
|
289
|
+
if (options.ecma >= 2015 && !options.safari10 && !regexp) {
|
248
290
|
str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
|
249
291
|
var code = get_full_char_code(ch, 0).toString(16);
|
250
292
|
return "\\u{" + code + "}";
|
@@ -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 ||
|
@@ -2163,7 +2213,7 @@ function OutputStream(options) {
|
|
2163
2213
|
flags = flags ? sort_regexp_flags(flags) : "";
|
2164
2214
|
source = source.replace(r_slash_script, slash_script_replace);
|
2165
2215
|
|
2166
|
-
output.print(output.to_utf8(`/${source}/${flags}
|
2216
|
+
output.print(output.to_utf8(`/${source}/${flags}`, false, true));
|
2167
2217
|
|
2168
2218
|
const parent = output.parent();
|
2169
2219
|
if (
|
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
|
|