terser 5.27.0 → 5.27.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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.27.2
4
+ - Recognise `this` as a reference to the surrounding class in `drop_unused`. Closes #1472
5
+
6
+ ## v5.27.1
7
+ - Fixed case where `collapse_vars` inlines `await` expressions into non-async functions.
8
+
3
9
  ## v5.27.0
4
10
  - Created `minify_sync()` alternative to `minify()` since there's no async code left.
5
11
 
@@ -15137,6 +15137,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15137
15137
  return node.expression;
15138
15138
  }
15139
15139
  };
15140
+ var this_def = null;
15140
15141
  var in_use_ids = new Map();
15141
15142
  var fixed_ids = new Map();
15142
15143
  if (self instanceof AST_Toplevel && compressor.top_retain) {
@@ -15148,6 +15149,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15148
15149
  }
15149
15150
  var var_defs_by_id = new Map();
15150
15151
  var initializations = new Map();
15152
+
15151
15153
  // pass 1: find out which symbols are directly used in
15152
15154
  // this scope (not in nested scopes).
15153
15155
  var scope = this;
@@ -15160,11 +15162,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15160
15162
  });
15161
15163
  }
15162
15164
  if (node === self) return;
15163
- if (node instanceof AST_Class) {
15164
- if (node.has_side_effects(compressor)) {
15165
- node.visit_nondeferred_class_parts(tw);
15166
- }
15167
- }
15168
15165
  if (node instanceof AST_Defun || node instanceof AST_DefClass) {
15169
15166
  var node_def = node.name.definition();
15170
15167
  const in_export = tw.parent() instanceof AST_Export;
@@ -15174,11 +15171,22 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15174
15171
  }
15175
15172
  }
15176
15173
 
15174
+ if (node instanceof AST_DefClass && node.has_side_effects(compressor)) {
15175
+ const save_this_def = this_def;
15176
+ this_def = node_def;
15177
+ node.visit_nondeferred_class_parts(tw);
15178
+ this_def = save_this_def;
15179
+ }
15180
+
15177
15181
  map_add(initializations, node_def.id, node);
15178
15182
  return true; // don't go in nested scopes
15179
15183
  }
15180
15184
  // In the root scope, we drop things. In inner scopes, we just check for uses.
15181
15185
  const in_root_scope = scope === self;
15186
+ if (node instanceof AST_This && this_def && in_root_scope) {
15187
+ in_use_ids.set(this_def.id, this_def);
15188
+ return true;
15189
+ }
15182
15190
  if (node instanceof AST_SymbolFunarg && in_root_scope) {
15183
15191
  map_add(var_defs_by_id, node.definition().id, node);
15184
15192
  }
@@ -16725,6 +16733,14 @@ function tighten_body(statements, compressor) {
16725
16733
  return found;
16726
16734
  }
16727
16735
 
16736
+ function arg_is_injectable(arg) {
16737
+ if (arg instanceof AST_Expansion) return false;
16738
+ const contains_await = walk(arg, (node) => {
16739
+ if (node instanceof AST_Await) return walk_abort;
16740
+ });
16741
+ if (contains_await) return false;
16742
+ return true;
16743
+ }
16728
16744
  function extract_args() {
16729
16745
  var iife, fn = compressor.self();
16730
16746
  if (is_func_expr(fn)
@@ -16733,7 +16749,8 @@ function tighten_body(statements, compressor) {
16733
16749
  && !fn.pinned()
16734
16750
  && (iife = compressor.parent()) instanceof AST_Call
16735
16751
  && iife.expression === fn
16736
- && iife.args.every((arg) => !(arg instanceof AST_Expansion))) {
16752
+ && iife.args.every(arg_is_injectable)
16753
+ ) {
16737
16754
  var fn_strict = compressor.has_directive("use strict");
16738
16755
  if (fn_strict && !member(fn_strict, fn.body))
16739
16756
  fn_strict = false;
@@ -70,6 +70,7 @@ import {
70
70
  AST_SymbolFunarg,
71
71
  AST_SymbolRef,
72
72
  AST_SymbolVar,
73
+ AST_This,
73
74
  AST_Toplevel,
74
75
  AST_Unary,
75
76
  AST_Var,
@@ -126,6 +127,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
126
127
  return node.expression;
127
128
  }
128
129
  };
130
+ var this_def = null;
129
131
  var in_use_ids = new Map();
130
132
  var fixed_ids = new Map();
131
133
  if (self instanceof AST_Toplevel && compressor.top_retain) {
@@ -137,6 +139,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
137
139
  }
138
140
  var var_defs_by_id = new Map();
139
141
  var initializations = new Map();
142
+
140
143
  // pass 1: find out which symbols are directly used in
141
144
  // this scope (not in nested scopes).
142
145
  var scope = this;
@@ -149,11 +152,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
149
152
  });
150
153
  }
151
154
  if (node === self) return;
152
- if (node instanceof AST_Class) {
153
- if (node.has_side_effects(compressor)) {
154
- node.visit_nondeferred_class_parts(tw);
155
- }
156
- }
157
155
  if (node instanceof AST_Defun || node instanceof AST_DefClass) {
158
156
  var node_def = node.name.definition();
159
157
  const in_export = tw.parent() instanceof AST_Export;
@@ -163,11 +161,22 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
163
161
  }
164
162
  }
165
163
 
164
+ if (node instanceof AST_DefClass && node.has_side_effects(compressor)) {
165
+ const save_this_def = this_def;
166
+ this_def = node_def;
167
+ node.visit_nondeferred_class_parts(tw);
168
+ this_def = save_this_def;
169
+ }
170
+
166
171
  map_add(initializations, node_def.id, node);
167
172
  return true; // don't go in nested scopes
168
173
  }
169
174
  // In the root scope, we drop things. In inner scopes, we just check for uses.
170
175
  const in_root_scope = scope === self;
176
+ if (node instanceof AST_This && this_def && in_root_scope) {
177
+ in_use_ids.set(this_def.id, this_def);
178
+ return true;
179
+ }
171
180
  if (node instanceof AST_SymbolFunarg && in_root_scope) {
172
181
  map_add(var_defs_by_id, node.definition().id, node);
173
182
  }
@@ -574,6 +574,14 @@ export function tighten_body(statements, compressor) {
574
574
  return found;
575
575
  }
576
576
 
577
+ function arg_is_injectable(arg) {
578
+ if (arg instanceof AST_Expansion) return false;
579
+ const contains_await = walk(arg, (node) => {
580
+ if (node instanceof AST_Await) return walk_abort;
581
+ });
582
+ if (contains_await) return false;
583
+ return true;
584
+ }
577
585
  function extract_args() {
578
586
  var iife, fn = compressor.self();
579
587
  if (is_func_expr(fn)
@@ -582,7 +590,8 @@ export function tighten_body(statements, compressor) {
582
590
  && !fn.pinned()
583
591
  && (iife = compressor.parent()) instanceof AST_Call
584
592
  && iife.expression === fn
585
- && iife.args.every((arg) => !(arg instanceof AST_Expansion))) {
593
+ && iife.args.every(arg_is_injectable)
594
+ ) {
586
595
  var fn_strict = compressor.has_directive("use strict");
587
596
  if (fn_strict && !member(fn_strict, fn.body))
588
597
  fn_strict = false;
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.27.0",
7
+ "version": "5.27.2",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },