terser 5.16.3 → 5.16.4

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,14 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.16.4
4
+
5
+ - Keep `(defaultArg = undefined) => ...`, because default args don't count for function length
6
+ - Prevent inlining variables into `?.` optional chains
7
+ - Avoid removing unused arguments while transforming
8
+ - Optimize iterating AST node lists
9
+ - Make sure `catch` and `finally` aren't children of `try` in the AST
10
+ - Use modern unicode property escapes (`\p{...}`) to parse identifiers when available
11
+
3
12
  ## v5.16.3
4
13
 
5
14
  - Ensure function definitions, don't assume the values of variables defined after them.
@@ -100,48 +100,42 @@ 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);
103
+ function MAP(a, tw, allow_splicing = true) {
104
+ // Loop but try not to build a new array
105
+ for (let i = 0; i < a.length; ++i) {
106
+ let item = a[i];
107
+ let ret = item.transform(tw, allow_splicing);
108
+
109
+ if (ret !== item) {
110
+ const a1 = a.slice(0, i);
111
+
112
+ // Looks like something was transformed. Change the loop.
113
+ if (ret instanceof AST_Node) {
114
+ a1.push(ret);
115
+ } else if (ret instanceof Splice) {
116
+ a1.push(...ret.v);
115
117
  }
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);
118
+
119
+ while ((item = a[++i])) {
120
+ const ret = item.transform(tw, true);
121
+
122
+ if (ret instanceof AST_Node) {
123
+ a1.push(ret);
124
+ } else if (ret instanceof Splice) {
125
+ a1.push(...ret.v);
126
+ }
121
127
  }
128
+
129
+ return a1;
122
130
  }
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;
132
- }
133
- } else {
134
- for (i in a) if (HOP(a, i)) if (doit()) break;
135
131
  }
136
- return top.concat(ret);
132
+
133
+ return a;
137
134
  }
138
- MAP.at_top = function(val) { return new AtTop(val); };
135
+
139
136
  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; }
137
+ MAP.skip = {};
143
138
  function Splice(val) { this.v = val; }
144
- function Last(val) { this.v = val; }
145
139
  return MAP;
146
140
  })();
147
141
 
@@ -426,6 +420,19 @@ var UNICODE = {
426
420
  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
421
  };
428
422
 
