terser 5.13.0 → 5.14.1

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/ast.js CHANGED
@@ -93,6 +93,7 @@ const set_tok_flag = (tok, flag, truth) => {
93
93
  const TOK_FLAG_NLB = 0b0001;
94
94
  const TOK_FLAG_QUOTE_SINGLE = 0b0010;
95
95
  const TOK_FLAG_QUOTE_EXISTS = 0b0100;
96
+ const TOK_FLAG_TEMPLATE_END = 0b1000;
96
97
 
97
98
  class AST_Token {
98
99
  constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
@@ -128,6 +129,14 @@ class AST_Token {
128
129
  set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
129
130
  set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
130
131
  }
132
+
133
+ get template_end() {
134
+ return has_tok_flag(this, TOK_FLAG_TEMPLATE_END);
135
+ }
136
+
137
+ set template_end(new_template_end) {
138
+ set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end);
139
+ }
131
140
  }
132
141
 
133
142
  var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) {
@@ -552,11 +561,10 @@ var AST_With = DEFNODE("With", "expression", function AST_With(props) {
552
561
 
553
562
  var AST_Scope = DEFNODE(
554
563
  "Scope",
555
- "variables functions uses_with uses_eval parent_scope enclosed cname",
564
+ "variables uses_with uses_eval parent_scope enclosed cname",
556
565
  function AST_Scope(props) {
557
566
  if (props) {
558
567
  this.variables = props.variables;
559
- this.functions = props.functions;
560
568
  this.uses_with = props.uses_with;
561
569
  this.uses_eval = props.uses_eval;
562
570
  this.parent_scope = props.parent_scope;
@@ -612,7 +620,6 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) {
612
620
  if (props) {
613
621
  this.globals = props.globals;
614
622
  this.variables = props.variables;
615
- this.functions = props.functions;
616
623
  this.uses_with = props.uses_with;
617
624
  this.uses_eval = props.uses_eval;
618
625
  this.parent_scope = props.parent_scope;
@@ -694,7 +701,6 @@ var AST_Lambda = DEFNODE(
694
701
  this.is_generator = props.is_generator;
695
702
  this.async = props.async;
696
703
  this.variables = props.variables;
697
- this.functions = props.functions;
698
704
  this.uses_with = props.uses_with;
699
705
  this.uses_eval = props.uses_eval;
700
706
  this.parent_scope = props.parent_scope;
@@ -774,7 +780,6 @@ var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) {
774
780
  this.is_generator = props.is_generator;
775
781
  this.async = props.async;
776
782
  this.variables = props.variables;
777
- this.functions = props.functions;
778
783
  this.uses_with = props.uses_with;
779
784
  this.uses_eval = props.uses_eval;
780
785
  this.parent_scope = props.parent_scope;
@@ -799,7 +804,6 @@ var AST_Function = DEFNODE("Function", null, function AST_Function(props) {
799
804
  this.is_generator = props.is_generator;
800
805
  this.async = props.async;
801
806
  this.variables = props.variables;
802
- this.functions = props.functions;
803
807
  this.uses_with = props.uses_with;
804
808
  this.uses_eval = props.uses_eval;
805
809
  this.parent_scope = props.parent_scope;
@@ -824,7 +828,6 @@ var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) {
824
828
  this.is_generator = props.is_generator;
825
829
  this.async = props.async;
826
830
  this.variables = props.variables;
827
- this.functions = props.functions;
828
831
  this.uses_with = props.uses_with;
829
832
  this.uses_eval = props.uses_eval;
830
833
  this.parent_scope = props.parent_scope;
@@ -849,7 +852,6 @@ var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) {
849
852
  this.is_generator = props.is_generator;
850
853
  this.async = props.async;
851
854
  this.variables = props.variables;
852
- this.functions = props.functions;
853
855
  this.uses_with = props.uses_with;
854
856
  this.uses_eval = props.uses_eval;
855
857
  this.parent_scope = props.parent_scope;
@@ -2161,7 +2163,6 @@ var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(p
2161
2163
  this.extends = props.extends;
2162
2164
  this.properties = props.properties;
2163
2165
  this.variables = props.variables;
2164
- this.functions = props.functions;
2165
2166
  this.uses_with = props.uses_with;
2166
2167
  this.uses_eval = props.uses_eval;
2167
2168
  this.parent_scope = props.parent_scope;
@@ -2255,7 +2256,6 @@ var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
2255
2256
  this.extends = props.extends;
2256
2257
  this.properties = props.properties;
2257
2258
  this.variables = props.variables;
2258
- this.functions = props.functions;
2259
2259
  this.uses_with = props.uses_with;
2260
2260
  this.uses_eval = props.uses_eval;
2261
2261
  this.parent_scope = props.parent_scope;
@@ -2278,7 +2278,6 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExp
2278
2278
  this.extends = props.extends;
2279
2279
  this.properties = props.properties;
2280
2280
  this.variables = props.variables;
2281
- this.functions = props.functions;
2282
2281
  this.uses_with = props.uses_with;
2283
2282
  this.uses_eval = props.uses_eval;
2284
2283
  this.parent_scope = props.parent_scope;
@@ -2869,6 +2868,21 @@ function walk(node, cb, to_visit = [node]) {
2869
2868
  return false;
2870
2869
  }
2871
2870
 
2871
+ /**
2872
+ * Walks an AST node and its children.
2873
+ *
2874
+ * {cb} can return `walk_abort` to interrupt the walk.
2875
+ *
2876
+ * @param node
2877
+ * @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)}
2878
+ *
2879
+ * @returns {boolean} whether the walk was aborted
2880
+ *
2881
+ * @example
2882
+ * const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => {
2883
+ * if (some_cond(node, parent())) return walk_abort
2884
+ * });
2885
+ */
2872
2886
  function walk_parent(node, cb, initial_stack) {
2873
2887
  const to_visit = [node];
2874
2888
  const push = to_visit.push.bind(to_visit);
@@ -2987,6 +3001,15 @@ class TreeWalker {
2987
3001
  }
2988
3002
  }
2989
3003
 
3004
+ find_scope() {
3005
+ for (let i = 0;;i++) {
3006
+ const p = this.parent(i);
3007
+ if (p instanceof AST_Toplevel) return p;
3008
+ if (p instanceof AST_Lambda) return p;
3009
+ if (p.block_scope) return p.block_scope;
3010
+ }
3011
+ }
3012
+
2990
3013
  has_directive(type) {
2991
3014
  var dir = this.directives[type];
2992
3015
  if (dir) return dir;
@@ -80,9 +80,13 @@ import {
80
80
  AST_Undefined,
81
81
 
82
82
  TreeWalker,
83
+ walk,
84
+ walk_abort,
85
+ walk_parent,
83
86
  } from "../ast.js";
84
87
  import { make_node, regexp_source_fix, string_template, makePredicate } from "../utils/index.js";
85
88
  import { first_in_statement } from "../utils/first_in_statement.js";
89
+ import { has_flag, TOP } from "./compressor-flags.js";
86
90
 
87
91
  export function merge_sequence(array, node) {
88
92
  if (node instanceof AST_Sequence) {
@@ -244,6 +248,13 @@ export function is_iife_call(node) {
244
248
  return node.expression instanceof AST_Function || is_iife_call(node.expression);
245
249
  }
246
250
 
251
+ export function is_empty(thing) {
252
+ if (thing === null) return true;
253
+ if (thing instanceof AST_EmptyStatement) return true;
254
+ if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
255
+ return false;
256
+ }
257
+
247
258
  export const identifier_atom = makePredicate("Infinity NaN undefined");
248
259
  export function is_identifier_atom(node) {
249
260
  return node instanceof AST_Infinity
@@ -281,6 +292,34 @@ export function as_statement_array(thing) {
281
292
  throw new Error("Can't convert thing to statement array");
282
293
  }
283
294
 
295
+ export function is_reachable(scope_node, defs) {
296
+ const find_ref = node => {
297
+ if (node instanceof AST_SymbolRef && defs.includes(node.definition())) {
298
+ return walk_abort;
299
+ }
300
+ };
301
+
302
+ return walk_parent(scope_node, (node, info) => {
303
+ if (node instanceof AST_Scope && node !== scope_node) {
304
+ var parent = info.parent();
305
+
306
+ if (
307
+ parent instanceof AST_Call
308
+ && parent.expression === node
309
+ // Async/Generators aren't guaranteed to sync evaluate all of
310
+ // their body steps, so it's possible they close over the variable.
311
+ && !(node.async || node.is_generator)
312
+ ) {
313
+ return;
314
+ }
315
+
316
+ if (walk(node, find_ref)) return walk_abort;
317
+
318
+ return true;
319
+ }
320
+ });
321
+ }
322
+
284
323
  /** Check if a ref refers to the name of a function/class it's defined within */
285
324
  export function is_recursive_ref(compressor, def) {
286
325
  var node;
@@ -294,3 +333,12 @@ export function is_recursive_ref(compressor, def) {
294
333
  }
295
334
  return false;
296
335
  }
336
+
337
+ // TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
338
+ export function retain_top_func(fn, compressor) {
339
+ return compressor.top_retain
340
+ && fn instanceof AST_Defun
341
+ && has_flag(fn, TOP)
342
+ && fn.name
343
+ && compressor.top_retain(fn.name);
344
+ }