terser 5.7.2 → 5.11.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.
@@ -321,7 +321,9 @@ export function tighten_body(statements, compressor) {
321
321
  // Replace variable with assignment when found
322
322
  if (can_replace
323
323
  && !(node instanceof AST_SymbolDeclaration)
324
- && lhs.equivalent_to(node)) {
324
+ && lhs.equivalent_to(node)
325
+ && !shadows(node.scope, lvalues)
326
+ ) {
325
327
  if (stop_if_hit) {
326
328
  abort = true;
327
329
  return node;
@@ -369,7 +371,7 @@ export function tighten_body(statements, compressor) {
369
371
  || node instanceof AST_PropAccess
370
372
  && (side_effects || node.expression.may_throw_on_access(compressor))
371
373
  || node instanceof AST_SymbolRef
372
- && (lvalues.get(node.name) || side_effects && may_modify(node))
374
+ && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node))
373
375
  || node instanceof AST_VarDef && node.value
374
376
  && (lvalues.has(node.name.name) || side_effects && may_modify(node.name))
375
377
  || (sym = is_lhs(node.left, node))
@@ -442,8 +444,9 @@ export function tighten_body(statements, compressor) {
442
444
  // Locate symbols which may execute code outside of scanning range
443
445
  var lvalues = get_lvalues(candidate);
444
446
  var lhs_local = is_lhs_local(lhs);
445
- if (lhs instanceof AST_SymbolRef)
446
- lvalues.set(lhs.name, false);
447
+ if (lhs instanceof AST_SymbolRef) {
448
+ lvalues.set(lhs.name, { def: lhs.definition(), modified: false });
449
+ }
447
450
  var side_effects = value_has_side_effects(candidate);
448
451
  var replace_all = replace_all_symbols();
449
452
  var may_throw = candidate.may_throw(compressor);
@@ -509,8 +512,9 @@ export function tighten_body(statements, compressor) {
509
512
  return false;
510
513
  let cur_scope = def.scope;
511
514
  while (cur_scope && cur_scope !== scope) {
512
- if (cur_scope.variables.has(def.name))
515
+ if (cur_scope.variables.has(def.name)) {
513
516
  return true;
517
+ }
514
518
  cur_scope = cur_scope.parent_scope;
515
519
  }
516
520
  return false;
@@ -791,8 +795,14 @@ export function tighten_body(statements, compressor) {
791
795
  var sym = node;
792
796
  while (sym instanceof AST_PropAccess)
793
797
  sym = sym.expression;
794
- if (sym instanceof AST_SymbolRef || sym instanceof AST_This) {
795
- lvalues.set(sym.name, lvalues.get(sym.name) || is_modified(compressor, tw, node, node, 0));
798
+ if (sym instanceof AST_SymbolRef) {
799
+ const prev = lvalues.get(sym.name);
800
+ if (!prev || !prev.modified) {
801
+ lvalues.set(sym.name, {
802
+ def: sym.definition(),
803
+ modified: is_modified(compressor, tw, node, node, 0)
804
+ });
805
+ }
796
806
  }
797
807
  });
798
808
  get_rvalue(expr).walk(tw);
@@ -904,6 +914,18 @@ export function tighten_body(statements, compressor) {
904
914
  }
905
915
  return false;
906
916
  }
917
+
918
+ function shadows(newScope, lvalues) {
919
+ for (const {def} of lvalues.values()) {
920
+ let current = newScope;
921
+ while (current && current !== def.scope) {
922
+ let nested_def = current.variables.get(def.name);
923
+ if (nested_def && nested_def !== def) return true;
924
+ current = current.parent_scope;
925
+ }
926
+ }
927
+ return false;
928
+ }
907
929
  }
908
930
 
909
931
  function eliminate_spurious_blocks(statements) {
package/lib/minify.js CHANGED
@@ -15,6 +15,7 @@ import { base54 } from "./scope.js";
15
15
  import { SourceMap } from "./sourcemap.js";
16
16
  import {
17
17
  mangle_properties,
18
+ mangle_private_properties,
18
19
  reserve_quoted_keys,
19
20
  } from "./propmangle.js";
20
21
 
@@ -113,6 +114,7 @@ async function minify(files, options) {
113
114
  keep_classnames: false,
114
115
  keep_fnames: false,
115
116
  module: false,
117
+ nth_identifier: base54,
116
118
  properties: false,
117
119
  reserved: [],
118
120
  safari10: false,
@@ -203,9 +205,9 @@ async function minify(files, options) {
203
205
  if (options.mangle) toplevel.figure_out_scope(options.mangle);
204
206
  if (timings) timings.mangle = Date.now();
205
207
  if (options.mangle) {
206
- base54.reset();
207
208
  toplevel.compute_char_frequency(options.mangle);
208
209
  toplevel.mangle_names(options.mangle);
210
+ toplevel = mangle_private_properties(toplevel, options.mangle);
209
211
  }
210
212
  if (timings) timings.properties = Date.now();
211
213
  if (options.mangle && options.mangle.properties) {
@@ -158,6 +158,7 @@ import {
158
158
  AST_With,
159
159
  AST_Yield,
160
160
  } from "./ast.js";
161
+ import { is_basic_identifier_string } from "./parse.js";
161
162
 
162
163
  (function() {
163
164
 
@@ -179,6 +180,24 @@ import {
179
180
  return body;
180
181
  };
181
182
 
183
+ const assert_clause_from_moz = (assertions) => {
184
+ if (assertions && assertions.length > 0) {
185
+ return new AST_Object({
186
+ start: my_start_token(assertions),
187
+ end: my_end_token(assertions),
188
+ properties: assertions.map((assertion_kv) =>
189
+ new AST_ObjectKeyVal({
190
+ start: my_start_token(assertion_kv),
191
+ end: my_end_token(assertion_kv),
192
+ key: assertion_kv.key.name || assertion_kv.key.value,
193
+ value: from_moz(assertion_kv.value)
194
+ })
195
+ )
196
+ });
197
+ }
198
+ return null;
199
+ };
200
+
182
201
  var MOZ_TO_ME = {
183
202
  Program: function(M) {
184
203
  return new AST_Toplevel({
@@ -499,7 +518,8 @@ import {
499
518
  end : my_end_token(M),
500
519
  imported_name: imported_name,
501
520
  imported_names : imported_names,
502
- module_name : from_moz(M.source)
521
+ module_name : from_moz(M.source),
522
+ assert_clause: assert_clause_from_moz(M.assertions)
503
523
  });
504
524
  },
505
525
  ExportAllDeclaration: function(M) {
@@ -512,7 +532,8 @@ import {
512
532
  foreign_name: new AST_SymbolExportForeign({ name: "*" })
513
533
  })
514
534
  ],
515
- module_name: from_moz(M.source)
535
+ module_name: from_moz(M.source),
536
+ assert_clause: assert_clause_from_moz(M.assertions)
516
537
  });
517
538
  },
518
539
  ExportNamedDeclaration: function(M) {
@@ -526,7 +547,8 @@ import {
526
547
  name: from_moz(specifier.local)
527
548
  });
528
549
  }) : null,
529
- module_name: from_moz(M.source)
550
+ module_name: from_moz(M.source),
551
+ assert_clause: assert_clause_from_moz(M.assertions)
530
552
  });
531
553
  },
532
554
  ExportDefaultDeclaration: function(M) {
@@ -818,12 +840,30 @@ import {
818
840
  };
819
841
  });
