terser 5.19.4 → 5.21.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.
@@ -344,5 +344,5 @@ export function retain_top_func(fn, compressor) {
344
344
  && fn instanceof AST_Defun
345
345
  && has_flag(fn, TOP)
346
346
  && fn.name
347
- && compressor.top_retain(fn.name);
347
+ && compressor.top_retain(fn.name.definition());
348
348
  }
@@ -128,7 +128,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
128
128
  var fixed_ids = new Map();
129
129
  if (self instanceof AST_Toplevel && compressor.top_retain) {
130
130
  self.variables.forEach(function(def) {
131
- if (compressor.top_retain(def) && !in_use_ids.has(def.id)) {
131
+ if (compressor.top_retain(def)) {
132
132
  in_use_ids.set(def.id, def);
133
133
  }
134
134
  });
@@ -143,9 +143,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
143
143
  node.argnames.forEach(function(argname) {
144
144
  if (!(argname instanceof AST_SymbolDeclaration)) return;
145
145
  var def = argname.definition();
146
- if (!in_use_ids.has(def.id)) {
147
- in_use_ids.set(def.id, def);
148
- }
146
+ in_use_ids.set(def.id, def);
149
147
  });
150
148
  }
151
149
  if (node === self) return;
@@ -158,7 +156,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
158
156
  var node_def = node.name.definition();
159
157
  const in_export = tw.parent() instanceof AST_Export;
160
158
  if (in_export || !drop_funcs && scope === self) {
161
- if (node_def.global && !in_use_ids.has(node_def.id)) {
159
+ if (node_def.global) {
162
160
  in_use_ids.set(node_def.id, node_def);
163
161
  }
164
162
  }
@@ -166,10 +164,12 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
166
164
  map_add(initializations, node_def.id, node);
167
165
  return true; // don't go in nested scopes
168
166
  }
169
- if (node instanceof AST_SymbolFunarg && scope === self) {
167
+ // In the root scope, we drop things. In inner scopes, we just check for uses.
168
+ const in_root_scope = scope === self;
169
+ if (node instanceof AST_SymbolFunarg && in_root_scope) {
170
170
  map_add(var_defs_by_id, node.definition().id, node);
171
171
  }
172
- if (node instanceof AST_Definitions && scope === self) {
172
+ if (node instanceof AST_Definitions && in_root_scope) {
173
173
  const in_export = tw.parent() instanceof AST_Export;
174
174
  node.definitions.forEach(function(def) {
175
175
  if (def.name instanceof AST_SymbolVar) {
@@ -179,7 +179,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
179
179
  walk(def.name, node => {
180
180
  if (node instanceof AST_SymbolDeclaration) {
181
181
  const def = node.definition();
182
- if (def.global && !in_use_ids.has(def.id)) {
182
+ if (def.global) {
183
183
  in_use_ids.set(def.id, def);
184
184
  }
185
185
  }
@@ -0,0 +1,92 @@
1
+ import {
2
+ AST_Array,
3
+ AST_Chain,
4
+ AST_Constant,
5
+ AST_Dot,
6
+ AST_ImportMeta,
7
+ AST_Node,
8
+ AST_Object,
9
+ AST_ObjectKeyVal,
10
+ AST_PropAccess,
11
+ AST_SymbolDeclaration,
12
+ AST_SymbolRef,
13
+ AST_Toplevel,
14
+ TreeTransformer,
15
+ } from "../ast.js";
16
+ import { make_node, noop, HOP } from "../utils/index.js";
17
+ import { make_node_from_constant } from "./common.js";
18
+ import { is_lhs } from "./inference.js";
19
+
20
+ (function(def_find_defs) {
21
+ function to_node(value, orig) {
22
+ if (value instanceof AST_Node) {
23
+ if (!(value instanceof AST_Constant)) {
24
+ // Value may be a function, an array including functions and even a complex assign / block expression,
25
+ // so it should never be shared in different places.
26
+ // Otherwise wrong information may be used in the compression phase
27
+ value = value.clone(true);
28
+ }
29
+ return make_node(value.CTOR, orig, value);
30
+ }
31
+ if (Array.isArray(value)) return make_node(AST_Array, orig, {
32
+ elements: value.map(function(value) {
33
+ return to_node(value, orig);
34
+ })
35
+ });
36
+ if (value && typeof value == "object") {
37
+ var props = [];
38
+ for (var key in value) if (HOP(value, key)) {
39
+ props.push(make_node(AST_ObjectKeyVal, orig, {
40
+ key: key,
41
+ value: to_node(value[key], orig)
42
+ }));
43
+ }
44
+ return make_node(AST_Object, orig, {
45
+ properties: props
46
+ });
47
+ }
48
+ return make_node_from_constant(value, orig);
49
+ }
50
+
51
+ AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
52
+ if (!compressor.option("global_defs")) return this;
53
+ this.figure_out_scope({ ie8: compressor.option("ie8") });
54
+ return this.transform(new TreeTransformer(function(node) {
55
+ var def = node._find_defs(compressor, "");
56
+ if (!def) return;
57
+ var level = 0, child = node, parent;
58
+ while (parent = this.parent(level++)) {
59
+ if (!(parent instanceof AST_PropAccess)) break;
60
+ if (parent.expression !== child) break;
61
+ child = parent;
62
+ }
63
+ if (is_lhs(child, parent)) {
64
+ return;
65
+ }
66
+ return def;
67
+ }));
68
+ });
69
+ def_find_defs(AST_Node, noop);
70
+ def_find_defs(AST_Chain, function(compressor, suffix) {
71
+ return this.expression._find_defs(compressor, suffix);
72
+ });
73
+ def_find_defs(AST_Dot, function(compressor, suffix) {
74
+ return this.expression._find_defs(compressor, "." + this.property + suffix);
75
+ });
76
+ def_find_defs(AST_SymbolDeclaration, function() {
77
+ if (!this.global()) return;
78
+ });
79
+ def_find_defs(AST_SymbolRef, function(compressor, suffix) {
80
+ if (!this.global()) return;
81
+ var defines = compressor.option("global_defs");
82
+ var name = this.name + suffix;
83
+ if (HOP(defines, name)) return to_node(defines[name], this);
84
+ });
85
+ def_find_defs(AST_ImportMeta, function(compressor, suffix) {
86
+ var defines = compressor.option("global_defs");
87
+ var name = "import.meta" + suffix;
88
+ if (HOP(defines, name)) return to_node(defines[name], this);
89
+ });
90
+ })(function(node, func) {
91
+ node.DEFMETHOD("_find_defs", func);
92
+ });
@@ -204,11 +204,11 @@ import {
204
204
  is_reachable,
205
205
  can_be_evicted_from_block,
206
206
  as_statement_array,
207
- retain_top_func,
208
207
  is_func_expr,
209
208
  } from "./common.js";
210
209
  import { tighten_body, trim_unreachable_code } from "./tighten-body.js";
211
210
  import { inline_into_symbolref, inline_into_call } from "./inline.js";
211
+ import "./global-defs.js";
212
212
 
213
213
  class Compressor extends TreeWalker {
214
214
  constructor(options, { false_by_default = false, mangle_options = false }) {
@@ -385,7 +385,7 @@ class Compressor extends TreeWalker {
385
385
  this._toplevel.figure_out_scope(mangle);
386
386
  if (pass === 0 && this.option("drop_console")) {
387
387
  // must be run before reduce_vars and compress pass
388
- this._toplevel = this._toplevel.drop_console();
388
+ this._toplevel = this._toplevel.drop_console(this.option("drop_console"));
389
389
  }
390
390
  if (pass > 0 || this.option("reduce_vars")) {
391
391
  this._toplevel.reset_opt_flags(this);
@@ -464,19 +464,30 @@ def_optimize(AST_Node, function(self) {
464
464
  return self;
465
465
  });
466
466
 
467
- AST_Toplevel.DEFMETHOD("drop_console", function() {
467
+ AST_Toplevel.DEFMETHOD("drop_console", function(options) {
468
+ var isArray = Array.isArray(options);
469
+
468
470
  return this.transform(new TreeTransformer(function(self) {
469
- if (self.TYPE == "Call") {
470
- var exp = self.expression;
471
- if (exp instanceof AST_PropAccess) {
472
- var name = exp.expression;
473
- while (name.expression) {
474
- name = name.expression;
475
- }
476
- if (is_undeclared_ref(name) && name.name == "console") {
477
- return make_node(AST_Undefined, self);
478
- }
479
- }
471
+ if (self.TYPE !== "Call") {
472
+ return;
473
+ }
474
+
475
+ var exp = self.expression;
476
+
477
+ if (!(exp instanceof AST_PropAccess)) {
478
+ return;
479
+ }
480
+
481
+ if (isArray && options.indexOf(exp.property) === -1) {
482
+ return;
483
+ }
484
+
485
+ var name = exp.expression;
486
+ while (name.expression) {
487
+ name = name.expression;
488
+ }
489
+ if (is_undeclared_ref(name) && name.name == "console") {
490
+ return make_node(AST_Undefined, self);
480
491
  }
481
492
  }));
482
493
  });
@@ -1598,18 +1609,10 @@ def_optimize(AST_Call, function(self, compressor) {
1598
1609
  var exp = self.expression;
1599
1610
  var fn = exp;
1600
1611
  inline_array_like_spread(self.args);
1601
- var simple_args = self.args.every((arg) =>
1602
- !(arg instanceof AST_Expansion)
1603
- );
1612
+ var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
1604
1613
 
1605
- if (compressor.option("reduce_vars")
1606
- && fn instanceof AST_SymbolRef
1607
- && !has_annotation(self, _NOINLINE)
1608
- ) {
1609
- const fixed = fn.fixed_value();
1610
- if (!retain_top_func(fixed, compressor)) {
1611
- fn = fixed;
1612
- }
1614
+ if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
1615
+ fn = fn.fixed_value();
1613
1616
  }
1614
1617
 
1615
1618
  var is_func = fn instanceof AST_Lambda;
@@ -1917,7 +1920,7 @@ def_optimize(AST_Call, function(self, compressor) {
1917
1920
  }
1918
1921
  }
1919
1922
 
1920
- return inline_into_call(self, fn, compressor);
1923
+ return inline_into_call(self, compressor);
1921
1924
  });
1922
1925
 
1923
1926
  def_optimize(AST_New, function(self, compressor) {
@@ -3750,10 +3753,10 @@ def_optimize(AST_Destructuring, function(self, compressor) {
3750
3753
  if (def.references.length) return true;
3751
3754
  if (!def.global) return false;
3752
3755
  if (compressor.toplevel.vars) {
3753
- if (compressor.top_retain) {
3754
- return compressor.top_retain(def);
3755
- }
3756
- return false;
3756
+ if (compressor.top_retain) {
3757
+ return compressor.top_retain(def);
3758
+ }
3759
+ return false;
3757
3760
  }
3758
3761
  return true;
3759
3762
  }
@@ -98,7 +98,6 @@ import {
98
98
  AST_TemplateSegment,
99
99
  AST_TemplateString,
100
100
  AST_This,
101
- AST_Toplevel,
102
101
  AST_True,
103
102
  AST_Try,
104
103
  AST_Unary,
@@ -107,7 +106,6 @@ import {
107
106
  AST_Undefined,
108
107
  AST_VarDef,
109
108
 
110
- TreeTransformer,
111
109
  walk,
112
110
  walk_abort,
113
111
 
@@ -121,11 +119,9 @@ import {
121
119
  return_this,
122
120
  make_node,
123
121
  member,
124
- noop,
125
122
  has_annotation,
126
- HOP
127
123
  } from "../utils/index.js";
128
- import { make_node_from_constant, make_sequence, best_of_expression, read_property } from "./common.js";
124
+ import { make_sequence, best_of_expression, read_property } from "./common.js";
129
125
 
130
126
  import { INLINED, UNDEFINED, has_flag } from "./compressor-flags.js";
131
127
  import { pure_prop_access_globals, is_pure_native_fn, is_pure_native_method } from "./native-objects.js";
@@ -728,80 +724,6 @@ export function is_lhs(node, parent) {
728
724
  if (parent instanceof AST_ForIn && parent.init === node) return node;
729
725
  }
730
726
 
731
- (function(def_find_defs) {
732
- function to_node(value, orig) {
733
- if (value instanceof AST_Node) {
734
- if (!(value instanceof AST_Constant)) {
735
- // Value may be a function, an array including functions and even a complex assign / block expression,
736
- // so it should never be shared in different places.
737
- // Otherwise wrong information may be used in the compression phase
738
- value = value.clone(true);
739
- }
740
- return make_node(value.CTOR, orig, value);
741
- }
742
- if (Array.isArray(value)) return make_node(AST_Array, orig, {
743
- elements: value.map(function(value) {
744
- return to_node(value, orig);
745
- })
746
- });
747
- if (value && typeof value == "object") {
748
- var props = [];
749
- for (var key in value) if (HOP(value, key)) {
750
- props.push(make_node(AST_ObjectKeyVal, orig, {
751
- key: key,
752
- value: to_node(value[key], orig)
753
- }));
754
- }
755
- return make_node(AST_Object, orig, {
756
- properties: props
757
- });
758
- }
759
- return make_node_from_constant(value, orig);
760
- }
761
-
762
- AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
763
- if (!compressor.option("global_defs")) return this;
764
- this.figure_out_scope({ ie8: compressor.option("ie8") });
765
- return this.transform(new TreeTransformer(function(node) {
766
- var def = node._find_defs(compressor, "");
767
- if (!def) return;
768
- var level = 0, child = node, parent;
769
- while (parent = this.parent(level++)) {
770
- if (!(parent instanceof AST_PropAccess)) break;
771
- if (parent.expression !== child) break;
772
- child = parent;
773
- }
774
- if (is_lhs(child, parent)) {
775
- return;
776
- }
777
- return def;
778
- }));
779
- });
780
- def_find_defs(AST_Node, noop);
781
- def_find_defs(AST_Chain, function(compressor, suffix) {
782
- return this.expression._find_defs(compressor, suffix);
783
- });
784
- def_find_defs(AST_Dot, function(compressor, suffix) {
785
- return this.expression._find_defs(compressor, "." + this.property + suffix);
786
- });
787
- def_find_defs(AST_SymbolDeclaration, function() {
788
- if (!this.global()) return;
789
- });
790
- def_find_defs(AST_SymbolRef, function(compressor, suffix) {
791
- if (!this.global()) return;
792
- var defines = compressor.option("global_defs");
793
- var name = this.name + suffix;
794
- if (HOP(defines, name)) return to_node(defines[name], this);
795
- });
796
- def_find_defs(AST_ImportMeta, function(compressor, suffix) {
797
- var defines = compressor.option("global_defs");
798
- var name = "import.meta" + suffix;
799
- if (HOP(defines, name)) return to_node(defines[name], this);
800
- });
801
- })(function(node, func) {
802
- node.DEFMETHOD("_find_defs", func);
803
- });
804
-
805
727
  // method to negate an expression
806
728
  (function(def_negate) {
807
729
  function basic_negation(exp) {
@@ -290,8 +290,9 @@ export function inline_into_symbolref(self, compressor) {
290
290
  return self;
291
291
  }
292
292
 
293
- export function inline_into_call(self, fn, compressor) {
293
+ export function inline_into_call(self, compressor) {
294
294
  var exp = self.expression;
295
+ var fn = exp;
295
296
  var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
296
297
 
297
298
  if (compressor.option("reduce_vars")
@@ -299,9 +300,15 @@ export function inline_into_call(self, fn, compressor) {
299
300
  && !has_annotation(self, _NOINLINE)
300
301
  ) {
301
302
  const fixed = fn.fixed_value();
302
- if (!retain_top_func(fixed, compressor)) {
303
- fn = fixed;
303
+
304
+ if (
305
+ retain_top_func(fixed, compressor)
306
+ || !compressor.toplevel.funcs && exp.definition().global
307
+ ) {
308
+ return self;
304
309
  }
310
+
311
+ fn = fixed;
305
312
  }
306
313
 
307
314
  var is_func = fn instanceof AST_Lambda;
package/lib/minify.js CHANGED
@@ -230,6 +230,9 @@ async function minify(files, options, _fs_module) {
230
230
  }
231
231
  }
232
232
  }
233
+ if (options.parse.toplevel === null) {
234
+ throw new Error("no source file given");
235
+ }
233
236
 
234
237
  toplevel = options.parse.toplevel;
235
238
  }
@@ -166,17 +166,15 @@ import { is_basic_identifier_string } from "./parse.js";
166
166
  (function() {
167
167
 
168
168
  var normalize_directives = function(body) {
169
- var in_directive = true;
170
-
171
169
  for (var i = 0; i < body.length; i++) {
172
- if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
170
+ if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
173
171
  body[i] = new AST_Directive({
174
172
  start: body[i].start,
175
173
  end: body[i].end,
176
174
  value: body[i].body.value
177
175
  });
178
- } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
179
- in_directive = false;
176
+ } else {
177
+ return body;
180
178
  }
181
179
  }
182
180
 
package/lib/output.js CHANGED
@@ -980,7 +980,8 @@ function OutputStream(options) {
980
980
  ) {
981
981
  return true;
982
982
  }
983
- return p instanceof AST_PropAccess && p.expression === this;
983
+ return p instanceof AST_PropAccess && p.expression === this
984
+ || p instanceof AST_Conditional && p.condition === this;
984
985
  });
985
986
 
986
987
  // same goes for an object literal (as in AST_Function), because
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.19.4",
7
+ "version": "5.21.0",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },