terser 5.16.3 → 5.16.5

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,20 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.16.5
4
+
5
+ - Correctly handle AST transform functions that mutate children arrays
6
+ - Don't mutate the options object passed to Terser (#1342)
7
+ - Do not treat BigInt like a number
8
+
9
+ ## v5.16.4
10
+
11
+ - Keep `(defaultArg = undefined) => ...`, because default args don't count for function length
12
+ - Prevent inlining variables into `?.` optional chains
13
+ - Avoid removing unused arguments while transforming
14
+ - Optimize iterating AST node lists
15
+ - Make sure `catch` and `finally` aren't children of `try` in the AST
16
+ - Use modern unicode property escapes (`\p{...}`) to parse identifiers when available
17
+
3
18
  ## v5.16.3
4
19
 
5
20
  - Ensure function definitions, don't assume the values of variables defined after them.
package/bin/terser.mjs ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ import "../tools/exit.cjs";
6
+
7
+ import fs from "fs";
8
+ import path from "path";
9
+ import program from "commander";
10
+
11
+ import { run_cli } from "../lib/cli.js";
12
+
13
+ const packageJson = {
14
+ name: "terser",
15
+ version: "experimental module CLI"
16
+ };
17
+
18
+ run_cli({ program, packageJson, fs, path }).catch((error) => {
19
+ console.error(error);
20
+ process.exitCode = 1;
21
+ });
@@ -100,48 +100,26 @@ function return_this() { return this; }
100
100
  function return_null() { return null; }
101
101
 