820
842
 
843
+ const assert_clause_to_moz = assert_clause => {
844
+ const assertions = [];
845
+ if (assert_clause) {
846
+ for (const { key, value } of assert_clause.properties) {
847
+ const key_moz = is_basic_identifier_string(key)
848
+ ? { type: "Identifier", name: key }
849
+ : { type: "Literal", value: key, raw: JSON.stringify(key) };
850
+ assertions.push({
851
+ type: "ImportAttribute",
852
+ key: key_moz,
853
+ value: to_moz(value)
854
+ });
855
+ }
856
+ }
857
+ return assertions;
858
+ };
859
+
821
860
  def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
822
861
  if (M.exported_names) {
823
862
  if (M.exported_names[0].name.name === "*") {
824
863
  return {
825
864
  type: "ExportAllDeclaration",
826
- source: to_moz(M.module_name)
865
+ source: to_moz(M.module_name),
866
+ assertions: assert_clause_to_moz(M.assert_clause)
827
867
  };
828
868
  }
829
869
  return {
@@ -836,7 +876,8 @@ import {
836
876
  };
837
877
  }),
838
878
  declaration: to_moz(M.exported_definition),
839
- source: to_moz(M.module_name)
879
+ source: to_moz(M.module_name),
880
+ assertions: assert_clause_to_moz(M.assert_clause)
840
881
  };
841
882
  }
842
883
  return {
@@ -870,7 +911,8 @@ import {
870
911
  return {
871
912
  type: "ImportDeclaration",
872
913
  specifiers: specifiers,
873
- source: to_moz(M.module_name)
914
+ source: to_moz(M.module_name),
915
+ assertions: assert_clause_to_moz(M.assert_clause)
874
916
  };
875
917
  });
876
918
 
package/lib/output.js CHANGED
@@ -176,6 +176,48 @@ function is_some_comments(comment) {
176
176
  );
177
177
  }
178
178
 
