terser 5.16.0 → 5.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +4 -4
- package/dist/bundle.min.js +3320 -3113
- package/lib/ast.js +7 -2
- package/lib/compress/common.js +3 -2
- package/lib/compress/drop-unused.js +482 -0
- package/lib/compress/evaluate.js +7 -0
- package/lib/compress/index.js +5 -392
- package/lib/compress/inference.js +1 -2
- package/lib/compress/inline.js +1 -19
- package/lib/compress/native-objects.js +22 -0
- package/lib/compress/tighten-body.js +38 -30
- package/lib/minify.js +9 -6
- package/lib/mozilla-ast.js +83 -34
- package/lib/output.js +44 -12
- package/lib/parse.js +48 -13
- package/lib/scope.js +33 -9
- package/lib/size.js +6 -8
- package/package.json +1 -1
- package/tools/terser.d.ts +1 -0
- package/bin/terser.mjs +0 -21
@@ -205,9 +205,10 @@ export function trim_unreachable_code(compressor, stat, target) {
|
|
205
205
|
|
206
206
|
/** Tighten a bunch of statements together, and perform statement-level optimization. */
|
207
207
|
export function tighten_body(statements, compressor) {
|
208
|
-
|
209
|
-
|
210
|
-
find_loop_scope_try();
|
208
|
+
const nearest_scope = compressor.find_scope();
|
209
|
+
const defun_scope = nearest_scope.get_defun_scope();
|
210
|
+
const { in_loop, in_try } = find_loop_scope_try();
|
211
|
+
|
211
212
|
var CHANGED, max_iter = 10;
|
212
213
|
do {
|
213
214
|
CHANGED = false;
|
@@ -231,19 +232,20 @@ export function tighten_body(statements, compressor) {
|
|
231
232
|
} while (CHANGED && max_iter-- > 0);
|
232
233
|
|
233
234
|
function find_loop_scope_try() {
|
234
|
-
var node = compressor.self(), level = 0;
|
235
|
+
var node = compressor.self(), level = 0, in_loop = false, in_try = false;
|
235
236
|
do {
|
236
237
|
if (node instanceof AST_Catch || node instanceof AST_Finally) {
|
237
238
|
level++;
|
238
239
|
} else if (node instanceof AST_IterationStatement) {
|
239
240
|
in_loop = true;
|
240
241
|
} else if (node instanceof AST_Scope) {
|
241
|
-
scope = node;
|
242
242
|
break;
|
243
243
|
} else if (node instanceof AST_Try) {
|
244
244
|
in_try = true;
|
245
245
|
}
|
246
246
|
} while (node = compressor.parent(level++));
|
247
|
+
|
248
|
+
return { in_loop, in_try };
|
247
249
|
}
|
248
250
|
|
249
251
|
// Search from right to left for assignment-like expressions:
|
@@ -255,7 +257,7 @@ export function tighten_body(statements, compressor) {
|
|
255
257
|
// Will not attempt to collapse assignments into or past code blocks
|
256
258
|
// which are not sequentially executed, e.g. loops and conditionals.
|
257
259
|
function collapse(statements, compressor) {
|
258
|
-
if (
|
260
|
+
if (nearest_scope.pinned() || defun_scope.pinned())
|
259
261
|
return statements;
|
260
262
|
var args;
|
261
263
|
var candidates = [];
|
@@ -319,10 +321,11 @@ export function tighten_body(statements, compressor) {
|
|
319
321
|
stop_if_hit = parent;
|
320
322
|
}
|
321
323
|
// Replace variable with assignment when found
|
322
|
-
if (
|
324
|
+
if (
|
325
|
+
can_replace
|
323
326
|
&& !(node instanceof AST_SymbolDeclaration)
|
324
327
|
&& lhs.equivalent_to(node)
|
325
|
-
&& !shadows(
|
328
|
+
&& !shadows(scanner.find_scope() || nearest_scope, lvalues)
|
326
329
|
) {
|
327
330
|
if (stop_if_hit) {
|
328
331
|
abort = true;
|
@@ -527,9 +530,9 @@ export function tighten_body(statements, compressor) {
|
|
527
530
|
return true;
|
528
531
|
if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) {
|
529
532
|
var s = node.definition().scope;
|
530
|
-
if (s !==
|
533
|
+
if (s !== defun_scope)
|
531
534
|
while (s = s.parent_scope) {
|
532
|
-
if (s ===
|
535
|
+
if (s === defun_scope)
|
533
536
|
return true;
|
534
537
|
}
|
535
538
|
return found = true;
|
@@ -851,7 +854,7 @@ export function tighten_body(statements, compressor) {
|
|
851
854
|
while (lhs instanceof AST_PropAccess)
|
852
855
|
lhs = lhs.expression;
|
853
856
|
return lhs instanceof AST_SymbolRef
|
854
|
-
&& lhs.definition().scope ===
|
857
|
+
&& lhs.definition().scope.get_defun_scope() === defun_scope
|
855
858
|
&& !(in_loop
|
856
859
|
&& (lvalues.has(lhs.name)
|
857
860
|
|| candidate instanceof AST_Unary
|
@@ -886,15 +889,11 @@ export function tighten_body(statements, compressor) {
|
|
886
889
|
var def = sym.definition();
|
887
890
|
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun)
|
888
891
|
return false;
|
889
|
-
if (def.scope.get_defun_scope() !==
|
892
|
+
if (def.scope.get_defun_scope() !== defun_scope)
|
890
893
|
return true;
|
891
|
-
return
|
892
|
-
|
893
|
-
|
894
|
-
if (s.TYPE == "Scope")
|
895
|
-
s = s.parent_scope;
|
896
|
-
return s === scope;
|
897
|
-
});
|
894
|
+
return def.references.some((ref) =>
|
895
|
+
ref.scope.get_defun_scope() !== defun_scope
|
896
|
+
);
|
898
897
|
}
|
899
898
|
|
900
899
|
function side_effects_external(node, lhs) {
|
@@ -910,18 +909,20 @@ export function tighten_body(statements, compressor) {
|
|
910
909
|
if (node instanceof AST_Sub)
|
911
910
|
return side_effects_external(node.expression, true);
|
912
911
|
if (node instanceof AST_SymbolRef)
|
913
|
-
return node.definition().scope !==
|
912
|
+
return node.definition().scope.get_defun_scope() !== defun_scope;
|
914
913
|
}
|
915
914
|
return false;
|
916
915
|
}
|
917
916
|
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
917
|
+
/**
|
918
|
+
* Will any of the pulled-in lvalues shadow a variable in newScope or parents?
|
919
|
+
* similar to scope_encloses_variables_in_this_scope */
|
920
|
+
function shadows(my_scope, lvalues) {
|
921
|
+
for (const { def } of lvalues.values()) {
|
922
|
+
const looked_up = my_scope.find_variable(def.name);
|
923
|
+
if (looked_up) {
|
924
|
+
if (looked_up === def) continue;
|
925
|
+
return true;
|
925
926
|
}
|
926
927
|
}
|
927
928
|
return false;
|
@@ -1343,7 +1344,7 @@ export function tighten_body(statements, compressor) {
|
|
1343
1344
|
break;
|
1344
1345
|
if (def.name.name != sym.name)
|
1345
1346
|
break;
|
1346
|
-
if (!node.right.is_constant_expression(
|
1347
|
+
if (!node.right.is_constant_expression(nearest_scope))
|
1347
1348
|
break;
|
1348
1349
|
var prop = node.left.property;
|
1349
1350
|
if (prop instanceof AST_Node) {
|
@@ -1403,14 +1404,21 @@ export function tighten_body(statements, compressor) {
|
|
1403
1404
|
CHANGED = true;
|
1404
1405
|
stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
|
1405
1406
|
statements[++j] = stat;
|
1406
|
-
} else if (
|
1407
|
+
} else if (
|
1408
|
+
prev instanceof AST_Var
|
1409
|
+
&& (!stat.init || stat.init.TYPE == prev.TYPE)
|
1410
|
+
) {
|
1407
1411
|
if (stat.init) {
|
1408
1412
|
prev.definitions = prev.definitions.concat(stat.init.definitions);
|
1409
1413
|
}
|
1410
1414
|
stat.init = prev;
|
1411
1415
|
statements[j] = stat;
|
1412
1416
|
CHANGED = true;
|
1413
|
-
} else if (
|
1417
|
+
} else if (
|
1418
|
+
defs instanceof AST_Var
|
1419
|
+
&& stat.init instanceof AST_Var
|
1420
|
+
&& declarations_only(stat.init)
|
1421
|
+
) {
|
1414
1422
|
defs.definitions = defs.definitions.concat(stat.init.definitions);
|
1415
1423
|
stat.init = null;
|
1416
1424
|
statements[++j] = stat;
|
package/lib/minify.js
CHANGED
@@ -19,12 +19,15 @@ import {
|
|
19
19
|
reserve_quoted_keys,
|
20
20
|
} from "./propmangle.js";
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
var
|
26
|
-
|
27
|
-
|
22
|
+
// to/from base64 functions
|
23
|
+
// Prefer built-in Buffer, if available, then use hack
|
24
|
+
// https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem
|
25
|
+
var to_ascii = typeof Buffer !== "undefined"
|
26
|
+
? (b64) => Buffer.from(b64, "base64").toString()
|
27
|
+
: (b64) => decodeURIComponent(escape(atob(b64)));
|
28
|
+
var to_base64 = typeof Buffer !== "undefined"
|
29
|
+
? (str) => Buffer.from(str).toString("base64")
|
30
|
+
: (str) => btoa(unescape(encodeURIComponent(str)));
|
28
31
|
|
29
32
|
function read_source_map(code) {
|
30
33
|
var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
|
package/lib/mozilla-ast.js
CHANGED
@@ -529,24 +529,11 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
529
529
|
var imported_name = null;
|
530
530
|
var imported_names = null;
|
531
531
|
M.specifiers.forEach(function (specifier) {
|
532
|
-
if (specifier.type === "ImportSpecifier") {
|
532
|
+
if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") {
|
533
533
|
if (!imported_names) { imported_names = []; }
|
534
|
-
imported_names.push(
|
535
|
-
start: my_start_token(specifier),
|
536
|
-
end: my_end_token(specifier),
|
537
|
-
foreign_name: from_moz(specifier.imported),
|
538
|
-
name: from_moz(specifier.local)
|
539
|
-
}));
|
534
|
+
imported_names.push(from_moz(specifier));
|
540
535
|
} else if (specifier.type === "ImportDefaultSpecifier") {
|
541
|
-
imported_name = from_moz(specifier
|
542
|
-
} else if (specifier.type === "ImportNamespaceSpecifier") {
|
543
|
-
if (!imported_names) { imported_names = []; }
|
544
|
-
imported_names.push(new AST_NameMapping({
|
545
|
-
start: my_start_token(specifier),
|
546
|
-
end: my_end_token(specifier),
|
547
|
-
foreign_name: new AST_SymbolImportForeign({ name: "*" }),
|
548
|
-
name: from_moz(specifier.local)
|
549
|
-
}));
|
536
|
+
imported_name = from_moz(specifier);
|
550
537
|
}
|
551
538
|
});
|
552
539
|
return new AST_Import({
|
@@ -559,14 +546,39 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
559
546
|
});
|
560
547
|
},
|
561
548
|
|
549
|
+
ImportSpecifier: function(M) {
|
550
|
+
return new AST_NameMapping({
|
551
|
+
start: my_start_token(M),
|
552
|
+
end: my_end_token(M),
|
553
|
+
foreign_name: from_moz(M.imported),
|
554
|
+
name: from_moz(M.local)
|
555
|
+
});
|
556
|
+
},
|
557
|
+
|
558
|
+
ImportDefaultSpecifier: function(M) {
|
559
|
+
return from_moz(M.local);
|
560
|
+
},
|
561
|
+
|
562
|
+
ImportNamespaceSpecifier: function(M) {
|
563
|
+
return new AST_NameMapping({
|
564
|
+
start: my_start_token(M),
|
565
|
+
end: my_end_token(M),
|
566
|
+
foreign_name: new AST_SymbolImportForeign({ name: "*" }),
|
567
|
+
name: from_moz(M.local)
|
568
|
+
});
|
569
|
+
},
|
570
|
+
|
562
571
|
ExportAllDeclaration: function(M) {
|
572
|
+
var foreign_name = M.exported == null ?
|
573
|
+
new AST_SymbolExportForeign({ name: "*" }) :
|
574
|
+
from_moz(M.exported);
|
563
575
|
return new AST_Export({
|
564
576
|
start: my_start_token(M),
|
565
577
|
end: my_end_token(M),
|
566
578
|
exported_names: [
|
567
579
|
new AST_NameMapping({
|
568
580
|
name: new AST_SymbolExportForeign({ name: "*" }),
|
569
|
-
foreign_name:
|
581
|
+
foreign_name: foreign_name
|
570
582
|
})
|
571
583
|
],
|
572
584
|
module_name: from_moz(M.source),
|
@@ -580,10 +592,7 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
580
592
|
end: my_end_token(M),
|
581
593
|
exported_definition: from_moz(M.declaration),
|
582
594
|
exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(function (specifier) {
|
583
|
-
return
|
584
|
-
foreign_name: from_moz(specifier.exported),
|
585
|
-
name: from_moz(specifier.local)
|
586
|
-
});
|
595
|
+
return from_moz(specifier);
|
587
596
|
}) : null,
|
588
597
|
module_name: from_moz(M.source),
|
589
598
|
assert_clause: assert_clause_from_moz(M.assertions)
|
@@ -599,6 +608,13 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
599
608
|
});
|
600
609
|
},
|
601
610
|
|
611
|
+
ExportSpecifier: function(M) {
|
612
|
+
return new AST_NameMapping({
|
613
|
+
foreign_name: from_moz(M.exported),
|
614
|
+
name: from_moz(M.local)
|
615
|
+
});
|
616
|
+
},
|
617
|
+
|
602
618
|
Literal: function(M) {
|
603
619
|
var val = M.value, args = {
|
604
620
|
start : my_start_token(M),
|
@@ -624,6 +640,22 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
624
640
|
if (val === null) return new AST_Null(args);
|
625
641
|
switch (typeof val) {
|
626
642
|
case "string":
|
643
|
+
args.quote = "\"";
|
644
|
+
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
645
|
+
if (p.type == "ImportSpecifier") {
|
646
|
+
args.name = val;
|
647
|
+
return new AST_SymbolImportForeign(args);
|
648
|
+
} else if (p.type == "ExportSpecifier") {
|
649
|
+
args.name = val;
|
650
|
+
if (M == p.exported) {
|
651
|
+
return new AST_SymbolExportForeign(args);
|
652
|
+
} else {
|
653
|
+
return new AST_SymbolExport(args);
|
654
|
+
}
|
655
|
+
} else if (p.type == "ExportAllDeclaration" && M == p.exported) {
|
656
|
+
args.name = val;
|
657
|
+
return new AST_SymbolExportForeign(args);
|
658
|
+
}
|
627
659
|
args.value = val;
|
628
660
|
return new AST_String(args);
|
629
661
|
case "number":
|
@@ -1328,10 +1360,17 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
1328
1360
|
|
1329
1361
|
def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
|
1330
1362
|
if (M.exported_names) {
|
1331
|
-
|
1363
|
+
var first_exported = M.exported_names[0];
|
1364
|
+
var first_exported_name = first_exported.name;
|
1365
|
+
if (first_exported_name.name === "*" && !first_exported_name.quote) {
|
1366
|
+
var foreign_name = first_exported.foreign_name;
|
1367
|
+
var exported = foreign_name.name === "*" && !foreign_name.quote
|
1368
|
+
? null
|
1369
|
+
: to_moz(foreign_name);
|
1332
1370
|
return {
|
1333
1371
|
type: "ExportAllDeclaration",
|
1334
1372
|
source: to_moz(M.module_name),
|
1373
|
+
exported: exported,
|
1335
1374
|
assertions: assert_clause_to_moz(M.assert_clause)
|
1336
1375
|
};
|
1337
1376
|
}
|
@@ -1363,19 +1402,22 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
1363
1402
|
local: to_moz(M.imported_name)
|
1364
1403
|
});
|
1365
1404
|
}
|
1366
|
-
if (M.imported_names
|
1367
|
-
|
1368
|
-
|
1369
|
-
local: to_moz(M.imported_names[0].name)
|
1370
|
-
});
|
1371
|
-
} else if (M.imported_names) {
|
1372
|
-
M.imported_names.forEach(function(name_mapping) {
|
1405
|
+
if (M.imported_names) {
|
1406
|
+
var first_imported_foreign_name = M.imported_names[0].foreign_name;
|
1407
|
+
if (first_imported_foreign_name.name === "*" && !first_imported_foreign_name.quote) {
|
1373
1408
|
specifiers.push({
|
1374
|
-
type: "
|
1375
|
-
local: to_moz(
|
1376
|
-
imported: to_moz(name_mapping.foreign_name)
|
1409
|
+
type: "ImportNamespaceSpecifier",
|
1410
|
+
local: to_moz(M.imported_names[0].name)
|
1377
1411
|
});
|
1378
|
-
}
|
1412
|
+
} else {
|
1413
|
+
M.imported_names.forEach(function(name_mapping) {
|
1414
|
+
specifiers.push({
|
1415
|
+
type: "ImportSpecifier",
|
1416
|
+
local: to_moz(name_mapping.name),
|
1417
|
+
imported: to_moz(name_mapping.foreign_name)
|
1418
|
+
});
|
1419
|
+
});
|
1420
|
+
}
|
1379
1421
|
}
|
1380
1422
|
return {
|
1381
1423
|
type: "ImportDeclaration",
|
@@ -1639,7 +1681,14 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
1639
1681
|
});
|
1640
1682
|
|
1641
1683
|
def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
|
1642
|
-
if (
|
1684
|
+
if (
|
1685
|
+
(M instanceof AST_SymbolMethod && parent.quote) ||
|
1686
|
+
((
|
1687
|
+
M instanceof AST_SymbolImportForeign ||
|
1688
|
+
M instanceof AST_SymbolExportForeign ||
|
1689
|
+
M instanceof AST_SymbolExport
|
1690
|
+
) && M.quote)
|
1691
|
+
) {
|
1643
1692
|
return {
|
1644
1693
|
type: "Literal",
|
1645
1694
|
value: M.name
|
package/lib/output.js
CHANGED
@@ -1225,7 +1225,7 @@ function OutputStream(options) {
|
|
1225
1225
|
}
|
1226
1226
|
|
1227
1227
|
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
|
1228
|
-
|
1228
|
+
print_maybe_braced_body(this.body, output);
|
1229
1229
|
});
|
1230
1230
|
|
1231
1231
|
DEFPRINT(AST_Statement, function(self, output) {
|
@@ -1554,7 +1554,7 @@ function OutputStream(options) {
|
|
1554
1554
|
b = b.body;
|
1555
1555
|
} else break;
|
1556
1556
|
}
|
1557
|
-
|
1557
|
+
print_maybe_braced_body(self.body, output);
|
1558
1558
|
}
|
1559
1559
|
DEFPRINT(AST_If, function(self, output) {
|
1560
1560
|
output.print("if");
|
@@ -1571,7 +1571,7 @@ function OutputStream(options) {
|
|
1571
1571
|
if (self.alternative instanceof AST_If)
|
1572
1572
|
self.alternative.print(output);
|
1573
1573
|
else
|
1574
|
-
|
1574
|
+
print_maybe_braced_body(self.alternative, output);
|
1575
1575
|
} else {
|
1576
1576
|
self._do_print_body(output);
|
1577
1577
|
}
|
@@ -1681,7 +1681,9 @@ function OutputStream(options) {
|
|
1681
1681
|
output.space();
|
1682
1682
|
}
|
1683
1683
|
if (self.imported_names) {
|
1684
|
-
if (self.imported_names.length === 1 &&
|
1684
|
+
if (self.imported_names.length === 1 &&
|
1685
|
+
self.imported_names[0].foreign_name.name === "*" &&
|
1686
|
+
!self.imported_names[0].foreign_name.quote) {
|
1685
1687
|
self.imported_names[0].print(output);
|
1686
1688
|
} else {
|
1687
1689
|
output.print("{");
|
@@ -1715,14 +1717,31 @@ function OutputStream(options) {
|
|
1715
1717
|
DEFPRINT(AST_NameMapping, function(self, output) {
|
1716
1718
|
var is_import = output.parent() instanceof AST_Import;
|
1717
1719
|
var definition = self.name.definition();
|
1720
|
+
var foreign_name = self.foreign_name;
|
1718
1721
|
var names_are_different =
|
1719
1722
|
(definition && definition.mangled_name || self.name.name) !==
|
1720
|
-
|
1723
|
+
foreign_name.name;
|
1724
|
+
if (!names_are_different &&
|
1725
|
+
foreign_name.name === "*" &&
|
1726
|
+
foreign_name.quote != self.name.quote) {
|
1727
|
+
// export * as "*"
|
1728
|
+
names_are_different = true;
|
1729
|
+
}
|
1730
|
+
var foreign_name_is_name = foreign_name.quote == null;
|
1721
1731
|
if (names_are_different) {
|
1722
1732
|
if (is_import) {
|
1723
|
-
|
1733
|
+
if (foreign_name_is_name) {
|
1734
|
+
output.print(foreign_name.name);
|
1735
|
+
} else {
|
1736
|
+
output.print_string(foreign_name.name, foreign_name.quote);
|
1737
|
+
}
|
1724
1738
|
} else {
|
1725
|
-
self.name.
|
1739
|
+
if (self.name.quote == null) {
|
1740
|
+
self.name.print(output);
|
1741
|
+
} else {
|
1742
|
+
output.print_string(self.name.name, self.name.quote);
|
1743
|
+
}
|
1744
|
+
|
1726
1745
|
}
|
1727
1746
|
output.space();
|
1728
1747
|
output.print("as");
|
@@ -1730,10 +1749,18 @@ function OutputStream(options) {
|
|
1730
1749
|
if (is_import) {
|
1731
1750
|
self.name.print(output);
|
1732
1751
|
} else {
|
1733
|
-
|
1752
|
+
if (foreign_name_is_name) {
|
1753
|
+
output.print(foreign_name.name);
|
1754
|
+
} else {
|
1755
|
+
output.print_string(foreign_name.name, foreign_name.quote);
|
1756
|
+
}
|
1734
1757
|
}
|
1735
1758
|
} else {
|
1736
|
-
self.name.
|
1759
|
+
if (self.name.quote == null) {
|
1760
|
+
self.name.print(output);
|
1761
|
+
} else {
|
1762
|
+
output.print_string(self.name.name, self.name.quote);
|
1763
|
+
}
|
1737
1764
|
}
|
1738
1765
|
});
|
1739
1766
|
|
@@ -1745,8 +1772,10 @@ function OutputStream(options) {
|
|
1745
1772
|
output.space();
|
1746
1773
|
}
|
1747
1774
|
if (self.exported_names) {
|
1748
|
-
if (self.exported_names.length === 1 &&
|
1749
|
-
self.exported_names[0].
|
1775
|
+
if (self.exported_names.length === 1 &&
|
1776
|
+
self.exported_names[0].name.name === "*" &&
|
1777
|
+
!self.exported_names[0].name.quote) {
|
1778
|
+
self.exported_names[0].print(output);
|
1750
1779
|
} else {
|
1751
1780
|
output.print("{");
|
1752
1781
|
self.exported_names.forEach(function(name_export, i) {
|
@@ -2266,12 +2295,15 @@ function OutputStream(options) {
|
|
2266
2295
|
}
|
2267
2296
|
});
|
2268
2297
|
|
2269
|
-
|
2298
|
+
/** if, for, while, may or may not have braces surrounding its body */
|
2299
|
+
function print_maybe_braced_body(stat, output) {
|
2270
2300
|
if (output.option("braces")) {
|
2271
2301
|
make_block(stat, output);
|
2272
2302
|
} else {
|
2273
2303
|
if (!stat || stat instanceof AST_EmptyStatement)
|
2274
2304
|
output.force_semicolon();
|
2305
|
+
else if (stat instanceof AST_Let || stat instanceof AST_Const || stat instanceof AST_Class)
|
2306
|
+
make_block(stat, output);
|
2275
2307
|
else
|
2276
2308
|
stat.print(output);
|
2277
2309
|
}
|
package/lib/parse.js
CHANGED
@@ -2089,14 +2089,20 @@ function parse($TEXT, options) {
|
|
2089
2089
|
});
|
2090
2090
|
}
|
2091
2091
|
|
2092
|
+
/**
|
2093
|
+
* var
|
2094
|
+
* vardef1 = 2,
|
2095
|
+
* vardef2 = 3;
|
2096
|
+
*/
|
2092
2097
|
function vardefs(no_in, kind) {
|
2093
|
-
var
|
2098
|
+
var var_defs = [];
|
2094
2099
|
var def;
|
2095
2100
|
for (;;) {
|
2096
2101
|
var sym_type =
|
2097
2102
|
kind === "var" ? AST_SymbolVar :
|
2098
2103
|
kind === "const" ? AST_SymbolConst :
|
2099
2104
|
kind === "let" ? AST_SymbolLet : null;
|
2105
|
+
// var { a } = b
|
2100
2106
|
if (is("punc", "{") || is("punc", "[")) {
|
2101
2107
|
def = new AST_VarDef({
|
2102
2108
|
start: S.token,
|
@@ -2116,12 +2122,12 @@ function parse($TEXT, options) {
|
|
2116
2122
|
});
|
2117
2123
|
if (def.name.name == "import") croak("Unexpected token: import");
|
2118
2124
|
}
|
2119
|
-
|
2125
|
+
var_defs.push(def);
|
2120
2126
|
if (!is("punc", ","))
|
2121
2127
|
break;
|
2122
2128
|
next();
|
2123
2129
|
}
|
2124
|
-
return
|
2130
|
+
return var_defs;
|
2125
2131
|
}
|
2126
2132
|
|
2127
2133
|
var var_ = function(no_in) {
|
@@ -2548,6 +2554,7 @@ function parse($TEXT, options) {
|
|
2548
2554
|
|
2549
2555
|
expect("{");
|
2550
2556
|
// mark in class feild,
|
2557
|
+
const save_in_class = S.in_class;
|
2551
2558
|
S.in_class = true;
|
2552
2559
|
while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
|
2553
2560
|
while (!is("punc", "}")) {
|
@@ -2558,7 +2565,7 @@ function parse($TEXT, options) {
|
|
2558
2565
|
while (is("punc", ";")) { next(); }
|
2559
2566
|
}
|
2560
2567
|
// mark in class feild,
|
2561
|
-
S.in_class =
|
2568
|
+
S.in_class = save_in_class;
|
2562
2569
|
|
2563
2570
|
S.input.pop_directives_stack();
|
2564
2571
|
|
@@ -2787,9 +2794,10 @@ function parse($TEXT, options) {
|
|
2787
2794
|
}
|
2788
2795
|
|
2789
2796
|
function map_name(is_import) {
|
2790
|
-
function make_symbol(type) {
|
2797
|
+
function make_symbol(type, quote) {
|
2791
2798
|
return new type({
|
2792
2799
|
name: as_property_name(),
|
2800
|
+
quote: quote || undefined,
|
2793
2801
|
start: prev(),
|
2794
2802
|
end: prev()
|
2795
2803
|
});
|
@@ -2802,16 +2810,16 @@ function parse($TEXT, options) {
|
|
2802
2810
|
var name;
|
2803
2811
|
|
2804
2812
|
if (is_import) {
|
2805
|
-
foreign_name = make_symbol(foreign_type);
|
2813
|
+
foreign_name = make_symbol(foreign_type, start.quote);
|
2806
2814
|
} else {
|
2807
|
-
name = make_symbol(type);
|
2815
|
+
name = make_symbol(type, start.quote);
|
2808
2816
|
}
|
2809
2817
|
if (is("name", "as")) {
|
2810
2818
|
next(); // The "as" word
|
2811
2819
|
if (is_import) {
|
2812
2820
|
name = make_symbol(type);
|
2813
2821
|
} else {
|
2814
|
-
foreign_name = make_symbol(foreign_type);
|
2822
|
+
foreign_name = make_symbol(foreign_type, S.token.quote);
|
2815
2823
|
}
|
2816
2824
|
} else if (is_import) {
|
2817
2825
|
name = new type(foreign_name);
|
@@ -2827,20 +2835,26 @@ function parse($TEXT, options) {
|
|
2827
2835
|
});
|
2828
2836
|
}
|
2829
2837
|
|
2830
|
-
function map_nameAsterisk(is_import,
|
2838
|
+
function map_nameAsterisk(is_import, import_or_export_foreign_name) {
|
2831
2839
|
var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
|
2832
2840
|
var type = is_import ? AST_SymbolImport : AST_SymbolExport;
|
2833
2841
|
var start = S.token;
|
2834
|
-
var foreign_name;
|
2842
|
+
var name, foreign_name;
|
2835
2843
|
var end = prev();
|
2836
2844
|
|
2845
|
+
if (is_import) {
|
2846
|
+
name = import_or_export_foreign_name;
|
2847
|
+
} else {
|
2848
|
+
foreign_name = import_or_export_foreign_name;
|
2849
|
+
}
|
2850
|
+
|
2837
2851
|
name = name || new type({
|
2838
2852
|
start: start,
|
2839
2853
|
name: "*",
|
2840
2854
|
end: end,
|
2841
2855
|
});
|
2842
2856
|
|
2843
|
-
foreign_name = new foreign_type({
|
2857
|
+
foreign_name = foreign_name || new foreign_type({
|
2844
2858
|
start: start,
|
2845
2859
|
name: "*",
|
2846
2860
|
end: end,
|
@@ -2869,9 +2883,9 @@ function parse($TEXT, options) {
|
|
2869
2883
|
} else if (is("operator", "*")) {
|
2870
2884
|
var name;
|
2871
2885
|
next();
|
2872
|
-
if (
|
2886
|
+
if (is("name", "as")) {
|
2873
2887
|
next(); // The "as" word
|
2874
|
-
name =
|
2888
|
+
name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
|
2875
2889
|
}
|
2876
2890
|
names = [map_nameAsterisk(is_import, name)];
|
2877
2891
|
}
|
@@ -3036,6 +3050,27 @@ function parse($TEXT, options) {
|
|
3036
3050
|
return sym;
|
3037
3051
|
}
|
3038
3052
|
|
3053
|
+
function as_symbol_or_string(type) {
|
3054
|
+
if (!is("name")) {
|
3055
|
+
if (!is("string")) {
|
3056
|
+
croak("Name or string expected");
|
3057
|
+
}
|
3058
|
+
var tok = S.token;
|
3059
|
+
var ret = new type({
|
3060
|
+
start : tok,
|
3061
|
+
end : tok,
|
3062
|
+
name : tok.value,
|
3063
|
+
quote : tok.quote
|
3064
|
+
});
|
3065
|
+
next();
|
3066
|
+
return ret;
|
3067
|
+
}
|
3068
|
+
var sym = _make_symbol(type);
|
3069
|
+
_verify_symbol(sym);
|
3070
|
+
next();
|
3071
|
+
return sym;
|
3072
|
+
}
|
3073
|
+
|
3039
3074
|
// Annotate AST_Call, AST_Lambda or AST_New with the special comments
|
3040
3075
|
function annotate(node) {
|
3041
3076
|
var start = node.start;
|