423
+ try {
424
+ UNICODE = {
425
+ // https://262.ecma-international.org/13.0/#prod-IdentifierStartChar
426
+ // $, _, ID_Start
427
+ ID_Start: new RegExp("[_$\\p{ID_Start}]", "u"),
428
+ // https://262.ecma-international.org/13.0/#prod-IdentifierPartChar
429
+ // $, zero-width-joiner, zero-width-non-joiner, ID_Continue
430
+ ID_Continue: new RegExp("[$\\u200C\\u200D\\p{ID_Continue}]+", "u"),
431
+ };
432
+ } catch(e) {
433
+ // Could not use modern JS \p{...}. UNICODE is already defined above so let's continue
434
+ }
435
+
429
436
  function get_full_char(str, pos) {
430
437
  if (is_surrogate_pair_head(str.charCodeAt(pos))) {
431
438
  if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
@@ -2219,7 +2226,12 @@ function parse($TEXT, options) {
2219
2226
  }
2220
2227
 
2221
2228
  function try_() {
2222
- var body = block_(), bcatch = null, bfinally = null;
2229
+ var body, bcatch = null, bfinally = null;
2230
+ body = new AST_TryBlock({
2231
+ start : S.token,
2232
+ body : block_(),
2233
+ end : prev(),
2234
+ });
2223
2235
  if (is("keyword", "catch")) {
2224
2236
  var start = S.token;
2225
2237
  next();
@@ -3716,6 +3728,14 @@ class AST_Token {
3716
3728
  Object.seal(this);
3717
3729
  }
3718
3730
 
3731
+ // Return a string summary of the token for node.js console.log
3732
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
3733
+ const special = str => options.stylize(str, "special");
3734
+ const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
3735
+ const value = `${quote}${this.value}${quote}`;
3736
+ return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
3737
+ }
3738
+
3719
3739
  get nlb() {
3720
3740
  return has_tok_flag(this, TOK_FLAG_NLB);
3721
3741
  }
@@ -4862,12 +4882,11 @@ var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
4862
4882
 
4863
4883
  /* -----[ EXCEPTIONS ]----- */
4864
4884
 
4865
- var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4885
+ var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
4866
4886
  if (props) {
4887
+ this.body = props.body;
4867
4888
  this.bcatch = props.bcatch;
4868
4889
  this.bfinally = props.bfinally;
4869
- this.body = props.body;
4870
- this.block_scope = props.block_scope;
4871
4890
  this.start = props.start;
4872
4891
  this.end = props.end;
4873
4892
  }
@@ -4876,12 +4895,13 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4876
4895
  }, {
4877
4896
  $documentation: "A `try` statement",
4878
4897
  $propdoc: {
4898
+ body: "[AST_TryBlock] the try block",
4879
4899
  bcatch: "[AST_Catch?] the catch block, or null if not present",
4880
4900
  bfinally: "[AST_Finally?] the finally block, or null if not present"
4881
4901
  },
4882
4902
  _walk: function(visitor) {
4883
4903
  return visitor._visit(this, function() {
4884
- walk_body(this, visitor);
4904
+ this.body._walk(visitor);
4885
4905
  if (this.bcatch) this.bcatch._walk(visitor);
4886
4906
  if (this.bfinally) this.bfinally._walk(visitor);
4887
4907
  });
@@ -4889,9 +4909,21 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
4889
4909
  _children_backwards(push) {
4890
4910
  if (this.bfinally) push(this.bfinally);
4891
4911
  if (this.bcatch) push(this.bcatch);
4892
- let i = this.body.length;
4893
- while (i--) push(this.body[i]);
4912
+ push(this.body);
4894
4913
  },
4914
+ }, AST_Statement);
4915
+
4916
+ var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
4917
+ if (props) {
4918
+ this.body = props.body;
4919
+ this.block_scope = props.block_scope;
4920
+ this.start = props.start;
4921
+ this.end = props.end;
4922
+ }
4923
+
4924
+ this.flags = 0;
4925
+ }, {
4926
+ $documentation: "The `try` block of a try statement"
4895
4927
  }, AST_Block);
4896
4928
 
4897
4929
  var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
@@ -6781,12 +6813,6 @@ function def_transform(node, descend) {
6781
6813
  });
6782
6814
  }
6783
6815
 
6784
- function do_list(list, tw) {
6785
- return MAP(list, function(node) {
6786
- return node.transform(tw, true);
6787
- });
6788
- }
6789
-
6790
6816
  def_transform(AST_Node, noop);
6791
6817
 