179
+ class Rope {
180
+ constructor() {
181
+ this.committed = "";
182
+ this.current = "";
183
+ }
184
+
185
+ append(str) {
186
+ this.current += str;
187
+ }
188
+
189
+ insertAt(char, index) {
190
+ const { committed, current } = this;
191
+ if (index < committed.length) {
192
+ this.committed = committed.slice(0, index) + char + committed.slice(index);
193
+ } else if (index === committed.length) {
194
+ this.committed += char;
195
+ } else {
196
+ index -= committed.length;
197
+ this.committed += current.slice(0, index) + char;
198
+ this.current = current.slice(index);
199
+ }
200
+ }
201
+
202
+ charAt(index) {
203
+ const { committed } = this;
204
+ if (index < committed.length) return committed[index];
205
+ return this.current[index - committed.length];
206
+ }
207
+
208
+ curLength() {
209
+ return this.current.length;
210
+ }
211
+
212
+ length() {
213
+ return this.committed.length + this.current.length;
214
+ }
215
+
216
+ toString() {
217
+ return this.committed + this.current;
218
+ }
219
+ }
220
+
179
221
  function OutputStream(options) {
180
222
 
181
223
  var readonly = !options;
@@ -240,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 + "}";
@@ -349,9 +391,11 @@ function OutputStream(options) {
349
391
  var do_add_mapping = mappings ? function() {
350
392
  mappings.forEach(function(mapping) {
351
393
  try {
352
- let name = !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name;
353
- if (name instanceof AST_Symbol) {
354
- name = name.name;
394
+ let { name, token } = mapping;
395
+ if (token.type == "name" || token.type === "privatename") {
396
+ name = token.value;
397
+ } else if (name instanceof AST_Symbol) {
398
+ name = token.type === "string" ? token.value : name.name;
355
399
  }
356
400
  options.source_map.add(
357
401
  mapping.token.file,
@@ -369,19 +413,18 @@ function OutputStream(options) {
369
413
  var ensure_line_len = options.max_line_len ? function() {
370
414
  if (current_col > options.max_line_len) {
371
415
  if (might_add_newline) {
372
- var left = OUTPUT.slice(0, might_add_newline);
373
- var right = OUTPUT.slice(might_add_newline);
416
+ OUTPUT.insertAt("\n", might_add_newline);
417
+ const curLength = OUTPUT.curLength();
374
418
  if (mappings) {
375
- var delta = right.length - current_col;
419
+ var delta = curLength - current_col;
376
420
  mappings.forEach(function(mapping) {
377
421
  mapping.line++;
378
422
  mapping.col += delta;
379
423
  });
380
424
  }
381
- OUTPUT = left + "\n" + right;
382
425
  current_line++;
383
426
  current_pos++;
384
- current_col = right.length;
427
+ current_col = curLength;
385
428
  }
386
429
  }
387
430
  if (might_add_newline) {
@@ -415,13 +458,13 @@ function OutputStream(options) {
415
458
 
416
459
  if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
417
460
  if (options.semicolons || requireSemicolonChars.has(ch)) {
418
- OUTPUT += ";";
461
+ OUTPUT.append(";");
419
462
  current_col++;
420
463
  current_pos++;
421
464
  } else {
422
465
  ensure_line_len();
423
466
  if (current_col > 0) {
424
- OUTPUT += "\n";
467
+ OUTPUT.append("\n");
425
468
  current_pos++;
426
469
  current_line++;
427
470
  current_col = 0;
@@ -445,7 +488,7 @@ function OutputStream(options) {
445
488
  || (ch == "/" && ch == prev)
446
489
  || ((ch == "+" || ch == "-") && ch == last)
447
490
  ) {
448
- OUTPUT += " ";
491
+ OUTPUT.append(" ");
449
492
  current_col++;
450
493
  current_pos++;
451
494
  }
@@ -463,7 +506,7 @@ function OutputStream(options) {
463
506
  if (!might_add_newline) do_add_mapping();
464
507
  }
465
508
 
466
- OUTPUT += str;
509
+ OUTPUT.append(str);
467
510
  has_parens = str[str.length - 1] == "(";
468
511
  current_pos += str.length;
469
512
  var a = str.split(/\r?\n/), n = a.length - 1;
@@ -503,15 +546,15 @@ function OutputStream(options) {
503
546
 
504
547
  var newline = options.beautify ? function() {
505
548
  if (newline_insert < 0) return print("\n");
506
- if (OUTPUT[newline_insert] != "\n") {
507
- OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert);
549
+ if (OUTPUT.charAt(newline_insert) != "\n") {
550
+ OUTPUT.insertAt("\n", newline_insert);
508
551
  current_pos++;
509
552
  current_line++;
510
553
  }
511
554
  newline_insert++;
512
555
  } : options.max_line_len ? function() {
513
556
  ensure_line_len();
514
- might_add_newline = OUTPUT.length;
557
+ might_add_newline = OUTPUT.length();
515
558
  } : noop;
516
559
 
517
560
  var semicolon = options.beautify ? function() {
@@ -577,13 +620,14 @@ function OutputStream(options) {
577
620
  if (might_add_newline) {
578
621
  ensure_line_len();
579
622
  }
580
- return OUTPUT;
623
+ return OUTPUT.toString();
581
624
  }
582
625
 
583
626
  function has_nlb() {
584
- let n = OUTPUT.length - 1;
627
+ const output = OUTPUT.toString();
628
+ let n = output.length - 1;
585
629
  while (n >= 0) {
586
- const code = OUTPUT.charCodeAt(n);
630
+ const code = output.charCodeAt(n);
587
631
  if (code === CODE_LINE_BREAK) {
588
632
  return true;
589
633
  }
@@ -720,7 +764,7 @@ function OutputStream(options) {
720
764
  !/comment[134]/.test(c.type)
721
765
  ))) return;
722
766
  printed_comments.add(comments);
723
- var insert = OUTPUT.length;
767
+ var insert = OUTPUT.length();
724
768
  comments.filter(comment_filter, node).forEach(function(c, i) {
725
769
  if (printed_comments.has(c)) return;
726
770
  printed_comments.add(c);
@@ -749,7 +793,7 @@ function OutputStream(options) {
749
793
  need_space = true;
750
794
  }
751
795
  });
752
- if (OUTPUT.length > insert) newline_insert = insert;
796
+ if (OUTPUT.length() > insert) newline_insert = insert;
753
797
  }
754
798
 
755
799
  var stack = [];
@@ -779,7 +823,7 @@ function OutputStream(options) {
779
823
  var encoded = encode_string(str, quote);
780
824
  if (escape_directive === true && !encoded.includes("\\")) {
781
825
  // Insert semicolons to break directive prologue
782
- if (!EXPECT_DIRECTIVE.test(OUTPUT)) {
826
+ if (!EXPECT_DIRECTIVE.test(OUTPUT.toString())) {
783
827
  force_semicolon();
784
828
  }
785
829
  force_semicolon();
@@ -1635,6 +1679,10 @@ function OutputStream(options) {
1635
1679
  output.space();
1636
1680
  }
1637
1681
  self.module_name.print(output);
1682
+ if (self.assert_clause) {
1683
+ output.print("assert");
1684
+ self.assert_clause.print(output);
1685
+ }
1638
1686
  output.semicolon();
1639
1687
  });
1640
1688
  DEFPRINT(AST_ImportMeta, function(self, output) {
@@ -1700,6 +1748,10 @@ function OutputStream(options) {
1700
1748
  output.space();
1701
1749
  self.module_name.print(output);
1702
1750
  }
1751
+ if (self.assert_clause) {
1752
+ output.print("assert");
1753
+ self.assert_clause.print(output);
1754
+ }
1703
1755
  if (self.exported_value
1704
1756
  && !(self.exported_value instanceof AST_Defun ||
1705
1757
  self.exported_value instanceof AST_Function ||
@@ -1824,6 +1876,7 @@ function OutputStream(options) {
1824
1876
 
1825
1877
  if (self.optional) output.print("?");
1826
1878
  output.print(".#");
1879
+ output.add_mapping(self.end);
1827
1880
  output.print_name(prop);
1828
1881
  });
1829
1882
  DEFPRINT(AST_Sub, function(self, output) {
@@ -2160,7 +2213,7 @@ function OutputStream(options) {
2160
2213
  flags = flags ? sort_regexp_flags(flags) : "";
2161
2214
  source = source.replace(r_slash_script, slash_script_replace);
2162
2215
 
2163
- output.print(output.to_utf8(`/${source}/${flags}`));
2216
+ output.print(output.to_utf8(`/${source}/${flags}`, false, true));
2164
2217
 
2165
2218
  const parent = output.parent();
2166
2219
  if (
@@ -2277,8 +2330,10 @@ function OutputStream(options) {
2277
2330
  DEFMAP([
2278
2331
  AST_ObjectGetter,
2279
2332
  AST_ObjectSetter,
2333
+ AST_PrivateGetter,
2334
+ AST_PrivateSetter,
2280
2335
  ], function(output) {
2281
- output.add_mapping(this.start, this.key.name);
2336
+ output.add_mapping(this.key.end, this.key.name);
2282
2337
  });
2283
2338
 
2284
2339
  DEFMAP([ AST_ObjectProperty ], function(output) {
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 = import_();
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 = export_();
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 import_() {
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: start,
2694
- imported_name: imported_name,
2695
- imported_names: 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 export_() {
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