102
102
  var MAP = (function() {
103
- function MAP(a, f, backwards) {
104
- var ret = [], top = [], i;
105
- function doit() {
106
- var val = f(a[i], i);
107
- var is_last = val instanceof Last;
108
- if (is_last) val = val.v;
109
- if (val instanceof AtTop) {
110
- val = val.v;
111
- if (val instanceof Splice) {
112
- top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
113
- } else {
114
- top.push(val);
115
- }
116
- } else if (val !== skip) {
117
- if (val instanceof Splice) {
118
- ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
119
- } else {
120
- ret.push(val);
121
- }
122
- }
123
- return is_last;
124
- }
125
- if (Array.isArray(a)) {
126
- if (backwards) {
127
- for (i = a.length; --i >= 0;) if (doit()) break;
128
- ret.reverse();
129
- top.reverse();
130
- } else {
131
- for (i = 0; i < a.length; ++i) if (doit()) break;
103
+ function MAP(a, tw, allow_splicing = true) {
104
+ const new_a = [];
105
+
106
+ for (let i = 0; i < a.length; ++i) {
107
+ let item = a[i];
108
+ let ret = item.transform(tw, allow_splicing);
109
+
110
+ if (ret instanceof AST_Node) {
111
+ new_a.push(ret);
112
+ } else if (ret instanceof Splice) {
113
+ new_a.push(...ret.v);
132
114
  }
133
- } else {
134
- for (i in a) if (HOP(a, i)) if (doit()) break;
135
115
  }
136
- return top.concat(ret);
116
+
117
+ return new_a;
137
118
  }
138
- MAP.at_top = function(val) { return new AtTop(val); };
119
+
139
120
  MAP.splice = function(val) { return new Splice(val); };
140
- MAP.last = function(val) { return new Last(val); };
141
- var skip = MAP.skip = {};
142
- function AtTop(val) { this.v = val; }
121
+ MAP.skip = {};
143
122
  function Splice(val) { this.v = val; }
144
- function Last(val) { this.v = val; }
145
123
  return MAP;
146
124
  })();
147
125
 
@@ -426,6 +404,19 @@ var UNICODE = {
426
404
  ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/,
427
405
  };
428
406
 
407
+ try {
408
+ UNICODE = {
409
+ // https://262.ecma-international.org/13.0/#prod-IdentifierStartChar
410
+ // $, _, ID_Start
411
+ ID_Start: new RegExp("[_$\\p{ID_Start}]", "u"),
412
+ // https://262.ecma-international.org/13.0/#prod-IdentifierPartChar
413
+ // $, zero-width-joiner, zero-width-non-joiner, ID_Continue
414
+ ID_Continue: new RegExp("[$\\u200C\\u200D\\p{ID_Continue}]+", "u"),
415
+ };
416
+ } catch(e) {
417
+ // Could not use modern JS \p{...}. UNICODE is already defined above so let's continue
418
+ }
419
+
429
420
  function get_full_char(str, pos) {
430
421
  if (is_surrogate_pair_head(str.charCodeAt(pos))) {
431
422
  if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
@@ -2219,7 +2210,12 @@ function parse($TEXT, options) {
2219
2210
  }
2220
2211
 
2221
2212
  function try_() {
2222
- var body = block_(), bcatch = null, bfinally = null;
2213
+ var body, bcatch = null, bfinally = null;
2214
+ body = new AST_TryBlock({
2215
+ start : S.token,
2216
+ body : block_(),
2217
+ end : prev(),
2218
+ });
2223
2219
  if (is("keyword", "catch")) {
2224
2220
  var start = S.token;
2225
2221
  next();
@@ -3716,6 +3712,14 @@ class AST_Token {
3716
3712
  Object.seal(this);
3717
3713
  }
3718
3714
 
3715
+ // Return a string summary of the token for node.js console.log
3716
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
3717
+ const special = str => options.stylize(str, "special");
3718
+ const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
3719
+ const value = `${quote}${this.value}${quote}`;
3720
+ return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
3721
+ }
3722
+
3719
3723
  get nlb() {
3720
3724
  return has_tok_flag(this, TOK_FLAG_NLB);
3721
3725
  }
@@ -4862,12 +4866,11 @@ var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
4862
4866
 
4863
4867
  /* -----[ EXCEPTIONS ]----- */
4864
4868
 
4865
- var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4869
+ var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
4866
4870
  if (props) {
4871
+ this.body = props.body;
4867
4872
  this.bcatch = props.bcatch;
4868
4873
  this.bfinally = props.bfinally;
4869
- this.body = props.body;
4870
- this.block_scope = props.block_scope;
4871
4874
  this.start = props.start;
4872
4875
  this.end = props.end;
4873
4876
  }
@@ -4876,12 +4879,13 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4876
4879
  }, {
4877
4880
  $documentation: "A `try` statement",
4878
4881
  $propdoc: {
4882
+ body: "[AST_TryBlock] the try block",
4879
4883
  bcatch: "[AST_Catch?] the catch block, or null if not present",
4880
4884
  bfinally: "[AST_Finally?] the finally block, or null if not present"
4881
4885
  },
4882
4886
  _walk: function(visitor) {
4883
4887
  return visitor._visit(this, function() {
4884
- walk_body(this, visitor);
4888
+ this.body._walk(visitor);
4885
4889
  if (this.bcatch) this.bcatch._walk(visitor);
4886
4890
  if (this.bfinally) this.bfinally._walk(visitor);
4887
4891
  });
@@ -4889,9 +4893,21 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4889
4893
  _children_backwards(push) {
4890
4894
  if (this.bfinally) push(this.bfinally);
4891
4895
  if (this.bcatch) push(this.bcatch);
4892
- let i = this.body.length;
4893
- while (i--) push(this.body[i]);
4896
+ push(this.body);
4894
4897
  },
4898
+ }, AST_Statement);
4899
+
4900
+ var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
4901
+ if (props) {
4902
+ this.body = props.body;
4903
+ this.block_scope = props.block_scope;
4904
+ this.start = props.start;
4905
+ this.end = props.end;
4906
+ }
4907
+
4908
+ this.flags = 0;
4909
+ }, {
4910
+ $documentation: "The `try` block of a try statement"
4895
4911
  }, AST_Block);
4896
4912
 
4897
4913
  var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
@@ -6781,12 +6797,6 @@ function def_transform(node, descend) {
6781
6797
  });
6782
6798
  }
6783
6799
 
6784
- function do_list(list, tw) {
6785
- return MAP(list, function(node) {
6786
- return node.transform(tw, true);
6787
- });
6788
- }
6789
-
6790
6800
  def_transform(AST_Node, noop);
6791
6801
 
6792
6802
  def_transform(AST_LabeledStatement, function(self, tw) {
@@ -6799,7 +6809,7 @@ def_transform(AST_SimpleStatement, function(self, tw) {
6799
6809
  });
6800
6810
 
6801
6811
  def_transform(AST_Block, function(self, tw) {
6802
- self.body = do_list(self.body, tw);
6812
+ self.body = MAP(self.body, tw);
6803
6813
  });
6804
6814
 
6805
6815
  def_transform(AST_Do, function(self, tw) {
@@ -6846,27 +6856,27 @@ def_transform(AST_If, function(self, tw) {
6846
6856
 
6847
6857
  def_transform(AST_Switch, function(self, tw) {
6848
6858
  self.expression = self.expression.transform(tw);
6849
- self.body = do_list(self.body, tw);
6859
+ self.body = MAP(self.body, tw);
6850
6860
  });
6851
6861
 
6852
6862
  def_transform(AST_Case, function(self, tw) {
6853
6863
  self.expression = self.expression.transform(tw);
6854
- self.body = do_list(self.body, tw);
6864
+ self.body = MAP(self.body, tw);
6855
6865
  });
6856
6866
 
6857
6867
  def_transform(AST_Try, function(self, tw) {
6858
- self.body = do_list(self.body, tw);
6868
+ self.body = self.body.transform(tw);
6859
6869
  if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
6860
6870
  if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
6861
6871
  });
6862
6872
 
6863
6873
  def_transform(AST_Catch, function(self, tw) {
6864
6874
  if (self.argname) self.argname = self.argname.transform(tw);
6865
- self.body = do_list(self.body, tw);
6875
+ self.body = MAP(self.body, tw);
6866
6876
  });
6867
6877
 
6868
6878
  def_transform(AST_Definitions, function(self, tw) {
6869
- self.definitions = do_list(self.definitions, tw);
6879
+ self.definitions = MAP(self.definitions, tw);
6870
6880
  });
6871
6881
 
6872
6882
  def_transform(AST_VarDef, function(self, tw) {
@@ -6875,26 +6885,26 @@ def_transform(AST_VarDef, function(self, tw) {
6875
6885
  });
6876
6886
 
6877
6887
  def_transform(AST_Destructuring, function(self, tw) {
6878
- self.names = do_list(self.names, tw);
6888
+ self.names = MAP(self.names, tw);
6879
6889
  });
6880
6890
 
6881
6891
  def_transform(AST_Lambda, function(self, tw) {
6882
6892
  if (self.name) self.name = self.name.transform(tw);
6883
- self.argnames = do_list(self.argnames, tw);
6893
+ self.argnames = MAP(self.argnames, tw, /* allow_splicing */ false);
6884
6894
  if (self.body instanceof AST_Node) {
6885
6895
  self.body = self.body.transform(tw);
6886
6896
  } else {
6887
- self.body = do_list(self.body, tw);
6897
+ self.body = MAP(self.body, tw);
6888
6898
  }
6889
6899
  });
6890
6900
 
6891
6901
  def_transform(AST_Call, function(self, tw) {
6892
6902
  self.expression = self.expression.transform(tw);
6893
- self.args = do_list(self.args, tw);
6903
+ self.args = MAP(self.args, tw, /* allow_splicing */ false);
6894
6904
  });
6895
6905
 
6896
6906
  def_transform(AST_Sequence, function(self, tw) {
6897
- const result = do_list(self.expressions, tw);
6907
+ const result = MAP(self.expressions, tw);
6898
6908
  self.expressions = result.length
6899
6909
  ? result
6900
6910
  : [new AST_Number({ value: 0 })];
@@ -6942,11 +6952,11 @@ def_transform(AST_Conditional, function(self, tw) {
6942
6952
  });
6943
6953
 
6944
6954
  def_transform(AST_Array, function(self, tw) {
6945
- self.elements = do_list(self.elements, tw);
6955
+ self.elements = MAP(self.elements, tw);
6946
6956
  });
6947
6957
 
6948
6958
  def_transform(AST_Object, function(self, tw) {
6949
- self.properties = do_list(self.properties, tw);
6959
+ self.properties = MAP(self.properties, tw);
6950
6960
  });
6951
6961
 
6952
6962
  def_transform(AST_ObjectProperty, function(self, tw) {
@@ -6959,11 +6969,11 @@ def_transform(AST_ObjectProperty, function(self, tw) {
6959
6969
  def_transform(AST_Class, function(self, tw) {
6960
6970
  if (self.name) self.name = self.name.transform(tw);
6961
6971
  if (self.extends) self.extends = self.extends.transform(tw);
6962
- self.properties = do_list(self.properties, tw);
6972
+ self.properties = MAP(self.properties, tw);
6963
6973
  });
6964
6974
 
6965
6975
  def_transform(AST_ClassStaticBlock, function(self, tw) {
6966
- self.body = do_list(self.body, tw);
6976
+ self.body = MAP(self.body, tw);
6967
6977
  });
6968
6978
 
6969
6979
  def_transform(AST_Expansion, function(self, tw) {
@@ -6977,19 +6987,19 @@ def_transform(AST_NameMapping, function(self, tw) {
6977
6987
 
6978
6988
  def_transform(AST_Import, function(self, tw) {
6979
6989
  if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
6980
- if (self.imported_names) do_list(self.imported_names, tw);
6990
+ if (self.imported_names) MAP(self.imported_names, tw);
6981
6991
  self.module_name = self.module_name.transform(tw);
6982
6992
  });
6983
6993
 
6984
6994
  def_transform(AST_Export, function(self, tw) {
6985
6995
  if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
6986
6996
  if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
6987
- if (self.exported_names) do_list(self.exported_names, tw);
6997
+ if (self.exported_names) MAP(self.exported_names, tw);
6988
6998
  if (self.module_name) self.module_name = self.module_name.transform(tw);
6989
6999
  });
6990
7000
 
6991
7001
  def_transform(AST_TemplateString, function(self, tw) {
6992
- self.segments = do_list(self.segments, tw);
7002
+ self.segments = MAP(self.segments, tw);
6993
7003
  });
6994
7004
 
6995
7005
  def_transform(AST_PrefixedTemplateString, function(self, tw) {
@@ -7222,7 +7232,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7222
7232
  return new AST_Try({
7223
7233
  start : my_start_token(M),
7224
7234
  end : my_end_token(M),
7225
- body : from_moz(M.block).body,
7235
+ body : new AST_TryBlock(from_moz(M.block)),
7226
7236
  bcatch : from_moz(handlers[0]),
7227
7237
  bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
7228
7238
  });
@@ -8193,7 +8203,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8193
8203
  def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
8194
8204
  return {
8195
8205
  type: "TryStatement",
8196
- block: to_moz_block(M),
8206
+ block: to_moz_block(M.body),
8197
8207
  handler: to_moz(M.bcatch),
8198
8208
  guardedHandlers: [],
8199
8209
  finalizer: to_moz(M.bfinally)
@@ -10273,7 +10283,7 @@ function OutputStream(options) {
10273
10283
  DEFPRINT(AST_Try, function(self, output) {
10274
10284
  output.print("try");
10275
10285
  output.space();
10276
- print_braced(self, output);
10286
+ self.body.print(output);
10277
10287
  if (self.bcatch) {
10278
10288
  output.space();
10279
10289
  self.bcatch.print(output);
@@ -10283,6 +10293,9 @@ function OutputStream(options) {
10283
10293
  self.bfinally.print(output);
10284
10294
  }
10285
10295
  });
10296
+ DEFPRINT(AST_TryBlock, function(self, output) {
10297
+ print_braced(self, output);
10298
+ });
10286
10299
  DEFPRINT(AST_Catch, function(self, output) {
10287
10300
  output.print("catch");
10288
10301
  if (self.argname) {
@@ -11175,7 +11188,7 @@ AST_Switch.prototype.shallow_cmp = pass_through;
11175
11188
  AST_SwitchBranch.prototype.shallow_cmp = pass_through;
11176
11189
 
11177
11190
  AST_Try.prototype.shallow_cmp = function(other) {
11178
- return (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
11191
+ return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
11179
11192
  };
11180
11193
 
11181
11194
  AST_Catch.prototype.shallow_cmp = function(other) {
@@ -11442,12 +11455,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
11442
11455
  const save_scope = scope;
11443
11456
  node.block_scope = scope = new AST_Scope(node);
11444
11457
  scope._block_scope = true;
11445
- // AST_Try in the AST sadly *is* (not has) a body itself,
11446
- // and its catch and finally branches are children of the AST_Try itself
11447
- const parent_scope = node instanceof AST_Catch
11448
- ? save_scope.parent_scope
11449
- : save_scope;
11450
- scope.init_scope_vars(parent_scope);
11458
+ scope.init_scope_vars(save_scope);
11451
11459
  scope.uses_with = save_scope.uses_with;
11452
11460
  scope.uses_eval = save_scope.uses_eval;
11453
11461
 
@@ -11462,7 +11470,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
11462
11470
  // AST_Switch has a scope within the body, but it itself "is a block scope"
11463
11471
  // This means the switched expression has to belong to the outer scope
11464
11472
  // while the body inside belongs to the switch itself.
11465
- // This is pretty nasty and warrants an AST change similar to AST_Try (read above)
11473
+ // This is pretty nasty and warrants an AST change
11466
11474
  const the_block_scope = scope;
11467
11475
  scope = save_scope;
11468
11476
  node.expression.walk(tw);
@@ -12408,9 +12416,7 @@ AST_Default.prototype._size = function () {
12408
12416
  return 8 + list_overhead(this.body);
12409
12417
  };
12410
12418
 
12411
- AST_Try.prototype._size = function () {
12412
- return 3 + list_overhead(this.body);
12413
- };
12419
+ AST_Try.prototype._size = () => 3;
12414
12420
 
12415
12421
  AST_Catch.prototype._size = function () {
12416
12422
  let size = 7 + list_overhead(this.body);
@@ -13345,7 +13351,7 @@ const unary_side_effects = makePredicate("delete ++ --");
13345
13351
  def_is_number(AST_Number, return_true);
13346
13352
  const unary = makePredicate("+ - ~ ++ --");
13347
13353
  def_is_number(AST_Unary, function() {
13348
- return unary.has(this.operator);
13354
+ return unary.has(this.operator) && !(this.expression instanceof AST_BigInt);
13349
13355
  });
13350
13356
  const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
13351
13357
  def_is_number(AST_Binary, function(compressor) {
@@ -13474,7 +13480,7 @@ function is_nullish(node, compressor) {
13474
13480
  || any(this.body, compressor);
13475
13481
  });
13476
13482
  def_has_side_effects(AST_Try, function(compressor) {
13477
- return any(this.body, compressor)
13483
+ return this.body.has_side_effects(compressor)
13478
13484
  || this.bcatch && this.bcatch.has_side_effects(compressor)
13479
13485
  || this.bfinally && this.bfinally.has_side_effects(compressor);
13480
13486
  });
@@ -13703,7 +13709,7 @@ function is_nullish(node, compressor) {
13703
13709
  });
13704
13710
  def_may_throw(AST_SymbolClassProperty, return_false);
13705
13711
  def_may_throw(AST_Try, function(compressor) {
13706
- return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
13712
+ return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
13707
13713
  || this.bfinally && this.bfinally.may_throw(compressor);
13708
13714
  });
13709
13715
  def_may_throw(AST_Unary, function(compressor) {
@@ -15873,7 +15879,7 @@ def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
15873
15879
  def_reduce_vars(AST_Try, function(tw, descend, compressor) {
15874
15880
  reset_block_variables(compressor, this);
15875
15881
  push(tw);
15876
- walk_body(this, tw);
15882
+ this.body.walk(tw);
15877
15883
  pop(tw);
15878
15884
  if (this.bcatch) {
15879
15885
  push(tw);
@@ -16077,13 +16083,11 @@ function tighten_body(statements, compressor) {
16077
16083
  function find_loop_scope_try() {
16078
16084
  var node = compressor.self(), level = 0, in_loop = false, in_try = false;
16079
16085
  do {
16080
- if (node instanceof AST_Catch || node instanceof AST_Finally) {
16081
- level++;
16082
- } else if (node instanceof AST_IterationStatement) {
16086
+ if (node instanceof AST_IterationStatement) {
16083
16087
  in_loop = true;
16084
16088
  } else if (node instanceof AST_Scope) {
16085
16089
  break;
16086
- } else if (node instanceof AST_Try) {
16090
+ } else if (node instanceof AST_TryBlock) {
16087
16091
  in_try = true;
16088
16092
  }
16089
16093
  } while (node = compressor.parent(level++));
@@ -16127,6 +16131,9 @@ function tighten_body(statements, compressor) {
16127
16131
  && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
16128
16132
  || node instanceof AST_Await
16129
16133
  || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
16134
+ ||
16135
+ (node instanceof AST_Call || node instanceof AST_PropAccess)
16136
+ && node.optional
16130
16137
  || node instanceof AST_Debugger
16131
16138
  || node instanceof AST_Destructuring
16132
16139
  || node instanceof AST_Expansion
@@ -16300,7 +16307,11 @@ function tighten_body(statements, compressor) {
16300
16307
  var hit = funarg;
16301
16308
  var abort = false, replaced = 0, can_replace = !args || !hit;
16302
16309
  if (!can_replace) {
16303
- for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
16310
+ for (
16311
+ let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
16312
+ !abort && j < args.length;
16313
+ j++
16314
+ ) {
16304
16315
  args[j].transform(scanner);
16305
16316
  }
16306
16317
  can_replace = true;
@@ -19228,9 +19239,9 @@ def_optimize(AST_Switch, function(self, compressor) {
19228
19239
  });
19229
19240
 
19230
19241
  def_optimize(AST_Try, function(self, compressor) {
19231
- tighten_body(self.body, compressor);
19232
19242
  if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
19233
- if (compressor.option("dead_code") && self.body.every(is_empty)) {
19243
+
19244
+ if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
19234
19245
  var body = [];
19235
19246
  if (self.bcatch) {
19236
19247
  trim_unreachable_code(compressor, self.bcatch, body);
@@ -20436,16 +20447,21 @@ def_optimize(AST_Assign, function(self, compressor) {
20436
20447
  return self;
20437
20448
 
20438
20449
  function in_try(level, node) {
20439
- var right = self.right;
20440
- self.right = make_node(AST_Null, right);
20441
- var may_throw = node.may_throw(compressor);
20442
- self.right = right;
20443
- var scope = self.left.definition().scope;
20450
+ function may_assignment_throw() {
20451
+ const right = self.right;
20452
+ self.right = make_node(AST_Null, right);
20453
+ const may_throw = node.may_throw(compressor);
20454
+ self.right = right;
20455
+
20456
+ return may_throw;
20457
+ }
20458
+
20459
+ var stop_at = self.left.definition().scope.get_defun_scope();
20444
20460
  var parent;
20445
- while ((parent = compressor.parent(level++)) !== scope) {
20461
+ while ((parent = compressor.parent(level++)) !== stop_at) {
20446
20462
  if (parent instanceof AST_Try) {
20447
20463
  if (parent.bfinally) return true;
20448
- if (may_throw && parent.bcatch) return true;
20464
+ if (parent.bcatch && may_assignment_throw()) return true;
20449
20465
  }
20450
20466
  }
20451
20467
  }
@@ -20458,7 +20474,13 @@ def_optimize(AST_DefaultAssign, function(self, compressor) {
20458
20474
  var evaluateRight = self.right.evaluate(compressor);
20459
20475
 
20460
20476
  // `[x = undefined] = foo` ---> `[x] = foo`
20461
- if (evaluateRight === undefined) {
20477
+ // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
20478
+ if (
20479
+ evaluateRight === undefined &&
20480
+ (compressor.parent() instanceof AST_Lambda
20481
+ ? compressor.option("keep_fargs") === false
20482
+ : true)
20483
+ ) {
20462
20484
  self = self.left;
20463
20485
  } else if (evaluateRight !== self.right) {
20464
20486
  evaluateRight = make_node_from_constant(evaluateRight, self.right);
@@ -29973,10 +29995,13 @@ async function minify(files, options, _fs_module) {
29973
29995
  if (options.format.spidermonkey) {
29974
29996
  result.ast = toplevel.to_mozilla_ast();
29975
29997
  }
29998
+ let format_options;
29976
29999
  if (!HOP(options.format, "code") || options.format.code) {
29977
- if (!options.format.ast) {
30000
+ // Make a shallow copy so that we can modify without mutating the user's input.
30001
+ format_options = {...options.format};
30002
+ if (!format_options.ast) {
29978
30003
  // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
29979
- options.format._destroy_ast = true;
30004
+ format_options._destroy_ast = true;
29980
30005
 
29981
30006
  walk(toplevel, node => {
29982
30007
  if (node instanceof AST_Scope) {
@@ -29996,17 +30021,17 @@ async function minify(files, options, _fs_module) {
29996
30021
  if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
29997
30022
  throw new Error("original source content unavailable");
29998
30023
  }
29999
- options.format.source_map = await SourceMap({
30024
+ format_options.source_map = await SourceMap({
30000
30025
  file: options.sourceMap.filename,
30001
30026
  orig: options.sourceMap.content,
30002
30027
  root: options.sourceMap.root,
30003
30028
  files: options.sourceMap.includeSources ? files : null,
30004
30029
  });
30005
30030
  }
30006
- delete options.format.ast;
30007
- delete options.format.code;
30008
- delete options.format.spidermonkey;
30009
- var stream = OutputStream(options.format);
30031
+ delete format_options.ast;
30032
+ delete format_options.code;
30033
+ delete format_options.spidermonkey;
30034
+ var stream = OutputStream(format_options);
30010
30035
  toplevel.print(stream);
30011
30036
  result.code = stream.get();
30012
30037
  if (options.sourceMap) {
@@ -30014,7 +30039,7 @@ async function minify(files, options, _fs_module) {
30014
30039
  configurable: true,
30015
30040
  enumerable: true,
30016
30041
  get() {
30017
- const map = options.format.source_map.getEncoded();
30042
+ const map = format_options.source_map.getEncoded();
30018
30043
  return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
30019
30044
  },
30020
30045
  set(value) {
@@ -30024,7 +30049,7 @@ async function minify(files, options, _fs_module) {
30024
30049
  });
30025
30050
  }
30026
30051
  });
30027
- result.decoded_map = options.format.source_map.getDecoded();
30052
+ result.decoded_map = format_options.source_map.getDecoded();
30028
30053
  if (options.sourceMap.url == "inline") {
30029
30054
  var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
30030
30055
  result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
@@ -30039,8 +30064,8 @@ async function minify(files, options, _fs_module) {
30039
30064
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
30040
30065
  }
30041
30066
  }
30042
- if (options.format && options.format.source_map) {
30043
- options.format.source_map.destroy();
30067
+ if (format_options && format_options.source_map) {
30068
+ format_options.source_map.destroy();
30044
30069
  }
30045
30070
  if (timings) {
30046
30071
  timings.end = Date.now();
package/lib/ast.js CHANGED
@@ -111,6 +111,14 @@ class AST_Token {
111
111
  Object.seal(this);
112
112
  }
113
113
 
114
+ // Return a string summary of the token for node.js console.log
115
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
116
+ const special = str => options.stylize(str, "special");
117
+ const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
118
+ const value = `${quote}${this.value}${quote}`;
119
+ return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
120
+ }
121
+
114
122
  get nlb() {
115
123
  return has_tok_flag(this, TOK_FLAG_NLB);
116
124
  }
@@ -1257,12 +1265,11 @@ var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
1257
1265
 
1258
1266
  /* -----[ EXCEPTIONS ]----- */
1259
1267
 
1260
- var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
1268
+ var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
1261
1269
  if (props) {
1270
+ this.body = props.body;
1262
1271
  this.bcatch = props.bcatch;
1263
1272
  this.bfinally = props.bfinally;
1264
- this.body = props.body;
1265
- this.block_scope = props.block_scope;
1266
1273
  this.start = props.start;
1267
1274
  this.end = props.end;
1268
1275
  }
@@ -1271,12 +1278,13 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
1271
1278
  }, {
1272
1279
  $documentation: "A `try` statement",
1273
1280
  $propdoc: {
1281
+ body: "[AST_TryBlock] the try block",
1274
1282
  bcatch: "[AST_Catch?] the catch block, or null if not present",
1275
1283
  bfinally: "[AST_Finally?] the finally block, or null if not present"
1276
1284
  },
1277
1285
  _walk: function(visitor) {
1278
1286
  return visitor._visit(this, function() {
1279
- walk_body(this, visitor);
1287
+ this.body._walk(visitor);
1280
1288
  if (this.bcatch) this.bcatch._walk(visitor);
1281
1289
  if (this.bfinally) this.bfinally._walk(visitor);
1282
1290
  });
@@ -1284,9 +1292,21 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
1284
1292
  _children_backwards(push) {
1285
1293
  if (this.bfinally) push(this.bfinally);
1286
1294
  if (this.bcatch) push(this.bcatch);
1287
- let i = this.body.length;
1288
- while (i--) push(this.body[i]);
1295
+ push(this.body);
1289
1296
  },
1297
+ }, AST_Statement);
1298
+
1299
+ var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
1300
+ if (props) {
1301
+ this.body = props.body;
1302
+ this.block_scope = props.block_scope;
1303
+ this.start = props.start;
1304
+ this.end = props.end;
1305
+ }
1306
+
1307
+ this.flags = 0;
1308
+ }, {
1309
+ $documentation: "The `try` block of a try statement"
1290
1310
  }, AST_Block);
1291
1311
 
1292
1312
  var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
@@ -3235,6 +3255,7 @@ export {
3235
3255
  AST_Toplevel,
3236
3256
  AST_True,
3237
3257
  AST_Try,
3258
+ AST_TryBlock,
3238
3259
  AST_Unary,
3239
3260
  AST_UnaryPostfix,
3240
3261
  AST_UnaryPrefix,
@@ -1529,9 +1529,9 @@ def_optimize(AST_Switch, function(self, compressor) {
1529
1529
  });
1530
1530
 
1531
1531
  def_optimize(AST_Try, function(self, compressor) {
1532
- tighten_body(self.body, compressor);
1533
1532
  if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
1534
- if (compressor.option("dead_code") && self.body.every(is_empty)) {
1533
+
1534
+ if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
1535
1535
  var body = [];
1536
1536
  if (self.bcatch) {
1537
1537
  trim_unreachable_code(compressor, self.bcatch, body);
@@ -2737,16 +2737,21 @@ def_optimize(AST_Assign, function(self, compressor) {
2737
2737
  return self;
2738
2738
 
2739
2739
  function in_try(level, node) {
2740
- var right = self.right;
2741
- self.right = make_node(AST_Null, right);
2742
- var may_throw = node.may_throw(compressor);
2743
- self.right = right;
2744
- var scope = self.left.definition().scope;
2740
+ function may_assignment_throw() {
2741
+ const right = self.right;
2742
+ self.right = make_node(AST_Null, right);
2743
+ const may_throw = node.may_throw(compressor);
2744
+ self.right = right;
2745
+
2746
+ return may_throw;
2747
+ }
2748
+
2749
+ var stop_at = self.left.definition().scope.get_defun_scope();
2745
2750
  var parent;
2746
- while ((parent = compressor.parent(level++)) !== scope) {
2751
+ while ((parent = compressor.parent(level++)) !== stop_at) {
2747
2752
  if (parent instanceof AST_Try) {
2748
2753
  if (parent.bfinally) return true;
2749
- if (may_throw && parent.bcatch) return true;
2754
+ if (parent.bcatch && may_assignment_throw()) return true;
2750
2755
  }
2751
2756
  }
2752
2757
  }
@@ -2759,7 +2764,13 @@ def_optimize(AST_DefaultAssign, function(self, compressor) {
2759
2764
  var evaluateRight = self.right.evaluate(compressor);
2760
2765
 
2761
2766
  // `[x = undefined] = foo` ---> `[x] = foo`
2762
- if (evaluateRight === undefined) {
2767
+ // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
2768
+ if (
2769
+ evaluateRight === undefined &&
2770
+ (compressor.parent() instanceof AST_Lambda
2771
+ ? compressor.option("keep_fargs") === false
2772
+ : true)
2773
+ ) {
2763
2774
  self = self.left;
2764
2775
  } else if (evaluateRight !== self.right) {
2765
2776
  evaluateRight = make_node_from_constant(evaluateRight, self.right);
@@ -45,6 +45,7 @@ import {
45
45
  AST_Array,
46
46
  AST_Arrow,
47
47
  AST_Assign,
48
+ AST_BigInt,
48
49
  AST_Binary,
49
50
  AST_Block,
50
51
  AST_BlockStatement,
@@ -171,7 +172,7 @@ export const unary_side_effects = makePredicate("delete ++ --");
171
172
  def_is_number(AST_Number, return_true);
172
173
  const unary = makePredicate("+ - ~ ++ --");
173
174
  def_is_number(AST_Unary, function() {
174
- return unary.has(this.operator);
175
+ return unary.has(this.operator) && !(this.expression instanceof AST_BigInt);
175
176
  });
176
177
  const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
177
178
  def_is_number(AST_Binary, function(compressor) {
@@ -300,7 +301,7 @@ export function is_nullish(node, compressor) {
300
301
  || any(this.body, compressor);
301
302
  });
302
303
  def_has_side_effects(AST_Try, function(compressor) {
303
- return any(this.body, compressor)
304
+ return this.body.has_side_effects(compressor)
304
305
  || this.bcatch && this.bcatch.has_side_effects(compressor)
305
306
  || this.bfinally && this.bfinally.has_side_effects(compressor);
306
307
  });
@@ -529,7 +530,7 @@ export function is_nullish(node, compressor) {
529
530
  });
530
531
  def_may_throw(AST_SymbolClassProperty, return_false);
531
532
  def_may_throw(AST_Try, function(compressor) {
532
- return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
533
+ return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
533
534
  || this.bfinally && this.bfinally.may_throw(compressor);
534
535
  });
535
536
  def_may_throw(AST_Unary, function(compressor) {
@@ -624,7 +624,7 @@ def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
624
624
  def_reduce_vars(AST_Try, function(tw, descend, compressor) {
625
625
  reset_block_variables(compressor, this);
626
626
  push(tw);
627
- walk_body(this, tw);
627
+ this.body.walk(tw);
628
628
  pop(tw);
629
629
  if (this.bcatch) {
630
630
  push(tw);
@@ -52,7 +52,6 @@ import {
52
52
  AST_Break,
53
53
  AST_Call,
54
54
  AST_Case,
55
- AST_Catch,
56
55
  AST_Chain,
57
56
  AST_Class,
58
57
  AST_Conditional,
@@ -71,7 +70,6 @@ import {
71
70
  AST_Exit,
72
71
  AST_Expansion,
73
72
  AST_Export,
74
- AST_Finally,
75
73
  AST_For,
76
74
  AST_ForIn,
77
75
  AST_If,
@@ -103,6 +101,7 @@ import {
103
101
  AST_SymbolVar,
104
102
  AST_This,
105
103
  AST_Try,
104
+ AST_TryBlock,
106
105
  AST_Unary,
107
106
  AST_UnaryPostfix,
108
107
  AST_UnaryPrefix,
@@ -234,13 +233,11 @@ export function tighten_body(statements, compressor) {
234
233
  function find_loop_scope_try() {
235
234
  var node = compressor.self(), level = 0, in_loop = false, in_try = false;
236
235
  do {
237
- if (node instanceof AST_Catch || node instanceof AST_Finally) {
238
- level++;
239
- } else if (node instanceof AST_IterationStatement) {
236
+ if (node instanceof AST_IterationStatement) {
240
237
  in_loop = true;
241
238
  } else if (node instanceof AST_Scope) {
242
239
  break;
243
- } else if (node instanceof AST_Try) {
240
+ } else if (node instanceof AST_TryBlock) {
244
241
  in_try = true;
245
242
  }
246
243
  } while (node = compressor.parent(level++));
@@ -284,6 +281,9 @@ export function tighten_body(statements, compressor) {
284
281
  && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
285
282
  || node instanceof AST_Await
286
283
  || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
284
+ ||
285
+ (node instanceof AST_Call || node instanceof AST_PropAccess)
286
+ && node.optional
287
287
  || node instanceof AST_Debugger
288
288
  || node instanceof AST_Destructuring
289
289
  || node instanceof AST_Expansion
@@ -457,7 +457,11 @@ export function tighten_body(statements, compressor) {
457
457
  var hit = funarg;
458
458
  var abort = false, replaced = 0, can_replace = !args || !hit;
459
459
  if (!can_replace) {
460
- for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
460
+ for (
461
+ let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
462
+ !abort && j < args.length;
463
+ j++
464
+ ) {
461
465
  args[j].transform(scanner);
462
466
  }
463
467
  can_replace = true;
@@ -172,7 +172,7 @@ AST_Switch.prototype.shallow_cmp = pass_through;
172
172
  AST_SwitchBranch.prototype.shallow_cmp = pass_through;
173
173
 
174
174
  AST_Try.prototype.shallow_cmp = function(other) {
175
- return (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
175
+ return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
176
176
  };
177
177
 
178
178
  AST_Catch.prototype.shallow_cmp = function(other) {
package/lib/minify.js CHANGED
@@ -280,10 +280,13 @@ async function minify(files, options, _fs_module) {
280
280
  if (options.format.spidermonkey) {
281
281
  result.ast = toplevel.to_mozilla_ast();
282
282
  }
283
+ let format_options;
283
284
  if (!HOP(options.format, "code") || options.format.code) {
284
- if (!options.format.ast) {
285
+ // Make a shallow copy so that we can modify without mutating the user's input.
286
+ format_options = {...options.format};
287
+ if (!format_options.ast) {
285
288
  // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
286
- options.format._destroy_ast = true;
289
+ format_options._destroy_ast = true;
287
290
 
288
291
  walk(toplevel, node => {
289
292
  if (node instanceof AST_Scope) {
@@ -303,17 +306,17 @@ async function minify(files, options, _fs_module) {
303
306
  if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
304
307
  throw new Error("original source content unavailable");
305
308
  }
306
- options.format.source_map = await SourceMap({
309
+ format_options.source_map = await SourceMap({
307
310
  file: options.sourceMap.filename,
308
311
  orig: options.sourceMap.content,
309
312
  root: options.sourceMap.root,
310
313
  files: options.sourceMap.includeSources ? files : null,
311
314
  });
312
315
  }
313
- delete options.format.ast;
314
- delete options.format.code;
315
- delete options.format.spidermonkey;
316
- var stream = OutputStream(options.format);
316
+ delete format_options.ast;
317
+ delete format_options.code;
318
+ delete format_options.spidermonkey;
319
+ var stream = OutputStream(format_options);
317
320
  toplevel.print(stream);
318
321
  result.code = stream.get();
319
322
  if (options.sourceMap) {
@@ -321,7 +324,7 @@ async function minify(files, options, _fs_module) {
321
324
  configurable: true,
322
325
  enumerable: true,
323
326
  get() {
324
- const map = options.format.source_map.getEncoded();
327
+ const map = format_options.source_map.getEncoded();
325
328
  return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
326
329
  },
327
330
  set(value) {
@@ -331,7 +334,7 @@ async function minify(files, options, _fs_module) {
331
334
  });
332
335
  }
333
336
  });
334
- result.decoded_map = options.format.source_map.getDecoded();
337
+ result.decoded_map = format_options.source_map.getDecoded();
335
338
  if (options.sourceMap.url == "inline") {
336
339
  var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
337
340
  result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
@@ -346,8 +349,8 @@ async function minify(files, options, _fs_module) {
346
349
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
347
350
  }
348
351
  }
349
- if (options.format && options.format.source_map) {
350
- options.format.source_map.destroy();
352
+ if (format_options && format_options.source_map) {
353
+ format_options.source_map.destroy();
351
354
  }
352
355
  if (timings) {
353
356
  timings.end = Date.now();
@@ -151,6 +151,7 @@ import {
151
151
  AST_Toplevel,
152
152
  AST_True,
153
153
  AST_Try,
154
+ AST_TryBlock,
154
155
  AST_Unary,
155
156
  AST_UnaryPostfix,
156
157
  AST_UnaryPrefix,
@@ -344,7 +345,7 @@ import { is_basic_identifier_string } from "./parse.js";
344
345
  return new AST_Try({
345
346
  start : my_start_token(M),
346
347
  end : my_end_token(M),
347
- body : from_moz(M.block).body,
348
+ body : new AST_TryBlock(from_moz(M.block)),
348
349
  bcatch : from_moz(handlers[0]),
349
350
  bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
350
351
  });
@@ -1315,7 +1316,7 @@ import { is_basic_identifier_string } from "./parse.js";
1315
1316
  def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
1316
1317
  return {
1317
1318
  type: "TryStatement",
1318
- block: to_moz_block(M),
1319
+ block: to_moz_block(M.body),
1319
1320
  handler: to_moz(M.bcatch),
1320
1321
  guardedHandlers: [],
1321
1322
  finalizer: to_moz(M.bfinally)
package/lib/output.js CHANGED
@@ -143,6 +143,7 @@ import {
143
143
  AST_Throw,
144
144
  AST_Toplevel,
145
145
  AST_Try,
146
+ AST_TryBlock,
146
147
  AST_Unary,
147
148
  AST_UnaryPostfix,
148
149
  AST_UnaryPrefix,
@@ -1620,7 +1621,7 @@ function OutputStream(options) {
1620
1621
  DEFPRINT(AST_Try, function(self, output) {
1621
1622
  output.print("try");
1622
1623
  output.space();
1623
- print_braced(self, output);
1624
+ self.body.print(output);
1624
1625
  if (self.bcatch) {
1625
1626
  output.space();
1626
1627
  self.bcatch.print(output);
@@ -1630,6 +1631,9 @@ function OutputStream(options) {
1630
1631
  self.bfinally.print(output);
1631
1632
  }
1632
1633
  });
1634
+ DEFPRINT(AST_TryBlock, function(self, output) {
1635
+ print_braced(self, output);
1636
+ });
1633
1637
  DEFPRINT(AST_Catch, function(self, output) {
1634
1638
  output.print("catch");
1635
1639
  if (self.argname) {
package/lib/parse.js CHANGED
@@ -152,6 +152,7 @@ import {
152
152
  AST_Toplevel,
153
153
  AST_True,
154
154
  AST_Try,
155
+ AST_TryBlock,
155
156
  AST_UnaryPostfix,
156
157
  AST_UnaryPrefix,
157
158
  AST_Var,
@@ -260,6 +261,19 @@ var UNICODE = {
260
261
  ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/,
261
262
  };
262
263
 
264
+ try {
265
+ UNICODE = {
266
+ // https://262.ecma-international.org/13.0/#prod-IdentifierStartChar
267
+ // $, _, ID_Start
268
+ ID_Start: new RegExp("[_$\\p{ID_Start}]", "u"),
269
+ // https://262.ecma-international.org/13.0/#prod-IdentifierPartChar
270
+ // $, zero-width-joiner, zero-width-non-joiner, ID_Continue
271
+ ID_Continue: new RegExp("[$\\u200C\\u200D\\p{ID_Continue}]+", "u"),
272
+ };
273
+ } catch(e) {
274
+ // Could not use modern JS \p{...}. UNICODE is already defined above so let's continue
275
+ }
276
+
263
277
  function get_full_char(str, pos) {
264
278
  if (is_surrogate_pair_head(str.charCodeAt(pos))) {
265
279
  if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
@@ -2053,7 +2067,12 @@ function parse($TEXT, options) {
2053
2067
  }
2054
2068
 
2055
2069
  function try_() {
2056
- var body = block_(), bcatch = null, bfinally = null;
2070
+ var body, bcatch = null, bfinally = null;
2071
+ body = new AST_TryBlock({
2072
+ start : S.token,
2073
+ body : block_(),
2074
+ end : prev(),
2075
+ });
2057
2076
  if (is("keyword", "catch")) {
2058
2077
  var start = S.token;
2059
2078
  next();
package/lib/scope.js CHANGED
@@ -58,7 +58,6 @@ import {
58
58
  AST_Arrow,
59
59
  AST_Block,
60
60
  AST_Call,
61
- AST_Catch,
62
61
  AST_Class,
63
62
  AST_Conditional,
64
63
  AST_DefClass,
@@ -223,12 +222,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
223
222
  const save_scope = scope;
224
223
  node.block_scope = scope = new AST_Scope(node);
225
224
  scope._block_scope = true;
226
- // AST_Try in the AST sadly *is* (not has) a body itself,
227
- // and its catch and finally branches are children of the AST_Try itself
228
- const parent_scope = node instanceof AST_Catch
229
- ? save_scope.parent_scope
230
- : save_scope;
231
- scope.init_scope_vars(parent_scope);
225
+ scope.init_scope_vars(save_scope);
232
226
  scope.uses_with = save_scope.uses_with;
233
227
  scope.uses_eval = save_scope.uses_eval;
234
228
 
@@ -243,7 +237,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
243
237
  // AST_Switch has a scope within the body, but it itself "is a block scope"
244
238
  // This means the switched expression has to belong to the outer scope
245
239
  // while the body inside belongs to the switch itself.
246
- // This is pretty nasty and warrants an AST change similar to AST_Try (read above)
240
+ // This is pretty nasty and warrants an AST change
247
241
  const the_block_scope = scope;
248
242
  scope = save_scope;
249
243
  node.expression.walk(tw);
package/lib/size.js CHANGED
@@ -216,9 +216,7 @@ AST_Default.prototype._size = function () {
216
216
  return 8 + list_overhead(this.body);
217
217
  };
218
218
 
219
- AST_Try.prototype._size = function () {
220
- return 3 + list_overhead(this.body);
221
- };
219
+ AST_Try.prototype._size = () => 3;
222
220
 
223
221
  AST_Catch.prototype._size = function () {
224
222
  let size = 7 + list_overhead(this.body);
package/lib/transform.js CHANGED
@@ -89,7 +89,7 @@ import {
89
89
  AST_Yield,
90
90
  } from "./ast.js";
91
91
  import {
92
- MAP,
92
+ MAP as do_list,
93
93
  noop,
94
94
  } from "./utils/index.js";
95
95
 
@@ -111,12 +111,6 @@ function def_transform(node, descend) {
111
111
  });
112
112
  }
113
113
 
114
- function do_list(list, tw) {
115
- return MAP(list, function(node) {
116
- return node.transform(tw, true);
117
- });
118
- }
119
-
120
114
  def_transform(AST_Node, noop);
121
115
 
122
116
  def_transform(AST_LabeledStatement, function(self, tw) {
@@ -185,7 +179,7 @@ def_transform(AST_Case, function(self, tw) {
185
179
  });
186
180
 
187
181
  def_transform(AST_Try, function(self, tw) {
188
- self.body = do_list(self.body, tw);
182
+ self.body = self.body.transform(tw);
189
183
  if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
190
184
  if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
191
185
  });
@@ -210,7 +204,7 @@ def_transform(AST_Destructuring, function(self, tw) {
210
204
 
211
205
  def_transform(AST_Lambda, function(self, tw) {
212
206
  if (self.name) self.name = self.name.transform(tw);
213
- self.argnames = do_list(self.argnames, tw);
207
+ self.argnames = do_list(self.argnames, tw, /* allow_splicing */ false);
214
208
  if (self.body instanceof AST_Node) {
215
209
  self.body = self.body.transform(tw);
216
210
  } else {
@@ -220,7 +214,7 @@ def_transform(AST_Lambda, function(self, tw) {
220
214
 
221
215
  def_transform(AST_Call, function(self, tw) {
222
216
  self.expression = self.expression.transform(tw);
223
- self.args = do_list(self.args, tw);
217
+ self.args = do_list(self.args, tw, /* allow_splicing */ false);
224
218
  });
225
219
 
226
220
  def_transform(AST_Sequence, function(self, tw) {
@@ -43,6 +43,8 @@
43
43
 
44
44
  "use strict";
45
45
 
46
+ import { AST_Node } from "../ast.js";
47
+
46
48
  function characters(str) {
47
49
  return str.split("");
48
50
  }
@@ -96,48 +98,26 @@ function return_this() { return this; }
96
98
  function return_null() { return null; }
97
99
 
98
100
  var MAP = (function() {
99
- function MAP(a, f, backwards) {
100
- var ret = [], top = [], i;
101
- function doit() {
102
- var val = f(a[i], i);
103
- var is_last = val instanceof Last;
104
- if (is_last) val = val.v;
105
- if (val instanceof AtTop) {
106
- val = val.v;
107
- if (val instanceof Splice) {
108
- top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
109
- } else {
110
- top.push(val);
111
- }
112
- } else if (val !== skip) {
113
- if (val instanceof Splice) {
114
- ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
115
- } else {
116
- ret.push(val);
117
- }
118
- }
119
- return is_last;
120
- }
121
- if (Array.isArray(a)) {
122
- if (backwards) {
123
- for (i = a.length; --i >= 0;) if (doit()) break;
124
- ret.reverse();
125
- top.reverse();
126
- } else {
127
- for (i = 0; i < a.length; ++i) if (doit()) break;
101
+ function MAP(a, tw, allow_splicing = true) {
102
+ const new_a = [];
103
+
104
+ for (let i = 0; i < a.length; ++i) {
105
+ let item = a[i];
106
+ let ret = item.transform(tw, allow_splicing);
107
+
108
+ if (ret instanceof AST_Node) {
109
+ new_a.push(ret);
110
+ } else if (ret instanceof Splice) {
111
+ new_a.push(...ret.v);
128
112
  }
129
- } else {
130
- for (i in a) if (HOP(a, i)) if (doit()) break;
131
113
  }
132
- return top.concat(ret);
114
+
115
+ return new_a;
133
116
  }
134
- MAP.at_top = function(val) { return new AtTop(val); };
117
+
135
118
  MAP.splice = function(val) { return new Splice(val); };
136
- MAP.last = function(val) { return new Last(val); };
137
- var skip = MAP.skip = {};
138
- function AtTop(val) { this.v = val; }
119
+ MAP.skip = {};
139
120
  function Splice(val) { this.v = val; }
140
- function Last(val) { this.v = val; }
141
121
  return MAP;
142
122
  })();
143
123
 
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.16.3",
7
+ "version": "5.16.5",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },