terser 5.6.1 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/scope.js CHANGED
@@ -107,7 +107,7 @@ import {
107
107
  walk
108
108
  } from "./ast.js";
109
109
  import {
110
- RESERVED_WORDS,
110
+ ALL_RESERVED_WORDS,
111
111
  js_error,
112
112
  } from "./parse.js";
113
113
 
@@ -299,7 +299,14 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
299
299
  // scope when we encounter the AST_Defun node (which is
300
300
  // instanceof AST_Scope) but we get to the symbol a bit
301
301
  // later.
302
- mark_export((node.scope = defun.parent_scope.get_defun_scope()).def_function(node, defun), 1);
302
+ const closest_scope = defun.parent_scope;
303
+
304
+ // In strict mode, function definitions are block-scoped
305
+ node.scope = tw.directives["use strict"]
306
+ ? closest_scope
307
+ : closest_scope.get_defun_scope();
308
+
309
+ mark_export(node.scope.def_function(node, defun), 1);
303
310
  } else if (node instanceof AST_SymbolClass) {
304
311
  mark_export(defun.def_variable(node, defun), 1);
305
312
  } else if (node instanceof AST_SymbolImport) {
@@ -478,7 +485,6 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
478
485
 
479
486
  AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
480
487
  this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
481
- this.functions = new Map(); // map name to AST_SymbolDefun (functions defined in this scope)
482
488
  this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
483
489
  this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
484
490
  this.parent_scope = parent_scope; // the parent scope
@@ -641,7 +647,6 @@ AST_Scope.DEFMETHOD("find_variable", function(name) {
641
647
  AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
642
648
  var def = this.def_variable(symbol, init);
643
649
  if (!def.init || def.init instanceof AST_Defun) def.init = init;
644
- this.functions.set(symbol.name, def);
645
650
  return def;
646
651
  });
647
652
 
@@ -662,9 +667,10 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
662
667
 
663
668
  function next_mangled(scope, options) {
664
669
  var ext = scope.enclosed;
670
+ var nth_identifier = options.nth_identifier;
665
671
  out: while (true) {
666
- var m = base54(++scope.cname);
667
- if (RESERVED_WORDS.has(m)) continue; // skip over "do"
672
+ var m = nth_identifier.get(++scope.cname);
673
+ if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do"
668
674
 
669
675
  // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
670
676
  // shadow a name reserved from mangling.
@@ -739,6 +745,7 @@ AST_Symbol.DEFMETHOD("global", function() {
739
745
  AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
740
746
  options = defaults(options, {
741
747
  eval : false,
748
+ nth_identifier : base54,
742
749
  ie8 : false,
743
750
  keep_classnames: false,
744
751
  keep_fnames : false,
@@ -760,6 +767,7 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
760
767
 
761
768
  AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
762
769
  options = this._default_mangler_options(options);
770
+ var nth_identifier = options.nth_identifier;
763
771
 
764
772
  // We only need to mangle declaration nodes. Special logic wired
765
773
  // into the code generator will display the mangled name if it's
@@ -811,8 +819,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
811
819
  if (node instanceof AST_Label) {
812
820
  let name;
813
821
  do {
814
- name = base54(++lname);
815
- } while (RESERVED_WORDS.has(name));
822
+ name = nth_identifier.get(++lname);
823
+ } while (ALL_RESERVED_WORDS.has(name));
816
824
  node.mangled_name = name;
817
825
  return true;
818
826
  }
@@ -873,9 +881,12 @@ AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
873
881
  });
874
882
 
875
883
  AST_Toplevel.DEFMETHOD("expand_names", function(options) {
876
- base54.reset();
877
- base54.sort();
878
884
  options = this._default_mangler_options(options);
885
+ var nth_identifier = options.nth_identifier;
886
+ if (nth_identifier.reset && nth_identifier.sort) {
887
+ nth_identifier.reset();
888
+ nth_identifier.sort();
889
+ }
879
890
  var avoid = this.find_colliding_names(options);
880
891
  var cname = 0;
881
892
  this.globals.forEach(rename);
@@ -887,8 +898,8 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
887
898
  function next_name() {
888
899
  var name;
889
900
  do {
890
- name = base54(cname++);
891
- } while (avoid.has(name) || RESERVED_WORDS.has(name));
901
+ name = nth_identifier.get(cname++);
902
+ } while (avoid.has(name) || ALL_RESERVED_WORDS.has(name));
892
903
  return name;
893
904
  }
894
905
 
@@ -914,30 +925,37 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
914
925
 
915
926
  AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
916
927
  options = this._default_mangler_options(options);
928
+ var nth_identifier = options.nth_identifier;
929
+ if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) {
930
+ // If the identifier mangler is invariant, skip computing character frequency.
931
+ return;
932
+ }
933
+ nth_identifier.reset();
934
+
917
935
  try {
918
936
  AST_Node.prototype.print = function(stream, force_parens) {
919
937
  this._print(stream, force_parens);
920
938
  if (this instanceof AST_Symbol && !this.unmangleable(options)) {
921
- base54.consider(this.name, -1);
939
+ nth_identifier.consider(this.name, -1);
922
940
  } else if (options.properties) {
923
941
  if (this instanceof AST_DotHash) {
924
- base54.consider("#" + this.property, -1);
942
+ nth_identifier.consider("#" + this.property, -1);
925
943
  } else if (this instanceof AST_Dot) {
926
- base54.consider(this.property, -1);
944
+ nth_identifier.consider(this.property, -1);
927
945
  } else if (this instanceof AST_Sub) {
928
946
  skip_string(this.property);
929
947
  }
930
948
  }
931
949
  };
932
- base54.consider(this.print_to_string(), 1);
950
+ nth_identifier.consider(this.print_to_string(), 1);
933
951
  } finally {
934
952
  AST_Node.prototype.print = AST_Node.prototype._print;
935
953
  }
936
- base54.sort();
954
+ nth_identifier.sort();
937
955
 
938
956
  function skip_string(node) {
939
957
  if (node instanceof AST_String) {
940
- base54.consider(node.value, -1);
958
+ nth_identifier.consider(node.value, -1);
941
959
  } else if (node instanceof AST_Conditional) {
942
960
  skip_string(node.consequent);
943
961
  skip_string(node.alternative);
@@ -961,19 +979,20 @@ const base54 = (() => {
961
979
  frequency.set(ch, 0);
962
980
  });
963
981
  }
964
- base54.consider = function(str, delta) {
982
+ function consider(str, delta) {
965
983
  for (var i = str.length; --i >= 0;) {
966
984
  frequency.set(str[i], frequency.get(str[i]) + delta);
967
985
  }
968
- };
986
+ }
969
987
  function compare(a, b) {
970
988
  return frequency.get(b) - frequency.get(a);
971
989
  }
972
- base54.sort = function() {
990
+ function sort() {
973
991
  chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
974
- };
975
- base54.reset = reset;
992
+ }
993
+ // Ensure this is in a usable initial state.
976
994
  reset();
995
+ sort();
977
996
  function base54(num) {
978
997
  var ret = "", base = 54;
979
998
  num++;
@@ -985,7 +1004,13 @@ const base54 = (() => {
985
1004
  } while (num > 0);
986
1005
  return ret;
987
1006
  }
988
- return base54;
1007
+
1008
+ return {
1009
+ get: base54,
1010
+ consider,
1011
+ reset,
1012
+ sort
1013
+ };
989
1014
  })();
990
1015
 
991
1016
  export {
package/lib/transform.js CHANGED
@@ -57,7 +57,6 @@ import {
57
57
  AST_Definitions,
58
58
  AST_Destructuring,
59
59
  AST_Do,
60
- AST_Dot,
61
60
  AST_Exit,
62
61
  AST_Expansion,
63
62
  AST_Export,
@@ -74,6 +73,7 @@ import {
74
73
  AST_Object,
75
74
  AST_ObjectProperty,
76
75
  AST_PrefixedTemplateString,
76
+ AST_PropAccess,
77
77
  AST_Sequence,
78
78
  AST_SimpleStatement,
79
79
  AST_Sub,
@@ -228,7 +228,7 @@ def_transform(AST_Sequence, function(self, tw) {
228
228
  : [new AST_Number({ value: 0 })];
229
229
  });
230
230
 
231
- def_transform(AST_Dot, function(self, tw) {
231
+ def_transform(AST_PropAccess, function(self, tw) {
232
232
  self.expression = self.expression.transform(tw);
233
233
  });
234
234
 
@@ -64,10 +64,8 @@ class DefaultsError extends Error {
64
64
  function defaults(args, defs, croak) {
65
65
  if (args === true) {
66
66
  args = {};
67
- }
68
-
69
- if (args != null && typeof args === "object") {
70
- args = Object.assign({}, args);
67
+ } else if (args != null && typeof args === "object") {
68
+ args = {...args};
71
69
  }
72
70
 
73
71
  const ret = args || {};
@@ -196,7 +194,7 @@ function mergeSort(array, cmp) {
196
194
  function makePredicate(words) {
197
195
  if (!Array.isArray(words)) words = words.split(" ");
198
196
 
199
- return new Set(words);
197
+ return new Set(words.sort());
200
198
  }
201
199
 
202
200
  function map_add(map, key, value) {
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.6.1",
7
+ "version": "5.8.0",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },
@@ -24,7 +24,8 @@
24
24
  "./dist/bundle.min.js"
25
25
  ],
26
26
  "./package": "./package.json",
27
- "./package.json": "./package.json"
27
+ "./package.json": "./package.json",
28
+ "./bin/terser": "./bin/terser"
28
29
  },
29
30
  "types": "tools/terser.d.ts",
30
31
  "bin": {
@@ -44,19 +45,19 @@
44
45
  "dependencies": {
45
46
  "commander": "^2.20.0",
46
47
  "source-map": "~0.7.2",
47
- "source-map-support": "~0.5.19"
48
+ "source-map-support": "~0.5.20"
48
49
  },
49
50
  "devDependencies": {
50
- "@ls-lint/ls-lint": "^1.9.2",
51
- "acorn": "^8.0.5",
52
- "astring": "^1.6.2",
53
- "eslint": "^7.19.0",
54
- "eslump": "^2.0.0",
51
+ "@ls-lint/ls-lint": "^1.10.0",
52
+ "acorn": "^8.5.0",
53
+ "astring": "^1.7.5",
54
+ "eslint": "^7.32.0",
55
+ "eslump": "^3.0.0",
55
56
  "esm": "^3.2.25",
56
- "mocha": "^8.2.1",
57
+ "mocha": "^9.1.1",
57
58
  "pre-commit": "^1.2.2",
58
59
  "rimraf": "^3.0.2",
59
- "rollup": "2.38.4",
60
+ "rollup": "2.56.3",
60
61
  "semver": "^7.3.4"
61
62
  },
62
63
  "scripts": {
@@ -92,7 +93,7 @@
92
93
  "eslintConfig": {
93
94
  "parserOptions": {
94
95
  "sourceType": "module",
95
- "ecmaVersion": "2020"
96
+ "ecmaVersion": 2020
96
97
  },
97
98
  "env": {
98
99
  "node": true,
@@ -124,7 +125,7 @@
124
125
  "no-unused-vars": [
125
126
  "error",
126
127
  {
127
- "varsIgnorePattern": "^_$"
128
+ "varsIgnorePattern": "^_"
128
129
  }
129
130
  ],
130
131
  "no-tabs": "error",
package/tools/terser.d.ts CHANGED
@@ -80,16 +80,52 @@ export interface MangleOptions {
80
80
  keep_classnames?: boolean | RegExp;
81
81
  keep_fnames?: boolean | RegExp;
82
82
  module?: boolean;
83
+ nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
83
84
  properties?: boolean | ManglePropertiesOptions;
84
85
  reserved?: string[];
85
86
  safari10?: boolean;
86
87
  toplevel?: boolean;
87
88
  }
88
89
 
90
+ /**
91
+ * An identifier mangler for which the output is invariant with respect to the source code.
92
+ */
93
+ export interface SimpleIdentifierMangler {
94
+ /**
95
+ * Obtains the nth most favored (usually shortest) identifier to rename a variable to.
96
+ * The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word.
97
+ * This function is expected to be stable; Evaluating get(n) === get(n) should always return true.
98
+ * @param n The ordinal of the identifier.
99
+ */
100
+ get(n: number): string;
101
+ }
102
+
103
+ /**
104
+ * An identifier mangler that leverages character frequency analysis to determine identifier precedence.
105
+ */
106
+ export interface WeightedIdentifierMangler extends SimpleIdentifierMangler {
107
+ /**
108
+ * Modifies the internal weighting of the input characters by the specified delta.
109
+ * Will be invoked on the entire printed AST, and then deduct mangleable identifiers.
110
+ * @param chars The characters to modify the weighting of.
111
+ * @param delta The numeric weight to add to the characters.
112
+ */
113
+ consider(chars: string, delta: number): number;
114
+ /**
115
+ * Resets character weights.
116
+ */
117
+ reset(): void;
118
+ /**
119
+ * Sorts identifiers by character frequency, in preparation for calls to get(n).
120
+ */
121
+ sort(): void;
122
+ }
123
+
89
124
  export interface ManglePropertiesOptions {
90
125
  builtins?: boolean;
91
126
  debug?: boolean;
92
127
  keep_quoted?: boolean | 'strict';
128
+ nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
93
129
  regex?: RegExp | string;
94
130
  reserved?: string[];
95
131
  }
@@ -138,6 +174,7 @@ export enum OutputQuoteStyle {
138
174
  export interface MinifyOptions {
139
175
  compress?: boolean | CompressOptions;
140
176
  ecma?: ECMA;
177
+ enclose?: boolean | string;
141
178
  ie8?: boolean;
142
179
  keep_classnames?: boolean | RegExp;
143
180
  keep_fnames?: boolean | RegExp;