terser 5.16.1 → 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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.16.2
4
+
5
+ - Fix sourcemaps with non-ascii characters (#1318)
6
+ - Support string module name and export * as (#1336)
7
+ - Do not move `let` out of `for` initializers, as it can change scoping
8
+ - Fix a corner case that would generate the invalid syntax `if (something) let x` ("let" in braceless if body)
9
+ - Knowledge of more native object properties (#1330)
10
+ - Got rid of Travis (#1323)
11
+ - Added semi-secret `asObject` sourcemap option to typescript defs (#1321)
12
+
3
13
  ## v5.16.1
4
14
 
5
15
  - Properly handle references in destructurings (`const { [reference]: val } = ...`)
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![NPM Version][npm-image]][npm-url]
4
4
  [![NPM Downloads][downloads-image]][downloads-url]
5
- [![Travis Build][travis-image]][travis-url]
5
+ [![CI pipeline][ci-image]][ci-url]
6
6
  [![Opencollective financial contributors][opencollective-contributors]][opencollective-url]
7
7
 
8
8
  A JavaScript mangler/compressor toolkit for ES6+.
@@ -21,8 +21,8 @@ Find the changelog in [CHANGELOG.md](https://github.com/terser/terser/blob/maste
21
21
  [npm-url]: https://npmjs.org/package/terser
22
22
  [downloads-image]: https://img.shields.io/npm/dm/terser.svg
23
23
  [downloads-url]: https://npmjs.org/package/terser
24
- [travis-image]: https://app.travis-ci.com/terser/terser.svg?branch=master
25
- [travis-url]: https://app.travis-ci.com/github/terser/terser
24
+ [ci-image]: https://github.com/terser/terser/actions/workflows/ci.yml/badge.svg
25
+ [ci-url]: https://github.com/terser/terser/actions/workflows/ci.yml
26
26
  [opencollective-contributors]: https://opencollective.com/terser/tiers/badge.svg
27
27
  [opencollective-url]: https://opencollective.com/terser
28
28
 
@@ -758,7 +758,7 @@ If you happen to need the source map as a raw object, set `sourceMap.asObject` t
758
758
  - `3` -- inline functions with arguments and variables
759
759
  - `true` -- same as `3`
760
760
 
761
- - `join_vars` (default: `true`) -- join consecutive `var` statements
761
+ - `join_vars` (default: `true`) -- join consecutive `var`, `let` and `const` statements
762
762
 
763
763
  - `keep_classnames` (default: `false`) -- Pass `true` to prevent the compressor from
764
764
  discarding class names. Pass a regular expression to only keep class names matching
@@ -2255,14 +2255,20 @@ function parse($TEXT, options) {
2255
2255
  });
2256
2256
  }
2257
2257
 
2258
+ /**
2259
+ * var
2260
+ * vardef1 = 2,
2261
+ * vardef2 = 3;
2262
+ */
2258
2263
  function vardefs(no_in, kind) {
2259
- var a = [];
2264
+ var var_defs = [];
2260
2265
  var def;
2261
2266
  for (;;) {
2262
2267
  var sym_type =
2263
2268
  kind === "var" ? AST_SymbolVar :
2264
2269
  kind === "const" ? AST_SymbolConst :
2265
2270
  kind === "let" ? AST_SymbolLet : null;
2271
+ // var { a } = b
2266
2272
  if (is("punc", "{") || is("punc", "[")) {
2267
2273
  def = new AST_VarDef({
2268
2274
  start: S.token,
@@ -2282,12 +2288,12 @@ function parse($TEXT, options) {
2282
2288
  });
2283
2289
  if (def.name.name == "import") croak("Unexpected token: import");
2284
2290
  }
2285
- a.push(def);
2291
+ var_defs.push(def);
2286
2292
  if (!is("punc", ","))
2287
2293
  break;
2288
2294
  next();
2289
2295
  }
2290
- return a;
2296
+ return var_defs;
2291
2297
  }
2292
2298
 
2293
2299
  var var_ = function(no_in) {
@@ -2954,9 +2960,10 @@ function parse($TEXT, options) {
2954
2960
  }
2955
2961
 
2956
2962
  function map_name(is_import) {
2957
- function make_symbol(type) {
2963
+ function make_symbol(type, quote) {
2958
2964
  return new type({
2959
2965
  name: as_property_name(),
2966
+ quote: quote || undefined,
2960
2967
  start: prev(),
2961
2968
  end: prev()
2962
2969
  });
@@ -2969,16 +2976,16 @@ function parse($TEXT, options) {
2969
2976
  var name;
2970
2977
 
2971
2978
  if (is_import) {
2972
- foreign_name = make_symbol(foreign_type);
2979
+ foreign_name = make_symbol(foreign_type, start.quote);
2973
2980
  } else {
2974
- name = make_symbol(type);
2981
+ name = make_symbol(type, start.quote);
2975
2982
  }
2976
2983
  if (is("name", "as")) {
2977
2984
  next(); // The "as" word
2978
2985
  if (is_import) {
2979
2986
  name = make_symbol(type);
2980
2987
  } else {
2981
- foreign_name = make_symbol(foreign_type);
2988
+ foreign_name = make_symbol(foreign_type, S.token.quote);
2982
2989
  }
2983
2990
  } else if (is_import) {
2984
2991
  name = new type(foreign_name);
@@ -2994,20 +3001,26 @@ function parse($TEXT, options) {
2994
3001
  });
2995
3002
  }
2996
3003
 
2997
- function map_nameAsterisk(is_import, name) {
3004
+ function map_nameAsterisk(is_import, import_or_export_foreign_name) {
2998
3005
  var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2999
3006
  var type = is_import ? AST_SymbolImport : AST_SymbolExport;
3000
3007
  var start = S.token;
3001
- var foreign_name;
3008
+ var name, foreign_name;
3002
3009
  var end = prev();
3003
3010
 
3011
+ if (is_import) {
3012
+ name = import_or_export_foreign_name;
3013
+ } else {
3014
+ foreign_name = import_or_export_foreign_name;
3015
+ }
3016
+
3004
3017
  name = name || new type({
3005
3018
  start: start,
3006
3019
  name: "*",
3007
3020
  end: end,
3008
3021
  });
3009
3022
 
3010
- foreign_name = new foreign_type({
3023
+ foreign_name = foreign_name || new foreign_type({
3011
3024
  start: start,
3012
3025
  name: "*",
3013
3026
  end: end,
@@ -3036,9 +3049,9 @@ function parse($TEXT, options) {
3036
3049
  } else if (is("operator", "*")) {
3037
3050
  var name;
3038
3051
  next();
3039
- if (is_import && is("name", "as")) {
3052
+ if (is("name", "as")) {
3040
3053
  next(); // The "as" word
3041
- name = as_symbol(is_import ? AST_SymbolImport : AST_SymbolExportForeign);
3054
+ name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
3042
3055
  }
3043
3056
  names = [map_nameAsterisk(is_import, name)];
3044
3057
  }
@@ -3203,6 +3216,27 @@ function parse($TEXT, options) {
3203
3216
  return sym;
3204
3217
  }
3205
3218
 
3219
+ function as_symbol_or_string(type) {
3220
+ if (!is("name")) {
3221
+ if (!is("string")) {
3222
+ croak("Name or string expected");
3223
+ }
3224
+ var tok = S.token;
3225
+ var ret = new type({
3226
+ start : tok,
3227
+ end : tok,
3228
+ name : tok.value,
3229
+ quote : tok.quote
3230
+ });
3231
+ next();
3232
+ return ret;
3233
+ }
3234
+ var sym = _make_symbol(type);
3235
+ _verify_symbol(sym);
3236
+ next();
3237
+ return sym;
3238
+ }
3239
+
3206
3240
  // Annotate AST_Call, AST_Lambda or AST_New with the special comments
3207
3241
  function annotate(node) {
3208
3242
  var start = node.start;
@@ -4565,6 +4599,7 @@ var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) {
4565
4599
  $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
4566
4600
  }, AST_Statement);
4567
4601
 
4602
+ /** Base class for “exits” (`return` and `throw`) */
4568
4603
  var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) {
4569
4604
  if (props) {
4570
4605
  this.value = props.value;
@@ -6159,6 +6194,7 @@ var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, function AST_
6159
6194
  this.scope = props.scope;
6160
6195
  this.name = props.name;
6161
6196
  this.thedef = props.thedef;
6197
+ this.quote = props.quote;
6162
6198
  this.start = props.start;
6163
6199
  this.end = props.end;
6164
6200
  }
@@ -6210,6 +6246,7 @@ var AST_SymbolExport = DEFNODE("SymbolExport", null, function AST_SymbolExport(p
6210
6246
  this.scope = props.scope;
6211
6247
  this.name = props.name;
6212
6248
  this.thedef = props.thedef;
6249
+ this.quote = props.quote;
6213
6250
  this.start = props.start;
6214
6251
  this.end = props.end;
6215
6252
  }
@@ -6224,6 +6261,7 @@ var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", null, function AST_
6224
6261
  this.scope = props.scope;
6225
6262
  this.name = props.name;
6226
6263
  this.thedef = props.thedef;
6264
+ this.quote = props.quote;
6227
6265
  this.start = props.start;
6228
6266
  this.end = props.end;
6229
6267
  }
@@ -7369,24 +7407,11 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7369
7407
  var imported_name = null;
7370
7408
  var imported_names = null;
7371
7409
  M.specifiers.forEach(function (specifier) {
7372
- if (specifier.type === "ImportSpecifier") {
7410
+ if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") {
7373
7411
  if (!imported_names) { imported_names = []; }
7374
- imported_names.push(new AST_NameMapping({
7375
- start: my_start_token(specifier),
7376
- end: my_end_token(specifier),
7377
- foreign_name: from_moz(specifier.imported),
7378
- name: from_moz(specifier.local)
7379
- }));
7412
+ imported_names.push(from_moz(specifier));
7380
7413
  } else if (specifier.type === "ImportDefaultSpecifier") {
7381
- imported_name = from_moz(specifier.local);
7382
- } else if (specifier.type === "ImportNamespaceSpecifier") {
7383
- if (!imported_names) { imported_names = []; }
7384
- imported_names.push(new AST_NameMapping({
7385
- start: my_start_token(specifier),
7386
- end: my_end_token(specifier),
7387
- foreign_name: new AST_SymbolImportForeign({ name: "*" }),
7388
- name: from_moz(specifier.local)
7389
- }));
7414
+ imported_name = from_moz(specifier);
7390
7415
  }
7391
7416
  });
7392
7417
  return new AST_Import({
@@ -7399,14 +7424,39 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7399
7424
  });
7400
7425
  },
7401
7426
 
7427
+ ImportSpecifier: function(M) {
7428
+ return new AST_NameMapping({
7429
+ start: my_start_token(M),
7430
+ end: my_end_token(M),
7431
+ foreign_name: from_moz(M.imported),
7432
+ name: from_moz(M.local)
7433
+ });
7434
+ },
7435
+
7436
+ ImportDefaultSpecifier: function(M) {
7437
+ return from_moz(M.local);
7438
+ },
7439
+
7440
+ ImportNamespaceSpecifier: function(M) {
7441
+ return new AST_NameMapping({
7442
+ start: my_start_token(M),
7443
+ end: my_end_token(M),
7444
+ foreign_name: new AST_SymbolImportForeign({ name: "*" }),
7445
+ name: from_moz(M.local)
7446
+ });
7447
+ },
7448
+
7402
7449
  ExportAllDeclaration: function(M) {
7450
+ var foreign_name = M.exported == null ?
7451
+ new AST_SymbolExportForeign({ name: "*" }) :
7452
+ from_moz(M.exported);
7403
7453
  return new AST_Export({
7404
7454
  start: my_start_token(M),
7405
7455
  end: my_end_token(M),
7406
7456
  exported_names: [
7407
7457
  new AST_NameMapping({
7408
7458
  name: new AST_SymbolExportForeign({ name: "*" }),
7409
- foreign_name: new AST_SymbolExportForeign({ name: "*" })
7459
+ foreign_name: foreign_name
7410
7460
  })
7411
7461
  ],
7412
7462
  module_name: from_moz(M.source),
@@ -7420,10 +7470,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7420
7470
  end: my_end_token(M),
7421
7471
  exported_definition: from_moz(M.declaration),
7422
7472
  exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(function (specifier) {
7423
- return new AST_NameMapping({
7424
- foreign_name: from_moz(specifier.exported),
7425
- name: from_moz(specifier.local)
7426
- });
7473
+ return from_moz(specifier);
7427
7474
  }) : null,
7428
7475
  module_name: from_moz(M.source),
7429
7476
  assert_clause: assert_clause_from_moz(M.assertions)
@@ -7439,6 +7486,13 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7439
7486
  });
7440
7487
  },
7441
7488
 
7489
+ ExportSpecifier: function(M) {
7490
+ return new AST_NameMapping({
7491
+ foreign_name: from_moz(M.exported),
7492
+ name: from_moz(M.local)
7493
+ });
7494
+ },
7495
+
7442
7496
  Literal: function(M) {
7443
7497
  var val = M.value, args = {
7444
7498
  start : my_start_token(M),
@@ -7464,6 +7518,22 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7464
7518
  if (val === null) return new AST_Null(args);
7465
7519
  switch (typeof val) {
7466
7520
  case "string":
7521
+ args.quote = "\"";
7522
+ var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
7523
+ if (p.type == "ImportSpecifier") {
7524
+ args.name = val;
7525
+ return new AST_SymbolImportForeign(args);
7526
+ } else if (p.type == "ExportSpecifier") {
7527
+ args.name = val;
7528
+ if (M == p.exported) {
7529
+ return new AST_SymbolExportForeign(args);
7530
+ } else {
7531
+ return new AST_SymbolExport(args);
7532
+ }
7533
+ } else if (p.type == "ExportAllDeclaration" && M == p.exported) {
7534
+ args.name = val;
7535
+ return new AST_SymbolExportForeign(args);
7536
+ }
7467
7537
  args.value = val;
7468
7538
  return new AST_String(args);
7469
7539
  case "number":
@@ -8168,10 +8238,17 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8168
8238
 
8169
8239
  def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
8170
8240
  if (M.exported_names) {
8171
- if (M.exported_names[0].name.name === "*") {
8241
+ var first_exported = M.exported_names[0];
8242
+ var first_exported_name = first_exported.name;
8243
+ if (first_exported_name.name === "*" && !first_exported_name.quote) {
8244
+ var foreign_name = first_exported.foreign_name;
8245
+ var exported = foreign_name.name === "*" && !foreign_name.quote
8246
+ ? null
8247
+ : to_moz(foreign_name);
8172
8248
  return {
8173
8249
  type: "ExportAllDeclaration",
8174
8250
  source: to_moz(M.module_name),
8251
+ exported: exported,
8175
8252
  assertions: assert_clause_to_moz(M.assert_clause)
8176
8253
  };
8177
8254
  }
@@ -8203,19 +8280,22 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8203
8280
  local: to_moz(M.imported_name)
8204
8281
  });
8205
8282
  }
8206
- if (M.imported_names && M.imported_names[0].foreign_name.name === "*") {
8207
- specifiers.push({
8208
- type: "ImportNamespaceSpecifier",
8209
- local: to_moz(M.imported_names[0].name)
8210
- });
8211
- } else if (M.imported_names) {
8212
- M.imported_names.forEach(function(name_mapping) {
8283
+ if (M.imported_names) {
8284
+ var first_imported_foreign_name = M.imported_names[0].foreign_name;
8285
+ if (first_imported_foreign_name.name === "*" && !first_imported_foreign_name.quote) {
8213
8286
  specifiers.push({
8214
- type: "ImportSpecifier",
8215
- local: to_moz(name_mapping.name),
8216
- imported: to_moz(name_mapping.foreign_name)
8287
+ type: "ImportNamespaceSpecifier",
8288
+ local: to_moz(M.imported_names[0].name)
8217
8289
  });
8218
- });
8290
+ } else {
8291
+ M.imported_names.forEach(function(name_mapping) {
8292
+ specifiers.push({
8293
+ type: "ImportSpecifier",
8294
+ local: to_moz(name_mapping.name),
8295
+ imported: to_moz(name_mapping.foreign_name)
8296
+ });
8297
+ });
8298
+ }
8219
8299
  }
8220
8300
  return {
8221
8301
  type: "ImportDeclaration",
@@ -8479,7 +8559,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8479
8559
  });
8480
8560
 
8481
8561
  def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
8482
- if (M instanceof AST_SymbolMethod && parent.quote) {
8562
+ if (
8563
+ (M instanceof AST_SymbolMethod && parent.quote) ||
8564
+ ((
8565
+ M instanceof AST_SymbolImportForeign ||
8566
+ M instanceof AST_SymbolExportForeign ||
8567
+ M instanceof AST_SymbolExport
8568
+ ) && M.quote)
8569
+ ) {
8483
8570
  return {
8484
8571
  type: "Literal",
8485
8572
  value: M.name
@@ -9791,7 +9878,7 @@ function OutputStream(options) {
9791
9878
  }
9792
9879
 
9793
9880
  AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
9794
- force_statement(this.body, output);
9881
+ print_maybe_braced_body(this.body, output);
9795
9882
  });
9796
9883
 
9797
9884
  DEFPRINT(AST_Statement, function(self, output) {
@@ -10120,7 +10207,7 @@ function OutputStream(options) {
10120
10207
  b = b.body;
10121
10208
  } else break;
10122
10209
  }
10123
- force_statement(self.body, output);
10210
+ print_maybe_braced_body(self.body, output);
10124
10211
  }
10125
10212
  DEFPRINT(AST_If, function(self, output) {
10126
10213
  output.print("if");
@@ -10137,7 +10224,7 @@ function OutputStream(options) {
10137
10224
  if (self.alternative instanceof AST_If)
10138
10225
  self.alternative.print(output);
10139
10226
  else
10140
- force_statement(self.alternative, output);
10227
+ print_maybe_braced_body(self.alternative, output);
10141
10228
  } else {
10142
10229
  self._do_print_body(output);
10143
10230
  }
@@ -10247,7 +10334,9 @@ function OutputStream(options) {
10247
10334
  output.space();
10248
10335
  }
10249
10336
  if (self.imported_names) {
10250
- if (self.imported_names.length === 1 && self.imported_names[0].foreign_name.name === "*") {
10337
+ if (self.imported_names.length === 1 &&
10338
+ self.imported_names[0].foreign_name.name === "*" &&
10339
+ !self.imported_names[0].foreign_name.quote) {
10251
10340
  self.imported_names[0].print(output);
10252
10341
  } else {
10253
10342
  output.print("{");
@@ -10281,14 +10370,31 @@ function OutputStream(options) {
10281
10370
  DEFPRINT(AST_NameMapping, function(self, output) {
10282
10371
  var is_import = output.parent() instanceof AST_Import;
10283
10372
  var definition = self.name.definition();
10373
+ var foreign_name = self.foreign_name;
10284
10374
  var names_are_different =
10285
10375
  (definition && definition.mangled_name || self.name.name) !==
10286
- self.foreign_name.name;
10376
+ foreign_name.name;
10377
+ if (!names_are_different &&
10378
+ foreign_name.name === "*" &&
10379
+ foreign_name.quote != self.name.quote) {
10380
+ // export * as "*"
10381
+ names_are_different = true;
10382
+ }
10383
+ var foreign_name_is_name = foreign_name.quote == null;
10287
10384
  if (names_are_different) {
10288
10385
  if (is_import) {
10289
- output.print(self.foreign_name.name);
10386
+ if (foreign_name_is_name) {
10387
+ output.print(foreign_name.name);
10388
+ } else {
10389
+ output.print_string(foreign_name.name, foreign_name.quote);
10390
+ }
10290
10391
  } else {
10291
- self.name.print(output);
10392
+ if (self.name.quote == null) {
10393
+ self.name.print(output);
10394
+ } else {
10395
+ output.print_string(self.name.name, self.name.quote);
10396
+ }
10397
+
10292
10398
  }
10293
10399
  output.space();
10294
10400
  output.print("as");
@@ -10296,10 +10402,18 @@ function OutputStream(options) {
10296
10402
  if (is_import) {
10297
10403
  self.name.print(output);
10298
10404
  } else {
10299
- output.print(self.foreign_name.name);
10405
+ if (foreign_name_is_name) {
10406
+ output.print(foreign_name.name);
10407
+ } else {
10408
+ output.print_string(foreign_name.name, foreign_name.quote);
10409
+ }
10300
10410
  }
10301
10411
  } else {
10302
- self.name.print(output);
10412
+ if (self.name.quote == null) {
10413
+ self.name.print(output);
10414
+ } else {
10415
+ output.print_string(self.name.name, self.name.quote);
10416
+ }
10303
10417
  }
10304
10418
  });
10305
10419
 
@@ -10311,8 +10425,10 @@ function OutputStream(options) {
10311
10425
  output.space();
10312
10426
  }
10313
10427
  if (self.exported_names) {
10314
- if (self.exported_names.length === 1 && self.exported_names[0].name.name === "*") {
10315
- self.exported_names[0].print(output);
10428
+ if (self.exported_names.length === 1 &&
10429
+ self.exported_names[0].name.name === "*" &&
10430
+ !self.exported_names[0].name.quote) {
10431
+ self.exported_names[0].print(output);
10316
10432
  } else {
10317
10433
  output.print("{");
10318
10434
  self.exported_names.forEach(function(name_export, i) {
@@ -10832,12 +10948,15 @@ function OutputStream(options) {
10832
10948
  }
10833
10949
  });
10834
10950
 
10835
- function force_statement(stat, output) {
10951
+ /** if, for, while, may or may not have braces surrounding its body */
10952
+ function print_maybe_braced_body(stat, output) {
10836
10953
  if (output.option("braces")) {
10837
10954
  make_block(stat, output);
10838
10955
  } else {
10839
10956
  if (!stat || stat instanceof AST_EmptyStatement)
10840
10957
  output.force_semicolon();
10958
+ else if (stat instanceof AST_Let || stat instanceof AST_Const || stat instanceof AST_Class)
10959
+ make_block(stat, output);
10841
10960
  else
10842
10961
  stat.print(output);
10843
10962
  }
@@ -11331,8 +11450,9 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
11331
11450
  scope.init_scope_vars(parent_scope);
11332
11451
  scope.uses_with = save_scope.uses_with;
11333
11452
  scope.uses_eval = save_scope.uses_eval;
11453
+
11334
11454
  if (options.safari10) {
11335
- if (node instanceof AST_For || node instanceof AST_ForIn) {
11455
+ if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) {
11336
11456
  for_scopes.push(scope);
11337
11457
  }
11338
11458
  }
@@ -12828,9 +12948,10 @@ function is_func_expr(node) {
12828
12948
  return node instanceof AST_Arrow || node instanceof AST_Function;
12829
12949
  }
12830
12950
 
12951
+ /**
12952
+ * Used to determine whether the node can benefit from negation.
12953
+ * Not the case with arrow functions (you need an extra set of parens). */
12831
12954
  function is_iife_call(node) {
12832
- // Used to determine whether the node can benefit from negation.
12833
- // Not the case with arrow functions (you need an extra set of parens).
12834
12955
  if (node.TYPE != "Call") return false;
12835
12956
  return node.expression instanceof AST_Function || is_iife_call(node.expression);
12836
12957
  }
@@ -13010,6 +13131,9 @@ const object_methods = [
13010
13131
 
13011
13132
  const is_pure_native_method = make_nested_lookup({
13012
13133
  Array: [
13134
+ "at",
13135
+ "flat",
13136
+ "includes",
13013
13137
  "indexOf",
13014
13138
  "join",
13015
13139
  "lastIndexOf",
@@ -13030,22 +13154,41 @@ const is_pure_native_method = make_nested_lookup({
13030
13154
  ...object_methods,
13031
13155
  ],
13032
13156
  String: [
13157
+ "at",
13033
13158
  "charAt",
13034
13159
  "charCodeAt",
13160
+ "charPointAt",
13035
13161
  "concat",
13162
+ "endsWith",
13163
+ "fromCharCode",
13164
+ "fromCodePoint",
13165
+ "includes",
13036
13166
  "indexOf",
13037
13167
  "italics",
13038
13168
  "lastIndexOf",
13169
+ "localeCompare",
13039
13170
  "match",
13171
+ "matchAll",
13172
+ "normalize",
13173
+ "padStart",
13174
+ "padEnd",
13175
+ "repeat",
13040
13176
  "replace",
13177
+ "replaceAll",
13041
13178
  "search",
13042
13179
  "slice",
13043
13180
  "split",
13181
+ "startsWith",
13044
13182
  "substr",
13045
13183
  "substring",
13184
+ "repeat",
13185
+ "toLocaleLowerCase",
13186
+ "toLocaleUpperCase",
13046
13187
  "toLowerCase",
13047
13188
  "toUpperCase",
13048
13189
  "trim",
13190
+ "trimEnd",
13191
+ "trimStart",
13049
13192
  ...object_methods,
13050
13193
  ],
13051
13194
  });
@@ -17085,14 +17228,21 @@ function tighten_body(statements, compressor) {
17085
17228
  CHANGED = true;
17086
17229
  stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
17087
17230
  statements[++j] = stat;
17088
- } else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
17231
+ } else if (
17232
+ prev instanceof AST_Var
17233
+ && (!stat.init || stat.init.TYPE == prev.TYPE)
17234
+ ) {
17089
17235
  if (stat.init) {
17090
17236
  prev.definitions = prev.definitions.concat(stat.init.definitions);
17091
17237
  }
17092
17238
  stat.init = prev;
17093
17239
  statements[j] = stat;
17094
17240
  CHANGED = true;
17095
- } else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) {
17241
+ } else if (
17242
+ defs instanceof AST_Var
17243
+ && stat.init instanceof AST_Var
17244
+ && declarations_only(stat.init)
17245
+ ) {
17096
17246
  defs.definitions = defs.definitions.concat(stat.init.definitions);
17097
17247
  stat.init = null;
17098
17248
  statements[++j] = stat;
@@ -29543,12 +29693,15 @@ function mangle_properties(ast, options) {
29543
29693
  }
29544
29694
  }
29545
29695
 
29546
- var to_ascii = typeof atob == "undefined" ? function(b64) {
29547
- return Buffer.from(b64, "base64").toString();
29548
- } : atob;
29549
- var to_base64 = typeof btoa == "undefined" ? function(str) {
29550
- return Buffer.from(str).toString("base64");
29551
- } : btoa;
29696
+ // to/from base64 functions
29697
+ // Prefer built-in Buffer, if available, then use hack
29698
+ // https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem
29699
+ var to_ascii = typeof Buffer !== "undefined"
29700
+ ? (b64) => Buffer.from(b64, "base64").toString()
29701
+ : (b64) => decodeURIComponent(escape(atob(b64)));
29702
+ var to_base64 = typeof Buffer !== "undefined"
29703
+ ? (str) => Buffer.from(str).toString("base64")
29704
+ : (str) => btoa(unescape(encodeURIComponent(str)));
29552
29705
 
29553
29706
  function read_source_map(code) {
29554
29707
  var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
package/lib/ast.js CHANGED
@@ -994,6 +994,7 @@ var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) {
994
994
  $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
995
995
  }, AST_Statement);
996
996
 
997
+ /** Base class for “exits” (`return` and `throw`) */
997
998
  var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) {
998
999
  if (props) {
999
1000
  this.value = props.value;
@@ -2588,6 +2589,7 @@ var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, function AST_
2588
2589
  this.scope = props.scope;
2589
2590
  this.name = props.name;
2590
2591
  this.thedef = props.thedef;
2592
+ this.quote = props.quote;
2591
2593
  this.start = props.start;
2592
2594
  this.end = props.end;
2593
2595
  }
@@ -2639,6 +2641,7 @@ var AST_SymbolExport = DEFNODE("SymbolExport", null, function AST_SymbolExport(p
2639
2641
  this.scope = props.scope;
2640
2642
  this.name = props.name;
2641
2643
  this.thedef = props.thedef;
2644
+ this.quote = props.quote;
2642
2645
  this.start = props.start;
2643
2646
  this.end = props.end;
2644
2647
  }
@@ -2653,6 +2656,7 @@ var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", null, function AST_
2653
2656
  this.scope = props.scope;
2654
2657
  this.name = props.name;
2655
2658
  this.thedef = props.thedef;
2659
+ this.quote = props.quote;
2656
2660
  this.start = props.start;
2657
2661
  this.end = props.end;
2658
2662
  }
@@ -241,9 +241,10 @@ export function is_func_expr(node) {
241
241
  return node instanceof AST_Arrow || node instanceof AST_Function;
242
242
  }
243
243
 
244
+ /**
245
+ * Used to determine whether the node can benefit from negation.
246
+ * Not the case with arrow functions (you need an extra set of parens). */
244
247
  export function is_iife_call(node) {
245
- // Used to determine whether the node can benefit from negation.
246
- // Not the case with arrow functions (you need an extra set of parens).
247
248
  if (node.TYPE != "Call") return false;
248
249
  return node.expression instanceof AST_Function || is_iife_call(node.expression);
249
250
  }
@@ -79,6 +79,9 @@ const object_methods = [
79
79
 
80
80
  export const is_pure_native_method = make_nested_lookup({
81
81
  Array: [
82
+ "at",
83
+ "flat",
84
+ "includes",
82
85
  "indexOf",
83
86
  "join",
84
87
  "lastIndexOf",
@@ -99,22 +102,41 @@ export const is_pure_native_method = make_nested_lookup({
99
102
  ...object_methods,
100
103
  ],
101
104
  String: [
105
+ "at",
102
106
  "charAt",
103
107
  "charCodeAt",
108
+ "charPointAt",
104
109
  "concat",
110
+ "endsWith",
111
+ "fromCharCode",
112
+ "fromCodePoint",
113
+ "includes",
105
114
  "indexOf",
106
115
  "italics",
107
116
  "lastIndexOf",
117
+ "localeCompare",
108
118
  "match",
119
+ "matchAll",
120
+ "normalize",
121
+ "padStart",
122
+ "padEnd",
123
+ "repeat",
109
124
  "replace",
125
+ "replaceAll",
110
126
  "search",
111
127
  "slice",
112
128
  "split",
129
+ "startsWith",
113
130
  "substr",
114
131
  "substring",
132
+ "repeat",
133
+ "toLocaleLowerCase",
134
+ "toLocaleUpperCase",
115
135
  "toLowerCase",
116
136
  "toUpperCase",
117
137
  "trim",
138
+ "trimEnd",
139
+ "trimStart",
118
140
  ...object_methods,
119
141
  ],
120
142
  });
@@ -1404,14 +1404,21 @@ export function tighten_body(statements, compressor) {
1404
1404
  CHANGED = true;
1405
1405
  stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
1406
1406
  statements[++j] = stat;
1407
- } else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
1407
+ } else if (
1408
+ prev instanceof AST_Var
1409
+ && (!stat.init || stat.init.TYPE == prev.TYPE)
1410
+ ) {
1408
1411
  if (stat.init) {
1409
1412
  prev.definitions = prev.definitions.concat(stat.init.definitions);
1410
1413
  }
1411
1414
  stat.init = prev;
1412
1415
  statements[j] = stat;
1413
1416
  CHANGED = true;
1414
- } else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) {
1417
+ } else if (
1418
+ defs instanceof AST_Var
1419
+ && stat.init instanceof AST_Var
1420
+ && declarations_only(stat.init)
1421
+ ) {
1415
1422
  defs.definitions = defs.definitions.concat(stat.init.definitions);
1416
1423
  stat.init = null;
1417
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
- var to_ascii = typeof atob == "undefined" ? function(b64) {
23
- return Buffer.from(b64, "base64").toString();
24
- } : atob;
25
- var to_base64 = typeof btoa == "undefined" ? function(str) {
26
- return Buffer.from(str).toString("base64");
27
- } : btoa;
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);
@@ -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(new AST_NameMapping({
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.local);
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: new AST_SymbolExportForeign({ 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 new AST_NameMapping({
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
- if (M.exported_names[0].name.name === "*") {
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 && M.imported_names[0].foreign_name.name === "*") {
1367
- specifiers.push({
1368
- type: "ImportNamespaceSpecifier",
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: "ImportSpecifier",
1375
- local: to_moz(name_mapping.name),
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 (M instanceof AST_SymbolMethod && parent.quote) {
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
- force_statement(this.body, output);
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
- force_statement(self.body, output);
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
- force_statement(self.alternative, output);
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 && self.imported_names[0].foreign_name.name === "*") {
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
- self.foreign_name.name;
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
- output.print(self.foreign_name.name);
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.print(output);
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
- output.print(self.foreign_name.name);
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.print(output);
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 && self.exported_names[0].name.name === "*") {
1749
- self.exported_names[0].print(output);
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
- function force_statement(stat, output) {
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 a = [];
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
- a.push(def);
2125
+ var_defs.push(def);
2120
2126
  if (!is("punc", ","))
2121
2127
  break;
2122
2128
  next();
2123
2129
  }
2124
- return a;
2130
+ return var_defs;
2125
2131
  }
2126
2132
 
2127
2133
  var var_ = function(no_in) {
@@ -2788,9 +2794,10 @@ function parse($TEXT, options) {
2788
2794
  }
2789
2795
 
2790
2796
  function map_name(is_import) {
2791
- function make_symbol(type) {
2797
+ function make_symbol(type, quote) {
2792
2798
  return new type({
2793
2799
  name: as_property_name(),
2800
+ quote: quote || undefined,
2794
2801
  start: prev(),
2795
2802
  end: prev()
2796
2803
  });
@@ -2803,16 +2810,16 @@ function parse($TEXT, options) {
2803
2810
  var name;
2804
2811
 
2805
2812
  if (is_import) {
2806
- foreign_name = make_symbol(foreign_type);
2813
+ foreign_name = make_symbol(foreign_type, start.quote);
2807
2814
  } else {
2808
- name = make_symbol(type);
2815
+ name = make_symbol(type, start.quote);
2809
2816
  }
2810
2817
  if (is("name", "as")) {
2811
2818
  next(); // The "as" word
2812
2819
  if (is_import) {
2813
2820
  name = make_symbol(type);
2814
2821
  } else {
2815
- foreign_name = make_symbol(foreign_type);
2822
+ foreign_name = make_symbol(foreign_type, S.token.quote);
2816
2823
  }
2817
2824
  } else if (is_import) {
2818
2825
  name = new type(foreign_name);
@@ -2828,20 +2835,26 @@ function parse($TEXT, options) {
2828
2835
  });
2829
2836
  }
2830
2837
 
2831
- function map_nameAsterisk(is_import, name) {
2838
+ function map_nameAsterisk(is_import, import_or_export_foreign_name) {
2832
2839
  var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2833
2840
  var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2834
2841
  var start = S.token;
2835
- var foreign_name;
2842
+ var name, foreign_name;
2836
2843
  var end = prev();
2837
2844
 
2845
+ if (is_import) {
2846
+ name = import_or_export_foreign_name;
2847
+ } else {
2848
+ foreign_name = import_or_export_foreign_name;
2849
+ }
2850
+
2838
2851
  name = name || new type({
2839
2852
  start: start,
2840
2853
  name: "*",
2841
2854
  end: end,
2842
2855
  });
2843
2856
 
2844
- foreign_name = new foreign_type({
2857
+ foreign_name = foreign_name || new foreign_type({
2845
2858
  start: start,
2846
2859
  name: "*",
2847
2860
  end: end,
@@ -2870,9 +2883,9 @@ function parse($TEXT, options) {
2870
2883
  } else if (is("operator", "*")) {
2871
2884
  var name;
2872
2885
  next();
2873
- if (is_import && is("name", "as")) {
2886
+ if (is("name", "as")) {
2874
2887
  next(); // The "as" word
2875
- name = as_symbol(is_import ? AST_SymbolImport : AST_SymbolExportForeign);
2888
+ name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
2876
2889
  }
2877
2890
  names = [map_nameAsterisk(is_import, name)];
2878
2891
  }
@@ -3037,6 +3050,27 @@ function parse($TEXT, options) {
3037
3050
  return sym;
3038
3051
  }
3039
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
+
3040
3074
  // Annotate AST_Call, AST_Lambda or AST_New with the special comments
3041
3075
  function annotate(node) {
3042
3076
  var start = node.start;
package/lib/scope.js CHANGED
@@ -69,6 +69,7 @@ import {
69
69
  AST_Export,
70
70
  AST_For,
71
71
  AST_ForIn,
72
+ AST_ForOf,
72
73
  AST_Function,
73
74
  AST_Import,
74
75
  AST_IterationStatement,
@@ -230,8 +231,9 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
230
231
  scope.init_scope_vars(parent_scope);
231
232
  scope.uses_with = save_scope.uses_with;
232
233
  scope.uses_eval = save_scope.uses_eval;
234
+
233
235
  if (options.safari10) {
234
- if (node instanceof AST_For || node instanceof AST_ForIn) {
236
+ if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) {
235
237
  for_scopes.push(scope);
236
238
  }
237
239
  }
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.16.1",
7
+ "version": "5.16.2",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },
package/tools/terser.d.ts CHANGED
@@ -204,6 +204,7 @@ export interface SourceMapOptions {
204
204
  includeSources?: boolean;
205
205
  filename?: string;
206
206
  root?: string;
207
+ asObject?: boolean;
207
208
  url?: string | 'inline';
208
209
  }
209
210
 
package/bin/terser.mjs DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- "use strict";
4
-
5
- import "../tools/exit.cjs";
6
-
7
- import fs from "fs"
8
- import path from "path"
9
- import program from "commander"
10
-
11
- import { run_cli } from "../lib/cli.js"
12
-
13
- const packageJson = {
14
- name: "terser",
15
- version: "experimental module CLI"
16
- }
17
-
18
- run_cli({ program, packageJson, fs, path }).catch((error) => {
19
- console.error(error);
20
- process.exitCode = 1;
21
- });