6792
6818
  def_transform(AST_LabeledStatement, function(self, tw) {
@@ -6799,7 +6825,7 @@ def_transform(AST_SimpleStatement, function(self, tw) {
6799
6825
  });
6800
6826
 
6801
6827
  def_transform(AST_Block, function(self, tw) {
6802
- self.body = do_list(self.body, tw);
6828
+ self.body = MAP(self.body, tw);
6803
6829
  });
6804
6830
 
6805
6831
  def_transform(AST_Do, function(self, tw) {
@@ -6846,27 +6872,27 @@ def_transform(AST_If, function(self, tw) {
6846
6872
 
6847
6873
  def_transform(AST_Switch, function(self, tw) {
6848
6874
  self.expression = self.expression.transform(tw);
6849
- self.body = do_list(self.body, tw);
6875
+ self.body = MAP(self.body, tw);
6850
6876
  });
6851
6877
 
6852
6878
  def_transform(AST_Case, function(self, tw) {
6853
6879
  self.expression = self.expression.transform(tw);
6854
- self.body = do_list(self.body, tw);
6880
+ self.body = MAP(self.body, tw);
6855
6881
  });
6856
6882
 
6857
6883
  def_transform(AST_Try, function(self, tw) {
6858
- self.body = do_list(self.body, tw);
6884
+ self.body = self.body.transform(tw);
6859
6885
  if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
6860
6886
  if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
6861
6887
  });
6862
6888
 
6863
6889
  def_transform(AST_Catch, function(self, tw) {
6864
6890
  if (self.argname) self.argname = self.argname.transform(tw);
6865
- self.body = do_list(self.body, tw);
6891
+ self.body = MAP(self.body, tw);
6866
6892
  });
6867
6893
 
6868
6894
  def_transform(AST_Definitions, function(self, tw) {
6869
- self.definitions = do_list(self.definitions, tw);
6895
+ self.definitions = MAP(self.definitions, tw);
6870
6896
  });
6871
6897
 
6872
6898
  def_transform(AST_VarDef, function(self, tw) {
@@ -6875,26 +6901,26 @@ def_transform(AST_VarDef, function(self, tw) {
6875
6901
  });
6876
6902
 
6877
6903
  def_transform(AST_Destructuring, function(self, tw) {
6878
- self.names = do_list(self.names, tw);
6904
+ self.names = MAP(self.names, tw);
6879
6905
  });
6880
6906
 
6881
6907
  def_transform(AST_Lambda, function(self, tw) {
6882
6908
  if (self.name) self.name = self.name.transform(tw);
6883
- self.argnames = do_list(self.argnames, tw);
6909
+ self.argnames = MAP(self.argnames, tw, /* allow_splicing */ false);
6884
6910
  if (self.body instanceof AST_Node) {
6885
6911
  self.body = self.body.transform(tw);
6886
6912
  } else {
6887
- self.body = do_list(self.body, tw);
6913
+ self.body = MAP(self.body, tw);
6888
6914
  }
6889
6915
  });
6890
6916
 
6891
6917
  def_transform(AST_Call, function(self, tw) {
6892
6918
  self.expression = self.expression.transform(tw);
6893
- self.args = do_list(self.args, tw);
6919
+ self.args = MAP(self.args, tw, /* allow_splicing */ false);
6894
6920
  });
6895
6921
 
6896
6922
  def_transform(AST_Sequence, function(self, tw) {
6897
- const result = do_list(self.expressions, tw);
6923
+ const result = MAP(self.expressions, tw);
6898
6924
  self.expressions = result.length
6899
6925
  ? result
6900
6926
  : [new AST_Number({ value: 0 })];
@@ -6942,11 +6968,11 @@ def_transform(AST_Conditional, function(self, tw) {
6942
6968
  });
6943
6969
 
6944
6970
  def_transform(AST_Array, function(self, tw) {
6945
- self.elements = do_list(self.elements, tw);
6971
+ self.elements = MAP(self.elements, tw);
6946
6972
  });
6947
6973
 
6948
6974
  def_transform(AST_Object, function(self, tw) {
6949
- self.properties = do_list(self.properties, tw);
6975
+ self.properties = MAP(self.properties, tw);
6950
6976
  });
6951
6977
 
6952
6978
  def_transform(AST_ObjectProperty, function(self, tw) {
@@ -6959,11 +6985,11 @@ def_transform(AST_ObjectProperty, function(self, tw) {
6959
6985
  def_transform(AST_Class, function(self, tw) {
6960
6986
  if (self.name) self.name = self.name.transform(tw);
6961
6987
  if (self.extends) self.extends = self.extends.transform(tw);
6962
- self.properties = do_list(self.properties, tw);
6988
+ self.properties = MAP(self.properties, tw);
6963
6989
  });
6964
6990
 
6965
6991
  def_transform(AST_ClassStaticBlock, function(self, tw) {
6966
- self.body = do_list(self.body, tw);
6992
+ self.body = MAP(self.body, tw);
6967
6993
  });
6968
6994
 
6969
6995
  def_transform(AST_Expansion, function(self, tw) {
@@ -6977,19 +7003,19 @@ def_transform(AST_NameMapping, function(self, tw) {
6977
7003
 
6978
7004
  def_transform(AST_Import, function(self, tw) {
6979
7005
  if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
6980
- if (self.imported_names) do_list(self.imported_names, tw);
7006
+ if (self.imported_names) MAP(self.imported_names, tw);
6981
7007
  self.module_name = self.module_name.transform(tw);
6982
7008
  });
6983
7009
 
6984
7010
  def_transform(AST_Export, function(self, tw) {
6985
7011
  if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
6986
7012
  if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
6987
- if (self.exported_names) do_list(self.exported_names, tw);
7013
+ if (self.exported_names) MAP(self.exported_names, tw);
6988
7014
  if (self.module_name) self.module_name = self.module_name.transform(tw);
6989
7015
  });
6990
7016
 
6991
7017
  def_transform(AST_TemplateString, function(self, tw) {
6992
- self.segments = do_list(self.segments, tw);
7018
+ self.segments = MAP(self.segments, tw);
6993
7019
  });
6994
7020
 
6995
7021
  def_transform(AST_PrefixedTemplateString, function(self, tw) {
@@ -7222,7 +7248,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7222
7248
  return new AST_Try({
7223
7249
  start : my_start_token(M),
7224
7250
  end : my_end_token(M),
7225
- body : from_moz(M.block).body,
7251
+ body : new AST_TryBlock(from_moz(M.block)),
7226
7252
  bcatch : from_moz(handlers[0]),
7227
7253
  bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
7228
7254
  });
@@ -8193,7 +8219,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8193
8219
  def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
8194
8220
  return {
8195
8221
  type: "TryStatement",
8196
- block: to_moz_block(M),
8222
+ block: to_moz_block(M.body),
8197
8223
  handler: to_moz(M.bcatch),
8198
8224
  guardedHandlers: [],
8199
8225
  finalizer: to_moz(M.bfinally)
@@ -10273,7 +10299,7 @@ function OutputStream(options) {
10273
10299
  DEFPRINT(AST_Try, function(self, output) {
10274
10300
  output.print("try");
10275
10301
  output.space();
10276
- print_braced(self, output);
10302
+ self.body.print(output);
10277
10303
  if (self.bcatch) {
10278
10304
  output.space();
10279
10305
  self.bcatch.print(output);
@@ -10283,6 +10309,9 @@ function OutputStream(options) {
10283
10309
  self.bfinally.print(output);
10284
10310
  }
10285
10311
  });
10312
+ DEFPRINT(AST_TryBlock, function(self, output) {
10313
+ print_braced(self, output);
10314
+ });
10286
10315
  DEFPRINT(AST_Catch, function(self, output) {
10287
10316
  output.print("catch");
10288
10317
  if (self.argname) {
@@ -11175,7 +11204,7 @@ AST_Switch.prototype.shallow_cmp = pass_through;
11175
11204
  AST_SwitchBranch.prototype.shallow_cmp = pass_through;
11176
11205
 
11177
11206
  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);
11207
+ 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
11208
  };
11180
11209
 
11181
11210
  AST_Catch.prototype.shallow_cmp = function(other) {
@@ -11442,12 +11471,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
11442
11471
  const save_scope = scope;
11443
11472
  node.block_scope = scope = new AST_Scope(node);
11444
11473
  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);
11474
+ scope.init_scope_vars(save_scope);
11451
11475
  scope.uses_with = save_scope.uses_with;
11452
11476
  scope.uses_eval = save_scope.uses_eval;
11453
11477
 
@@ -11462,7 +11486,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
11462
11486
  // AST_Switch has a scope within the body, but it itself "is a block scope"
11463
11487
  // This means the switched expression has to belong to the outer scope
11464
11488
  // 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)
11489
+ // This is pretty nasty and warrants an AST change
11466
11490
  const the_block_scope = scope;
11467
11491
  scope = save_scope;
11468
11492
  node.expression.walk(tw);
@@ -12408,9 +12432,7 @@ AST_Default.prototype._size = function () {
12408
12432
  return 8 + list_overhead(this.body);
12409
12433
  };
12410
12434
 
12411
- AST_Try.prototype._size = function () {
12412
- return 3 + list_overhead(this.body);
12413
- };
12435
+ AST_Try.prototype._size = () => 3;
12414
12436
 
12415
12437
  AST_Catch.prototype._size = function () {
12416
12438
  let size = 7 + list_overhead(this.body);
@@ -13474,7 +13496,7 @@ function is_nullish(node, compressor) {
13474
13496
  || any(this.body, compressor);
13475
13497
  });
13476
13498
  def_has_side_effects(AST_Try, function(compressor) {
13477
- return any(this.body, compressor)
13499
+ return this.body.has_side_effects(compressor)
13478
13500
  || this.bcatch && this.bcatch.has_side_effects(compressor)
13479
13501
  || this.bfinally && this.bfinally.has_side_effects(compressor);
13480
13502
  });
@@ -13703,7 +13725,7 @@ function is_nullish(node, compressor) {
13703
13725
  });
13704
13726
  def_may_throw(AST_SymbolClassProperty, return_false);
13705
13727
  def_may_throw(AST_Try, function(compressor) {
13706
- return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
13728
+ return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
13707
13729
  || this.bfinally && this.bfinally.may_throw(compressor);
13708
13730
  });
13709
13731
  def_may_throw(AST_Unary, function(compressor) {
@@ -15873,7 +15895,7 @@ def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
15873
15895
  def_reduce_vars(AST_Try, function(tw, descend, compressor) {
15874
15896
  reset_block_variables(compressor, this);
15875
15897
  push(tw);
15876
- walk_body(this, tw);
15898
+ this.body.walk(tw);
15877
15899
  pop(tw);
15878
15900
  if (this.bcatch) {
15879
15901
  push(tw);
@@ -16077,13 +16099,11 @@ function tighten_body(statements, compressor) {
16077
16099
  function find_loop_scope_try() {
16078
16100
  var node = compressor.self(), level = 0, in_loop = false, in_try = false;
16079
16101
  do {
16080
- if (node instanceof AST_Catch || node instanceof AST_Finally) {
16081
- level++;
16082
- } else if (node instanceof AST_IterationStatement) {
16102
+ if (node instanceof AST_IterationStatement) {
16083
16103
  in_loop = true;
16084
16104
  } else if (node instanceof AST_Scope) {
16085
16105
  break;
16086
- } else if (node instanceof AST_Try) {
16106
+ } else if (node instanceof AST_TryBlock) {
16087
16107
  in_try = true;
16088
16108
  }
16089
16109
  } while (node = compressor.parent(level++));
@@ -16127,6 +16147,9 @@ function tighten_body(statements, compressor) {
16127
16147
  && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
16128
16148
  || node instanceof AST_Await
16129
16149
  || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
16150
+ ||
16151
+ (node instanceof AST_Call || node instanceof AST_PropAccess)
16152
+ && node.optional
16130
16153
  || node instanceof AST_Debugger
16131
16154
  || node instanceof AST_Destructuring
16132
16155
  || node instanceof AST_Expansion
@@ -16300,7 +16323,11 @@ function tighten_body(statements, compressor) {
16300
16323
  var hit = funarg;
16301
16324
  var abort = false, replaced = 0, can_replace = !args || !hit;
16302
16325
  if (!can_replace) {
16303
- for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
16326
+ for (
16327
+ let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
16328
+ !abort && j < args.length;
16329
+ j++
16330
+ ) {
16304
16331
  args[j].transform(scanner);
16305
16332
  }
16306
16333
  can_replace = true;
@@ -19228,9 +19255,9 @@ def_optimize(AST_Switch, function(self, compressor) {
19228
19255
  });
19229
19256
 
19230
19257
  def_optimize(AST_Try, function(self, compressor) {
19231
- tighten_body(self.body, compressor);
19232
19258
  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)) {
19259
+
19260
+ if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
19234
19261
  var body = [];
19235
19262
  if (self.bcatch) {
19236
19263
  trim_unreachable_code(compressor, self.bcatch, body);
@@ -20436,16 +20463,21 @@ def_optimize(AST_Assign, function(self, compressor) {
20436
20463
  return self;
20437
20464
 
20438
20465
  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;
20466
+ function may_assignment_throw() {
20467
+ const right = self.right;
20468
+ self.right = make_node(AST_Null, right);
20469
+ const may_throw = node.may_throw(compressor);
20470
+ self.right = right;
20471
+
20472
+ return may_throw;
20473
+ }
20474
+
20475
+ var stop_at = self.left.definition().scope.get_defun_scope();
20444
20476
  var parent;
20445
- while ((parent = compressor.parent(level++)) !== scope) {
20477
+ while ((parent = compressor.parent(level++)) !== stop_at) {
20446
20478
  if (parent instanceof AST_Try) {
20447
20479
  if (parent.bfinally) return true;
20448
- if (may_throw && parent.bcatch) return true;
20480
+ if (parent.bcatch && may_assignment_throw()) return true;
20449
20481
  }
20450
20482
  }
20451
20483
  }
@@ -20458,7 +20490,13 @@ def_optimize(AST_DefaultAssign, function(self, compressor) {
20458
20490
  var evaluateRight = self.right.evaluate(compressor);
20459
20491
 
20460
20492
  // `[x = undefined] = foo` ---> `[x] = foo`
20461
- if (evaluateRight === undefined) {
20493
+ // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
20494
+ if (
20495
+ evaluateRight === undefined &&
20496
+ (compressor.parent() instanceof AST_Lambda
20497
+ ? compressor.option("keep_fargs") === false
20498
+ : true)
20499
+ ) {
20462
20500
  self = self.left;
20463
20501
  } else if (evaluateRight !== self.right) {
20464
20502
  evaluateRight = make_node_from_constant(evaluateRight, self.right);
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);
@@ -300,7 +300,7 @@ export function is_nullish(node, compressor) {
300
300
  || any(this.body, compressor);
301
301
  });
302
302
  def_has_side_effects(AST_Try, function(compressor) {
303
- return any(this.body, compressor)
303
+ return this.body.has_side_effects(compressor)
304
304
  || this.bcatch && this.bcatch.has_side_effects(compressor)
305
305
  || this.bfinally && this.bfinally.has_side_effects(compressor);
306
306
  });
@@ -529,7 +529,7 @@ export function is_nullish(node, compressor) {
529
529
  });
530
530
  def_may_throw(AST_SymbolClassProperty, return_false);
531
531
  def_may_throw(AST_Try, function(compressor) {
532
- return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
532
+ return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
533
533
  || this.bfinally && this.bfinally.may_throw(compressor);
534
534
  });
535
535
  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) {
@@ -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,42 @@ 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);
101
+ function MAP(a, tw, allow_splicing = true) {
102
+ // Loop but try not to build a new array
103
+ for (let i = 0; i < a.length; ++i) {
104
+ let item = a[i];
105
+ let ret = item.transform(tw, allow_splicing);
106
+
107
+ if (ret !== item) {
108
+ const a1 = a.slice(0, i);
109
+
110
+ // Looks like something was transformed. Change the loop.
111
+ if (ret instanceof AST_Node) {
112
+ a1.push(ret);
113
+ } else if (ret instanceof Splice) {
114
+ a1.push(...ret.v);
111
115
  }
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);
116
+
117
+ while ((item = a[++i])) {
118
+ const ret = item.transform(tw, true);
119
+
120
+ if (ret instanceof AST_Node) {
121
+ a1.push(ret);
122
+ } else if (ret instanceof Splice) {
123
+ a1.push(...ret.v);
124
+ }
117
125
  }
126
+
127
+ return a1;
118
128
  }
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;
128
- }
129
- } else {
130
- for (i in a) if (HOP(a, i)) if (doit()) break;
131
129
  }
132
- return top.concat(ret);
130
+
131
+ return a;
133
132
  }
134
- MAP.at_top = function(val) { return new AtTop(val); };
133
+
135
134
  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; }
135
+ MAP.skip = {};
139
136
  function Splice(val) { this.v = val; }
140
- function Last(val) { this.v = val; }
141
137
  return MAP;
142
138
  })();
143
139
 
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.4",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },