source: frontend/node_modules/terser/lib/parse.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 129.5 KB
RevLine 
[9af201e]1/***********************************************************************
2
3 A JavaScript tokenizer / parser / beautifier / compressor.
4 https://github.com/mishoo/UglifyJS2
5
6 -------------------------------- (C) ---------------------------------
7
8 Author: Mihai Bazon
9 <mihai.bazon@gmail.com>
10 http://mihai.bazon.net/blog
11
12 Distributed under the BSD license:
13
14 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
15 Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/).
16
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions
19 are met:
20
21 * Redistributions of source code must retain the above
22 copyright notice, this list of conditions and the following
23 disclaimer.
24
25 * Redistributions in binary form must reproduce the above
26 copyright notice, this list of conditions and the following
27 disclaimer in the documentation and/or other materials
28 provided with the distribution.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
34 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
35 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
36 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
37 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
40 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 SUCH DAMAGE.
42
43 ***********************************************************************/
44
45"use strict";
46
47import {
48 characters,
49 defaults,
50 makePredicate,
51 set_annotation,
52} from "./utils/index.js";
53import {
54 AST_Accessor,
55 AST_Array,
56 AST_Arrow,
57 AST_Assign,
58 AST_Await,
59 AST_BigInt,
60 AST_Binary,
61 AST_BlockStatement,
62 AST_Break,
63 AST_Call,
64 AST_Case,
65 AST_Catch,
66 AST_Chain,
67 AST_ClassExpression,
68 AST_ClassPrivateProperty,
69 AST_ClassProperty,
70 AST_ClassStaticBlock,
71 AST_ConciseMethod,
72 AST_PrivateIn,
73 AST_PrivateGetter,
74 AST_PrivateMethod,
75 AST_PrivateSetter,
76 AST_Conditional,
77 AST_Const,
78 AST_Continue,
79 AST_Debugger,
80 AST_Default,
81 AST_DefaultAssign,
82 AST_DefClass,
83 AST_Definitions,
84 AST_DefinitionsLike,
85 AST_Defun,
86 AST_Destructuring,
87 AST_Directive,
88 AST_Do,
89 AST_Dot,
90 AST_DotHash,
91 AST_EmptyStatement,
92 AST_Expansion,
93 AST_Export,
94 AST_False,
95 AST_Finally,
96 AST_For,
97 AST_ForIn,
98 AST_ForOf,
99 AST_Function,
100 AST_Hole,
101 AST_If,
102 AST_DynamicImport,
103 AST_Import,
104 AST_ImportMeta,
105 AST_Infinity,
106 AST_IterationStatement,
107 AST_Label,
108 AST_LabeledStatement,
109 AST_LabelRef,
110 AST_Let,
111 AST_NameMapping,
112 AST_New,
113 AST_NewTarget,
114 AST_Null,
115 AST_Number,
116 AST_Object,
117 AST_ObjectGetter,
118 AST_ObjectKeyVal,
119 AST_ObjectProperty,
120 AST_ObjectSetter,
121 AST_PrefixedTemplateString,
122 AST_PropAccess,
123 AST_RegExp,
124 AST_Return,
125 AST_Sequence,
126 AST_SimpleStatement,
127 AST_String,
128 AST_Sub,
129 AST_Super,
130 AST_Switch,
131 AST_SymbolCatch,
132 AST_SymbolClass,
133 AST_SymbolClassProperty,
134 AST_SymbolConst,
135 AST_SymbolDeclaration,
136 AST_SymbolDefClass,
137 AST_SymbolDefun,
138 AST_SymbolExport,
139 AST_SymbolExportForeign,
140 AST_SymbolFunarg,
141 AST_SymbolImport,
142 AST_SymbolImportForeign,
143 AST_SymbolLambda,
144 AST_SymbolLet,
145 AST_SymbolMethod,
146 AST_SymbolRef,
147 AST_SymbolVar,
148 AST_SymbolUsing,
149 AST_TemplateSegment,
150 AST_TemplateString,
151 AST_This,
152 AST_SymbolPrivateProperty,
153 AST_Throw,
154 AST_Token,
155 AST_Toplevel,
156 AST_True,
157 AST_Try,
158 AST_TryBlock,
159 AST_UnaryPostfix,
160 AST_UnaryPrefix,
161 AST_Using,
162 AST_UsingDef,
163 AST_Var,
164 AST_VarDef,
165 AST_While,
166 AST_With,
167 AST_Yield,
168 _INLINE,
169 _NOINLINE,
170 _PURE,
171 _KEY,
172 _MANGLEPROP,
173} from "./ast.js";
174
175var LATEST_RAW = ""; // Only used for numbers and template strings
176var TEMPLATE_RAWS = new Map(); // Raw template strings
177
178var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with";
179var KEYWORDS_ATOM = "false null true";
180var RESERVED_WORDS = "enum import super this " + KEYWORDS_ATOM + " " + KEYWORDS;
181var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS;
182var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
183
184KEYWORDS = makePredicate(KEYWORDS);
185RESERVED_WORDS = makePredicate(RESERVED_WORDS);
186KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
187KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
188ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS);
189
190var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
191
192var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
193var RE_OCT_NUMBER = /^0[0-7]+$/;
194var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i;
195var RE_BIN_NUMBER = /^0b[01]+$/i;
196var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
197var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
198
199var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y;
200
201var OPERATORS = makePredicate([
202 "in",
203 "instanceof",
204 "typeof",
205 "new",
206 "void",
207 "delete",
208 "++",
209 "--",
210 "+",
211 "-",
212 "!",
213 "~",
214 "&",
215 "|",
216 "^",
217 "*",
218 "**",
219 "/",
220 "%",
221 ">>",
222 "<<",
223 ">>>",
224 "<",
225 ">",
226 "<=",
227 ">=",
228 "==",
229 "===",
230 "!=",
231 "!==",
232 "?",
233 "=",
234 "+=",
235 "-=",
236 "||=",
237 "&&=",
238 "??=",
239 "/=",
240 "*=",
241 "**=",
242 "%=",
243 ">>=",
244 "<<=",
245 ">>>=",
246 "|=",
247 "^=",
248 "&=",
249 "&&",
250 "??",
251 "||",
252]);
253
254var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF"));
255
256var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
257
258var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
259
260var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
261
262var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
263
264/* -----[ Tokenizer ]----- */
265
266// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
267var UNICODE = {
268 ID_Start: /[$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\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\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\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\u2071\u207F\u2090-\u209C\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-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\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\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\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\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\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\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\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]|\uD83A[\uDC00-\uDCC4]|\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]/,
269 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])+/,
270};
271
272function get_full_char(str, pos) {
273 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
274 if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
275 return str.charAt(pos) + str.charAt(pos + 1);
276 }
277 } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) {
278 if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) {
279 return str.charAt(pos - 1) + str.charAt(pos);
280 }
281 }
282 return str.charAt(pos);
283}
284
285function get_full_char_code(str, pos) {
286 // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
287 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
288 return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
289 }
290 return str.charCodeAt(pos);
291}
292
293function get_full_char_length(str) {
294 var surrogates = 0;
295
296 for (var i = 0; i < str.length; i++) {
297 if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
298 surrogates++;
299 i++;
300 }
301 }
302
303 return str.length - surrogates;
304}
305
306function from_char_code(code) {
307 // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
308 if (code > 0xFFFF) {
309 code -= 0x10000;
310 return (String.fromCharCode((code >> 10) + 0xD800) +
311 String.fromCharCode((code % 0x400) + 0xDC00));
312 }
313 return String.fromCharCode(code);
314}
315
316function is_surrogate_pair_head(code) {
317 return code >= 0xd800 && code <= 0xdbff;
318}
319
320function is_surrogate_pair_tail(code) {
321 return code >= 0xdc00 && code <= 0xdfff;
322}
323
324function is_digit(code) {
325 return code >= 48 && code <= 57;
326}
327
328function is_identifier_start(ch) {
329 return UNICODE.ID_Start.test(ch);
330}
331
332function is_identifier_char(ch) {
333 return UNICODE.ID_Continue.test(ch);
334}
335
336const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i;
337
338function is_basic_identifier_string(str) {
339 return BASIC_IDENT.test(str);
340}
341
342function is_identifier_string(str, allow_surrogates) {
343 if (BASIC_IDENT.test(str)) {
344 return true;
345 }
346 if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
347 return false;
348 }
349 var match = UNICODE.ID_Start.exec(str);
350 if (!match || match.index !== 0) {
351 return false;
352 }
353
354 str = str.slice(match[0].length);
355 if (!str) {
356 return true;
357 }
358
359 match = UNICODE.ID_Continue.exec(str);
360 return !!match && match[0].length === str.length;
361}
362
363function parse_js_number(num, allow_e = true) {
364 if (!allow_e && num.includes("e")) {
365 return NaN;
366 }
367 if (RE_HEX_NUMBER.test(num)) {
368 return parseInt(num.substr(2), 16);
369 } else if (RE_OCT_NUMBER.test(num)) {
370 return parseInt(num.substr(1), 8);
371 } else if (RE_ES6_OCT_NUMBER.test(num)) {
372 return parseInt(num.substr(2), 8);
373 } else if (RE_BIN_NUMBER.test(num)) {
374 return parseInt(num.substr(2), 2);
375 } else if (RE_DEC_NUMBER.test(num)) {
376 return parseFloat(num);
377 } else {
378 var val = parseFloat(num);
379 if (val == num) return val;
380 }
381}
382
383class JS_Parse_Error extends Error {
384 constructor(message, filename, line, col, pos) {
385 super();
386
387 this.name = "SyntaxError";
388 this.message = message;
389 this.filename = filename;
390 this.line = line;
391 this.col = col;
392 this.pos = pos;
393 }
394}
395
396function js_error(message, filename, line, col, pos) {
397 throw new JS_Parse_Error(message, filename, line, col, pos);
398}
399
400function is_token(token, type, val) {
401 return token.type == type && (val == null || token.value == val);
402}
403
404var EX_EOF = {};
405
406function tokenizer($TEXT, filename, html5_comments, shebang) {
407 var S = {
408 text : $TEXT,
409 filename : filename,
410 pos : 0,
411 tokpos : 0,
412 line : 1,
413 tokline : 0,
414 col : 0,
415 tokcol : 0,
416 newline_before : false,
417 regex_allowed : false,
418 brace_counter : 0,
419 template_braces : [],
420 comments_before : [],
421 directives : {},
422 directive_stack : []
423 };
424
425 function peek() { return get_full_char(S.text, S.pos); }
426
427 // Used because parsing ?. involves a lookahead for a digit
428 function is_option_chain_op() {
429 const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
430 if (!must_be_dot) return false;
431
432 const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
433 return cannot_be_digit < 48 || cannot_be_digit > 57;
434 }
435
436 function next(signal_eof, in_string) {
437 var ch = get_full_char(S.text, S.pos++);
438 if (signal_eof && !ch)
439 throw EX_EOF;
440 if (NEWLINE_CHARS.has(ch)) {
441 S.newline_before = S.newline_before || !in_string;
442 ++S.line;
443 S.col = 0;
444 if (ch == "\r" && peek() == "\n") {
445 // treat a \r\n sequence as a single \n
446 ++S.pos;
447 ch = "\n";
448 }
449 } else {
450 if (ch.length > 1) {
451 ++S.pos;
452 ++S.col;
453 }
454 ++S.col;
455 }
456 return ch;
457 }
458
459 function forward(i) {
460 while (i--) next();
461 }
462
463 function looking_at(str) {
464 return S.text.substr(S.pos, str.length) == str;
465 }
466
467 function find_eol() {
468 var text = S.text;
469 for (var i = S.pos, n = S.text.length; i < n; ++i) {
470 var ch = text[i];
471 if (NEWLINE_CHARS.has(ch))
472 return i;
473 }
474 return -1;
475 }
476
477 function find(what, signal_eof) {
478 var pos = S.text.indexOf(what, S.pos);
479 if (signal_eof && pos == -1) throw EX_EOF;
480 return pos;
481 }
482
483 function start_token() {
484 S.tokline = S.line;
485 S.tokcol = S.col;
486 S.tokpos = S.pos;
487 }
488
489 var prev_was_dot = false;
490 var previous_token = null;
491 function token(type, value, is_comment) {
492 S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) ||
493 (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
494 (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
495 (type == "arrow");
496 if (type == "punc" && (value == "." || value == "?.")) {
497 prev_was_dot = true;
498 } else if (!is_comment) {
499 prev_was_dot = false;
500 }
501 const line = S.tokline;
502 const col = S.tokcol;
503 const pos = S.tokpos;
504 const nlb = S.newline_before;
505 const file = filename;
506 let comments_before = [];
507 let comments_after = [];
508
509 if (!is_comment) {
510 comments_before = S.comments_before;
511 comments_after = S.comments_before = [];
512 }
513 S.newline_before = false;
514 const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file);
515
516 if (!is_comment) previous_token = tok;
517 return tok;
518 }
519
520 function skip_whitespace() {
521 while (WHITESPACE_CHARS.has(peek()))
522 next();
523 }
524
525 function peek_next_token_start_or_newline() {
526 var pos = S.pos;
527 for (var in_multiline_comment = false; pos < S.text.length; ) {
528 var ch = get_full_char(S.text, pos);
529 if (NEWLINE_CHARS.has(ch)) {
530 return { char: ch, pos: pos };
531 } else if (in_multiline_comment) {
532 if (ch == "*" && get_full_char(S.text, pos + 1) == "/") {
533 pos += 2;
534 in_multiline_comment = false;
535 } else {
536 pos++;
537 }
538 } else if (!WHITESPACE_CHARS.has(ch)) {
539 if (ch == "/") {
540 var next_ch = get_full_char(S.text, pos + 1);
541 if (next_ch == "/") {
542 pos = find_eol();
543 return { char: get_full_char(S.text, pos), pos: pos };
544 } else if (next_ch == "*") {
545 in_multiline_comment = true;
546 pos += 2;
547 continue;
548 }
549 }
550 return { char: ch, pos: pos };
551 } else {
552 pos++;
553 }
554 }
555 return { char: null, pos: pos };
556 }
557
558 function ch_starts_binding_identifier(ch, pos) {
559 if (ch == "\\") {
560 return true;
561 } else if (is_identifier_start(ch)) {
562 RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos;
563 if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) {
564 var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex);
565 if (!is_identifier_char(after) && after != "\\") {
566 // "in" or "instanceof" are keywords, not binding identifiers
567 return false;
568 }
569 }
570 return true;
571 }
572 return false;
573 }
574
575 function read_while(pred) {
576 var ret = "", ch, i = 0;
577 while ((ch = peek()) && pred(ch, i++))
578 ret += next();
579 return ret;
580 }
581
582 function parse_error(err) {
583 js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
584 }
585
586 function read_num(prefix) {
587 var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
588 var num = read_while(function(ch, i) {
589 if (is_big_int) return false;
590
591 var code = ch.charCodeAt(0);
592 switch (code) {
593 case 95: // _
594 return (numeric_separator = true);
595 case 98: case 66: // bB
596 return (has_x = true); // Can occur in hex sequence, don't return false yet
597 case 111: case 79: // oO
598 case 120: case 88: // xX
599 return has_x ? false : (has_x = true);
600 case 101: case 69: // eE
601 return has_x ? true : has_e ? false : (has_e = after_e = true);
602 case 45: // -
603 return after_e || (i == 0 && !prefix);
604 case 43: // +
605 return after_e;
606 case (after_e = false, 46): // .
607 return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
608 case 110: // n
609 is_big_int = true;
610 return true;
611 }
612
613 return (
614 code >= 48 && code <= 57 // 0-9
615 || code >= 97 && code <= 102 // a-f
616 || code >= 65 && code <= 70 // A-F
617 );
618 });
619 if (prefix) num = prefix + num;
620
621 LATEST_RAW = num;
622
623 if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
624 parse_error("Legacy octal literals are not allowed in strict mode");
625 }
626 if (numeric_separator) {
627 if (num.endsWith("_")) {
628 parse_error("Numeric separators are not allowed at the end of numeric literals");
629 } else if (num.includes("__")) {
630 parse_error("Only one underscore is allowed as numeric separator");
631 }
632 num = num.replace(/_/g, "");
633 }
634 if (is_big_int) {
635 const without_n = num.slice(0, -1);
636 const allow_e = RE_HEX_NUMBER.test(without_n);
637 const valid = parse_js_number(without_n, allow_e);
638 if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid))
639 return token("big_int", without_n);
640 parse_error("Invalid or unexpected token");
641 }
642 var valid = parse_js_number(num);
643 if (!isNaN(valid)) {
644 return token("num", valid);
645 } else {
646 parse_error("Invalid syntax: " + num);
647 }
648 }
649
650 function is_octal(ch) {
651 return ch >= "0" && ch <= "7";
652 }
653
654 function read_escaped_char(in_string, strict_hex, template_string) {
655 var ch = next(true, in_string);
656 switch (ch.charCodeAt(0)) {
657 case 110 : return "\n";
658 case 114 : return "\r";
659 case 116 : return "\t";
660 case 98 : return "\b";
661 case 118 : return "\u000b"; // \v
662 case 102 : return "\f";
663 case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x
664 case 117 : // \u
665 if (peek() == "{") {
666 next(true);
667 if (peek() === "}")
668 parse_error("Expecting hex-character between {}");
669 while (peek() == "0") next(true); // No significance
670 var result, length = find("}", true) - S.pos;
671 // Avoid 32 bit integer overflow (1 << 32 === 1)
672 // We know first character isn't 0 and thus out of range anyway
673 if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) {
674 parse_error("Unicode reference out of bounds");
675 }
676 next(true);
677 return from_char_code(result);
678 }
679 return String.fromCharCode(hex_bytes(4, strict_hex));
680 case 10 : return ""; // newline
681 case 13 : // \r
682 if (peek() == "\n") { // DOS newline
683 next(true, in_string);
684 return "";
685 }
686 }
687 if (is_octal(ch)) {
688 if (template_string && strict_hex) {
689 const represents_null_character = ch === "0" && !is_octal(peek());
690 if (!represents_null_character) {
691 parse_error("Octal escape sequences are not allowed in template strings");
692 }
693 }
694 return read_octal_escape_sequence(ch, strict_hex);
695 }
696 return ch;
697 }
698
699 function read_octal_escape_sequence(ch, strict_octal) {
700 // Read
701 var p = peek();
702 if (p >= "0" && p <= "7") {
703 ch += next(true);
704 if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
705 ch += next(true);
706 }
707
708 // Parse
709 if (ch === "0") return "\0";
710 if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal)
711 parse_error("Legacy octal escape sequences are not allowed in strict mode");
712 return String.fromCharCode(parseInt(ch, 8));
713 }
714
715 function hex_bytes(n, strict_hex) {
716 var num = 0;
717 for (; n > 0; --n) {
718 if (!strict_hex && isNaN(parseInt(peek(), 16))) {
719 return parseInt(num, 16) || "";
720 }
721 var digit = next(true);
722 if (isNaN(parseInt(digit, 16)))
723 parse_error("Invalid hex-character pattern in string");
724 num += digit;
725 }
726 return parseInt(num, 16);
727 }
728
729 var read_string = with_eof_error("Unterminated string constant", function() {
730 const start_pos = S.pos;
731 var quote = next(), ret = [];
732 for (;;) {
733 var ch = next(true, true);
734 if (ch == "\\") ch = read_escaped_char(true, true);
735 else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
736 else if (ch == quote) break;
737 ret.push(ch);
738 }
739 var tok = token("string", ret.join(""));
740 LATEST_RAW = S.text.slice(start_pos, S.pos);
741 tok.quote = quote;
742 return tok;
743 });
744
745 var read_template_characters = with_eof_error("Unterminated template", function(begin) {
746 if (begin) {
747 S.template_braces.push(S.brace_counter);
748 }
749 var content = "", raw = "", ch, tok;
750 next(true, true);
751 while ((ch = next(true, true)) != "`") {
752 if (ch == "\r") {
753 if (peek() == "\n") ++S.pos;
754 ch = "\n";
755 } else if (ch == "$" && peek() == "{") {
756 next(true, true);
757 S.brace_counter++;
758 tok = token(begin ? "template_head" : "template_cont", content);
759 TEMPLATE_RAWS.set(tok, raw);
760 tok.template_end = false;
761 return tok;
762 }
763
764 raw += ch;
765 if (ch == "\\") {
766 var tmp = S.pos;
767 var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]"));
768 ch = read_escaped_char(true, !prev_is_tag, true);
769 raw += S.text.substr(tmp, S.pos - tmp);
770 }
771
772 content += ch;
773 }
774 S.template_braces.pop();
775 tok = token(begin ? "template_head" : "template_cont", content);
776 TEMPLATE_RAWS.set(tok, raw);
777 tok.template_end = true;
778 return tok;
779 });
780
781 function skip_line_comment(type) {
782 var regex_allowed = S.regex_allowed;
783 var i = find_eol(), ret;
784 if (i == -1) {
785 ret = S.text.substr(S.pos);
786 S.pos = S.text.length;
787 } else {
788 ret = S.text.substring(S.pos, i);
789 S.pos = i;
790 }
791 S.col = S.tokcol + (S.pos - S.tokpos);
792 S.comments_before.push(token(type, ret, true));
793 S.regex_allowed = regex_allowed;
794 return next_token;
795 }
796
797 var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
798 var regex_allowed = S.regex_allowed;
799 var i = find("*/", true);
800 var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n");
801 // update stream position
802 forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2);
803 S.comments_before.push(token("comment2", text, true));
804 S.newline_before = S.newline_before || text.includes("\n");
805 S.regex_allowed = regex_allowed;
806 return next_token;
807 });
808
809 var read_name = function () {
810 let start = S.pos, end = start - 1, ch = "c";
811
812 while (
813 (ch = S.text.charAt(++end))
814 && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z")
815 );
816
817 // 0x7F is very rare in actual code, so we compare it to "~" (0x7E)
818 if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") {
819 S.pos += end - start;
820 S.col += end - start;
821 return S.text.slice(start, S.pos);
822 }
823
824 return read_name_hard();
825 };
826
827 var read_name_hard = with_eof_error("Unterminated identifier name", function() {
828 var name = [], ch, escaped = false;
829 var read_escaped_identifier_char = function() {
830 escaped = true;
831 next();
832 if (peek() !== "u") {
833 parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}");
834 }
835 return read_escaped_char(false, true);
836 };
837
838 // Read first character (ID_Start)
839 if ((ch = peek()) === "\\") {
840 ch = read_escaped_identifier_char();
841 if (!is_identifier_start(ch)) {
842 parse_error("First identifier char is an invalid identifier char");
843 }
844 } else if (is_identifier_start(ch)) {
845 next();
846 } else {
847 return "";
848 }
849
850 name.push(ch);
851
852 // Read ID_Continue
853 while ((ch = peek()) != null) {
854 if ((ch = peek()) === "\\") {
855 ch = read_escaped_identifier_char();
856 if (!is_identifier_char(ch)) {
857 parse_error("Invalid escaped identifier char");
858 }
859 } else {
860 if (!is_identifier_char(ch)) {
861 break;
862 }
863 next();
864 }
865 name.push(ch);
866 }
867 const name_str = name.join("");
868 if (RESERVED_WORDS.has(name_str) && escaped) {
869 parse_error("Escaped characters are not allowed in keywords");
870 }
871 return name_str;
872 });
873
874 var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
875 var prev_backslash = false, ch, in_class = false;
876 while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) {
877 parse_error("Unexpected line terminator");
878 } else if (prev_backslash) {
879 if (/^[\u0000-\u007F]$/.test(ch)) {
880 source += "\\" + ch;
881 } else {
882 // Remove the useless slash before the escape, but only for characters that won't be added to regexp syntax
883 source += ch;
884 }
885 prev_backslash = false;
886 } else if (ch == "[") {
887 in_class = true;
888 source += ch;
889 } else if (ch == "]" && in_class) {
890 in_class = false;
891 source += ch;
892 } else if (ch == "/" && !in_class) {
893 break;
894 } else if (ch == "\\") {
895 prev_backslash = true;
896 } else {
897 source += ch;
898 }
899 const flags = read_name();
900 return token("regexp", "/" + source + "/" + flags);
901 });
902
903 function read_operator(prefix) {
904 function grow(op) {
905 if (!peek()) return op;
906 var bigger = op + peek();
907 if (OPERATORS.has(bigger)) {
908 next();
909 return grow(bigger);
910 } else {
911 return op;
912 }
913 }
914 return token("operator", grow(prefix || next()));
915 }
916
917 function handle_slash() {
918 next();
919 switch (peek()) {
920 case "/":
921 next();
922 return skip_line_comment("comment1");
923 case "*":
924 next();
925 return skip_multiline_comment();
926 }
927 return S.regex_allowed ? read_regexp("") : read_operator("/");
928 }
929
930 function handle_eq_sign() {
931 next();
932 if (peek() === ">") {
933 next();
934 return token("arrow", "=>");
935 } else {
936 return read_operator("=");
937 }
938 }
939
940 function handle_dot() {
941 next();
942 if (is_digit(peek().charCodeAt(0))) {
943 return read_num(".");
944 }
945 if (peek() === ".") {
946 next(); // Consume second dot
947 next(); // Consume third dot
948 return token("expand", "...");
949 }
950
951 return token("punc", ".");
952 }
953
954 function read_word() {
955 var word = read_name();
956 if (prev_was_dot) return token("name", word);
957 return KEYWORDS_ATOM.has(word) ? token("atom", word)
958 : !KEYWORDS.has(word) ? token("name", word)
959 : OPERATORS.has(word) ? token("operator", word)
960 : token("keyword", word);
961 }
962
963 function read_private_word() {
964 next();
965 return token("privatename", read_name());
966 }
967
968 function with_eof_error(eof_error, cont) {
969 return function(x) {
970 try {
971 return cont(x);
972 } catch(ex) {
973 if (ex === EX_EOF) parse_error(eof_error);
974 else throw ex;
975 }
976 };
977 }
978
979 function next_token(force_regexp) {
980 if (force_regexp != null)
981 return read_regexp(force_regexp);
982 if (shebang && S.pos == 0 && looking_at("#!")) {
983 start_token();
984 forward(2);
985 skip_line_comment("comment5");
986 }
987 for (;;) {
988 skip_whitespace();
989 start_token();
990 if (html5_comments) {
991 if (looking_at("<!--")) {
992 forward(4);
993 skip_line_comment("comment3");
994 continue;
995 }
996 if (looking_at("-->") && S.newline_before) {
997 forward(3);
998 skip_line_comment("comment4");
999 continue;
1000 }
1001 }
1002 var ch = peek();
1003 if (!ch) return token("eof");
1004 var code = ch.charCodeAt(0);
1005 switch (code) {
1006 case 34: case 39: return read_string();
1007 case 46: return handle_dot();
1008 case 47: {
1009 var tok = handle_slash();
1010 if (tok === next_token) continue;
1011 return tok;
1012 }
1013 case 61: return handle_eq_sign();
1014 case 63: {
1015 if (!is_option_chain_op()) break; // Handled below
1016
1017 next(); // ?
1018 next(); // .
1019
1020 return token("punc", "?.");
1021 }
1022 case 96: return read_template_characters(true);
1023 case 123:
1024 S.brace_counter++;
1025 break;
1026 case 125:
1027 S.brace_counter--;
1028 if (S.template_braces.length > 0
1029 && S.template_braces[S.template_braces.length - 1] === S.brace_counter)
1030 return read_template_characters(false);
1031 break;
1032 }
1033 if (is_digit(code)) return read_num();
1034 if (PUNC_CHARS.has(ch)) return token("punc", next());
1035 if (OPERATOR_CHARS.has(ch)) return read_operator();
1036 if (code == 92 || is_identifier_start(ch)) return read_word();
1037 if (code == 35) return read_private_word();
1038 break;
1039 }
1040 parse_error("Unexpected character '" + ch + "'");
1041 }
1042
1043 next_token.next = next;
1044 next_token.peek = peek;
1045
1046 next_token.context = function(nc) {
1047 if (nc) S = nc;
1048 return S;
1049 };
1050
1051 next_token.add_directive = function(directive) {
1052 S.directive_stack[S.directive_stack.length - 1].push(directive);
1053
1054 if (S.directives[directive] === undefined) {
1055 S.directives[directive] = 1;
1056 } else {
1057 S.directives[directive]++;
1058 }
1059 };
1060
1061 next_token.push_directives_stack = function() {
1062 S.directive_stack.push([]);
1063 };
1064
1065 next_token.pop_directives_stack = function() {
1066 var directives = S.directive_stack[S.directive_stack.length - 1];
1067
1068 for (var i = 0; i < directives.length; i++) {
1069 S.directives[directives[i]]--;
1070 }
1071
1072 S.directive_stack.pop();
1073 };
1074
1075 next_token.has_directive = function(directive) {
1076 return S.directives[directive] > 0;
1077 };
1078
1079 next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline;
1080 next_token.ch_starts_binding_identifier = ch_starts_binding_identifier;
1081
1082 return next_token;
1083
1084}
1085
1086/* -----[ Parser (constants) ]----- */
1087
1088var UNARY_PREFIX = makePredicate([
1089 "typeof",
1090 "void",
1091 "delete",
1092 "--",
1093 "++",
1094 "!",
1095 "~",
1096 "-",
1097 "+"
1098]);
1099
1100var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
1101
1102var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
1103
1104var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]);
1105
1106var PRECEDENCE = (function(a, ret) {
1107 for (var i = 0; i < a.length; ++i) {
1108 for (const op of a[i]) {
1109 ret[op] = i + 1;
1110 }
1111 }
1112 return ret;
1113})(
1114 [
1115 ["||"],
1116 ["??"],
1117 ["&&"],
1118 ["|"],
1119 ["^"],
1120 ["&"],
1121 ["==", "===", "!=", "!=="],
1122 ["<", ">", "<=", ">=", "in", "instanceof"],
1123 [">>", "<<", ">>>"],
1124 ["+", "-"],
1125 ["*", "/", "%"],
1126 ["**"]
1127 ],
1128 {}
1129);
1130
1131var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]);
1132
1133/* -----[ Parser ]----- */
1134
1135function parse($TEXT, options) {
1136 // maps start tokens to count of comments found outside of their parens
1137 // Example: /* I count */ ( /* I don't */ foo() )
1138 // Useful because comments_before property of call with parens outside
1139 // contains both comments inside and outside these parens. Used to find the
1140 // right #__PURE__ comments for an expression
1141 const outer_comments_before_counts = new WeakMap();
1142
1143 options = defaults(options, {
1144 bare_returns : false,
1145 ecma : null, // Legacy
1146 expression : false,
1147 filename : null,
1148 html5_comments : true,
1149 module : false,
1150 shebang : true,
1151 strict : false,
1152 toplevel : null,
1153 }, true);
1154
1155 var S = {
1156 input : (typeof $TEXT == "string"
1157 ? tokenizer($TEXT, options.filename,
1158 options.html5_comments, options.shebang)
1159 : $TEXT),
1160 token : null,
1161 prev : null,
1162 peeked : null,
1163 in_function : 0,
1164 in_async : -1,
1165 in_generator : -1,
1166 in_directives : true,
1167 in_loop : 0,
1168 labels : []
1169 };
1170
1171 S.token = next();
1172
1173 function is(type, value) {
1174 return is_token(S.token, type, value);
1175 }
1176
1177 function peek() { return S.peeked || (S.peeked = S.input()); }
1178
1179 function next() {
1180 S.prev = S.token;
1181
1182 if (!S.peeked) peek();
1183 S.token = S.peeked;
1184 S.peeked = null;
1185 S.in_directives = S.in_directives && (
1186 S.token.type == "string" || is("punc", ";")
1187 );
1188 return S.token;
1189 }
1190
1191 function prev() {
1192 return S.prev;
1193 }
1194
1195 function croak(msg, line, col, pos) {
1196 var ctx = S.input.context();
1197 js_error(msg,
1198 ctx.filename,
1199 line != null ? line : ctx.tokline,
1200 col != null ? col : ctx.tokcol,
1201 pos != null ? pos : ctx.tokpos);
1202 }
1203
1204 function token_error(token, msg) {
1205 croak(msg, token.line, token.col);
1206 }
1207
1208 function unexpected(token) {
1209 if (token == null)
1210 token = S.token;
1211 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1212 }
1213
1214 function expect_token(type, val) {
1215 if (is(type, val)) {
1216 return next();
1217 }
1218 token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
1219 }
1220
1221 function expect(punc) { return expect_token("punc", punc); }
1222
1223 function has_newline_before(token) {
1224 return token.nlb || !token.comments_before.every((comment) => !comment.nlb);
1225 }
1226
1227 function can_insert_semicolon() {
1228 return !options.strict
1229 && (is("eof") || is("punc", "}") || has_newline_before(S.token));
1230 }
1231
1232 function is_in_generator() {
1233 return S.in_generator === S.in_function;
1234 }
1235
1236 function is_in_async() {
1237 return S.in_async === S.in_function;
1238 }
1239
1240 function can_await() {
1241 return (
1242 S.in_async === S.in_function
1243 || S.in_function === 0 && S.input.has_directive("use strict")
1244 );
1245 }
1246
1247 function semicolon(optional) {
1248 if (is("punc", ";")) next();
1249 else if (!optional && !can_insert_semicolon()) unexpected();
1250 }
1251
1252 function parenthesised() {
1253 expect("(");
1254 var exp = expression(true);
1255 expect(")");
1256 return exp;
1257 }
1258
1259 function embed_tokens(parser) {
1260 return function _embed_tokens_wrapper(...args) {
1261 const start = S.token;
1262 const expr = parser(...args);
1263 expr.start = start;
1264 expr.end = prev();
1265 return expr;
1266 };
1267 }
1268
1269 function handle_regexp() {
1270 if (is("operator", "/") || is("operator", "/=")) {
1271 S.peeked = null;
1272 S.token = S.input(S.token.value.substr(1)); // force regexp
1273 }
1274 }
1275
1276 var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
1277 handle_regexp();
1278 switch (S.token.type) {
1279 case "string":
1280 if (S.in_directives) {
1281 var token = peek();
1282 if (!LATEST_RAW.includes("\\")
1283 && (is_token(token, "punc", ";")
1284 || is_token(token, "punc", "}")
1285 || has_newline_before(token)
1286 || is_token(token, "eof"))) {
1287 S.input.add_directive(S.token.value);
1288 } else {
1289 S.in_directives = false;
1290 }
1291 }
1292 var dir = S.in_directives, stat = simple_statement();
1293 return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat;
1294 case "template_head":
1295 case "num":
1296 case "big_int":
1297 case "regexp":
1298 case "operator":
1299 case "atom":
1300 return simple_statement();
1301
1302 case "name":
1303 if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
1304 next();
1305 next();
1306 if (is_for_body) {
1307 croak("functions are not allowed as the body of a loop");
1308 }
1309 return function_(AST_Defun, false, true, is_export_default);
1310 }
1311 if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
1312 next();
1313 var node = import_statement();
1314 semicolon();
1315 return node;
1316 }
1317 if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) {
1318 next();
1319 var node = using_();
1320 semicolon();
1321 return node;
1322 }
1323 if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) {
1324 var next_next = S.input.peek_next_token_start_or_newline();
1325 if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) {
1326 next();
1327 // The "using" token will be consumed by the await_using_ function.
1328 var node = await_using_();
1329 semicolon();
1330 return node;
1331 }
1332 }
1333 return is_token(peek(), "punc", ":")
1334 ? labeled_statement()
1335 : simple_statement();
1336
1337 case "privatename":
1338 if(!S.in_class)
1339 croak("Private field must be used in an enclosing class");
1340 return simple_statement();
1341
1342 case "punc":
1343 switch (S.token.value) {
1344 case "{":
1345 return new AST_BlockStatement({
1346 start : S.token,
1347 body : block_(),
1348 end : prev()
1349 });
1350 case "[":
1351 case "(":
1352 return simple_statement();
1353 case ";":
1354 S.in_directives = false;
1355 next();
1356 return new AST_EmptyStatement();
1357 default:
1358 unexpected();
1359 }
1360
1361 case "keyword":
1362 switch (S.token.value) {
1363 case "break":
1364 next();
1365 return break_cont(AST_Break);
1366
1367 case "continue":
1368 next();
1369 return break_cont(AST_Continue);
1370
1371 case "debugger":
1372 next();
1373 semicolon();
1374 return new AST_Debugger();
1375
1376 case "do":
1377 next();
1378 var body = in_loop(statement);
1379 expect_token("keyword", "while");
1380 var condition = parenthesised();
1381 semicolon(true);
1382 return new AST_Do({
1383 body : body,
1384 condition : condition
1385 });
1386
1387 case "while":
1388 next();
1389 return new AST_While({
1390 condition : parenthesised(),
1391 body : in_loop(function() { return statement(false, true); })
1392 });
1393
1394 case "for":
1395 next();
1396 return for_();
1397
1398 case "class":
1399 next();
1400 if (is_for_body) {
1401 croak("classes are not allowed as the body of a loop");
1402 }
1403 if (is_if_body) {
1404 croak("classes are not allowed as the body of an if");
1405 }
1406 return class_(AST_DefClass, is_export_default);
1407
1408 case "function":
1409 next();
1410 if (is_for_body) {
1411 croak("functions are not allowed as the body of a loop");
1412 }
1413 return function_(AST_Defun, false, false, is_export_default);
1414
1415 case "if":
1416 next();
1417 return if_();
1418
1419 case "return":
1420 if (S.in_function == 0 && !options.bare_returns)
1421 croak("'return' outside of function");
1422 next();
1423 var value = null;
1424 if (is("punc", ";")) {
1425 next();
1426 } else if (!can_insert_semicolon()) {
1427 value = expression(true);
1428 semicolon();
1429 }
1430 return new AST_Return({
1431 value: value
1432 });
1433
1434 case "switch":
1435 next();
1436 return new AST_Switch({
1437 expression : parenthesised(),
1438 body : in_loop(switch_body_)
1439 });
1440
1441 case "throw":
1442 next();
1443 if (has_newline_before(S.token))
1444 croak("Illegal newline after 'throw'");
1445 var value = expression(true);
1446 semicolon();
1447 return new AST_Throw({
1448 value: value
1449 });
1450
1451 case "try":
1452 next();
1453 return try_();
1454
1455 case "var":
1456 next();
1457 var node = var_();
1458 semicolon();
1459 return node;
1460
1461 case "let":
1462 next();
1463 var node = let_();
1464 semicolon();
1465 return node;
1466
1467 case "const":
1468 next();
1469 var node = const_();
1470 semicolon();
1471 return node;
1472
1473 case "with":
1474 if (S.input.has_directive("use strict")) {
1475 croak("Strict mode may not include a with statement");
1476 }
1477 next();
1478 return new AST_With({
1479 expression : parenthesised(),
1480 body : statement()
1481 });
1482
1483 case "export":
1484 if (!is_token(peek(), "punc", "(")) {
1485 next();
1486 var node = export_statement();
1487 if (is("punc", ";")) semicolon();
1488 return node;
1489 }
1490 }
1491 }
1492 unexpected();
1493 });
1494
1495 function labeled_statement() {
1496 var label = as_symbol(AST_Label);
1497 if (label.name === "await" && is_in_async()) {
1498 token_error(S.prev, "await cannot be used as label inside async function");
1499 }
1500 if (S.labels.some((l) => l.name === label.name)) {
1501 // ECMA-262, 12.12: An ECMAScript program is considered
1502 // syntactically incorrect if it contains a
1503 // LabelledStatement that is enclosed by a
1504 // LabelledStatement with the same Identifier as label.
1505 croak("Label " + label.name + " defined twice");
1506 }
1507 expect(":");
1508 S.labels.push(label);
1509 var stat = statement();
1510 S.labels.pop();
1511 if (!(stat instanceof AST_IterationStatement)) {
1512 // check for `continue` that refers to this label.
1513 // those should be reported as syntax errors.
1514 // https://github.com/mishoo/UglifyJS2/issues/287
1515 label.references.forEach(function(ref) {
1516 if (ref instanceof AST_Continue) {
1517 ref = ref.label.start;
1518 croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
1519 ref.line, ref.col, ref.pos);
1520 }
1521 });
1522 }
1523 return new AST_LabeledStatement({ body: stat, label: label });
1524 }
1525
1526 function simple_statement(tmp) {
1527 return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
1528 }
1529
1530 function break_cont(type) {
1531 var label = null, ldef;
1532 if (!can_insert_semicolon()) {
1533 label = as_symbol(AST_LabelRef, true);
1534 }
1535 if (label != null) {
1536 ldef = S.labels.find((l) => l.name === label.name);
1537 if (!ldef)
1538 croak("Undefined label " + label.name);
1539 label.thedef = ldef;
1540 } else if (S.in_loop == 0)
1541 croak(type.TYPE + " not inside a loop or switch");
1542 semicolon();
1543 var stat = new type({ label: label });
1544 if (ldef) ldef.references.push(stat);
1545 return stat;
1546 }
1547
1548 function for_() {
1549 var for_await_error = "`for await` invalid in this context";
1550 var await_tok = S.token;
1551 if (await_tok.type == "name" && await_tok.value == "await") {
1552 if (!can_await()) {
1553 token_error(await_tok, for_await_error);
1554 }
1555 next();
1556 } else {
1557 await_tok = false;
1558 }
1559 expect("(");
1560 var init = null;
1561 if (!is("punc", ";")) {
1562 init =
1563 is("keyword", "var") ? (next(), var_(true)) :
1564 is("keyword", "let") ? (next(), let_(true)) :
1565 is("keyword", "const") ? (next(), const_(true)) :
1566 is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) :
1567 is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) :
1568 expression(true, true);
1569 var is_in = is("operator", "in");
1570 var is_of = is("name", "of");
1571 if (await_tok && !is_of) {
1572 token_error(await_tok, for_await_error);
1573 }
1574 if (is_in || is_of) {
1575 if (init instanceof AST_DefinitionsLike) {
1576 if (init.definitions.length > 1)
1577 token_error(init.start, "Only one variable declaration allowed in for..in loop");
1578 if (is_in && init instanceof AST_Using) {
1579 token_error(init.start, "Invalid using declaration in for..in loop");
1580 }
1581 } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
1582 token_error(init.start, "Invalid left-hand side in for..in loop");
1583 }
1584 next();
1585 if (is_in) {
1586 return for_in(init);
1587 } else {
1588 return for_of(init, !!await_tok);
1589 }
1590 }
1591 } else if (await_tok) {
1592 token_error(await_tok, for_await_error);
1593 }
1594 return regular_for(init);
1595 }
1596
1597 function regular_for(init) {
1598 expect(";");
1599 var test = is("punc", ";") ? null : expression(true);
1600 expect(";");
1601 var step = is("punc", ")") ? null : expression(true);
1602 expect(")");
1603 return new AST_For({
1604 init : init,
1605 condition : test,
1606 step : step,
1607 body : in_loop(function() { return statement(false, true); })
1608 });
1609 }
1610
1611 function for_of(init, is_await) {
1612 var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null;
1613 var obj = expression(true);
1614 expect(")");
1615 return new AST_ForOf({
1616 await : is_await,
1617 init : init,
1618 name : lhs,
1619 object : obj,
1620 body : in_loop(function() { return statement(false, true); })
1621 });
1622 }
1623
1624 function for_in(init) {
1625 var obj = expression(true);
1626 expect(")");
1627 return new AST_ForIn({
1628 init : init,
1629 object : obj,
1630 body : in_loop(function() { return statement(false, true); })
1631 });
1632 }
1633
1634 var arrow_function = function(start, argnames, is_async) {
1635 if (has_newline_before(S.token)) {
1636 croak("Unexpected newline before arrow (=>)");
1637 }
1638
1639 expect_token("arrow", "=>");
1640
1641 var body = _function_body(is("punc", "{"), false, is_async);
1642
1643 return new AST_Arrow({
1644 start : start,
1645 end : body.end,
1646 async : is_async,
1647 argnames : argnames,
1648 body : body
1649 });
1650 };
1651
1652 var function_ = function(ctor, is_generator, is_async, is_export_default) {
1653 var in_statement = ctor === AST_Defun;
1654 if (is("operator", "*")) {
1655 is_generator = true;
1656 next();
1657 }
1658
1659 var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
1660 if (in_statement && !name) {
1661 if (is_export_default) {
1662 ctor = AST_Function;
1663 } else {
1664 unexpected();
1665 }
1666 }
1667
1668 if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
1669 unexpected(prev());
1670
1671 var args = [];
1672 var body = _function_body(true, is_generator, is_async, name, args);
1673 return new ctor({
1674 start : args.start,
1675 end : body.end,
1676 is_generator: is_generator,
1677 async : is_async,
1678 name : name,
1679 argnames: args,
1680 body : body
1681 });
1682 };
1683
1684 class UsedParametersTracker {
1685 constructor(is_parameter, strict, duplicates_ok = false) {
1686 this.is_parameter = is_parameter;
1687 this.duplicates_ok = duplicates_ok;
1688 this.parameters = new Set();
1689 this.duplicate = null;
1690 this.default_assignment = false;
1691 this.spread = false;
1692 this.strict_mode = !!strict;
1693 }
1694 add_parameter(token) {
1695 if (this.parameters.has(token.value)) {
1696 if (this.duplicate === null) {
1697 this.duplicate = token;
1698 }
1699 this.check_strict();
1700 } else {
1701 this.parameters.add(token.value);
1702 if (this.is_parameter) {
1703 switch (token.value) {
1704 case "arguments":
1705 case "eval":
1706 case "yield":
1707 if (this.strict_mode) {
1708 token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode");
1709 }
1710 break;
1711 default:
1712 if (RESERVED_WORDS.has(token.value)) {
1713 unexpected();
1714 }
1715 }
1716 }
1717 }
1718 }
1719 mark_default_assignment(token) {
1720 if (this.default_assignment === false) {
1721 this.default_assignment = token;
1722 }
1723 }
1724 mark_spread(token) {
1725 if (this.spread === false) {
1726 this.spread = token;
1727 }
1728 }
1729 mark_strict_mode() {
1730 this.strict_mode = true;
1731 }
1732 is_strict() {
1733 return this.default_assignment !== false || this.spread !== false || this.strict_mode;
1734 }
1735 check_strict() {
1736 if (this.is_strict() && this.duplicate !== null && !this.duplicates_ok) {
1737 token_error(this.duplicate, "Parameter " + this.duplicate.value + " was used already");
1738 }
1739 }
1740 }
1741
1742 function parameters(params) {
1743 var used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
1744
1745 expect("(");
1746
1747 while (!is("punc", ")")) {
1748 var param = parameter(used_parameters);
1749 params.push(param);
1750
1751 if (!is("punc", ")")) {
1752 expect(",");
1753 }
1754
1755 if (param instanceof AST_Expansion) {
1756 break;
1757 }
1758 }
1759
1760 next();
1761 }
1762
1763 function parameter(used_parameters, symbol_type) {
1764 var param;
1765 var expand = false;
1766 if (used_parameters === undefined) {
1767 used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
1768 }
1769 if (is("expand", "...")) {
1770 expand = S.token;
1771 used_parameters.mark_spread(S.token);
1772 next();
1773 }
1774 param = binding_element(used_parameters, symbol_type);
1775
1776 if (is("operator", "=") && expand === false) {
1777 used_parameters.mark_default_assignment(S.token);
1778 next();
1779 param = new AST_DefaultAssign({
1780 start: param.start,
1781 left: param,
1782 operator: "=",
1783 right: expression(false),
1784 end: S.token
1785 });
1786 }
1787
1788 if (expand !== false) {
1789 if (!is("punc", ")")) {
1790 unexpected();
1791 }
1792 param = new AST_Expansion({
1793 start: expand,
1794 expression: param,
1795 end: expand
1796 });
1797 }
1798 used_parameters.check_strict();
1799
1800 return param;
1801 }
1802
1803 function binding_element(used_parameters, symbol_type) {
1804 var elements = [];
1805 var first = true;
1806 var is_expand = false;
1807 var expand_token;
1808 var first_token = S.token;
1809 if (used_parameters === undefined) {
1810 const strict = S.input.has_directive("use strict");
1811 const duplicates_ok = symbol_type === AST_SymbolVar;
1812 used_parameters = new UsedParametersTracker(false, strict, duplicates_ok);
1813 }
1814 symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type;
1815 if (is("punc", "[")) {
1816 next();
1817 while (!is("punc", "]")) {
1818 if (first) {
1819 first = false;
1820 } else {
1821 expect(",");
1822 }
1823
1824 if (is("expand", "...")) {
1825 is_expand = true;
1826 expand_token = S.token;
1827 used_parameters.mark_spread(S.token);
1828 next();
1829 }
1830 if (is("punc")) {
1831 switch (S.token.value) {
1832 case ",":
1833 elements.push(new AST_Hole({
1834 start: S.token,
1835 end: S.token
1836 }));
1837 continue;
1838 case "]": // Trailing comma after last element
1839 break;
1840 case "[":
1841 case "{":
1842 elements.push(binding_element(used_parameters, symbol_type));
1843 break;
1844 default:
1845 unexpected();
1846 }
1847 } else if (is("name")) {
1848 used_parameters.add_parameter(S.token);
1849 elements.push(as_symbol(symbol_type));
1850 } else {
1851 croak("Invalid function parameter");
1852 }
1853 if (is("operator", "=") && is_expand === false) {
1854 used_parameters.mark_default_assignment(S.token);
1855 next();
1856 elements[elements.length - 1] = new AST_DefaultAssign({
1857 start: elements[elements.length - 1].start,
1858 left: elements[elements.length - 1],
1859 operator: "=",
1860 right: expression(false),
1861 end: S.token
1862 });
1863 }
1864 if (is_expand) {
1865 if (!is("punc", "]")) {
1866 croak("Rest element must be last element");
1867 }
1868 elements[elements.length - 1] = new AST_Expansion({
1869 start: expand_token,
1870 expression: elements[elements.length - 1],
1871 end: expand_token
1872 });
1873 }
1874 }
1875 expect("]");
1876 used_parameters.check_strict();
1877 return new AST_Destructuring({
1878 start: first_token,
1879 names: elements,
1880 is_array: true,
1881 end: prev()
1882 });
1883 } else if (is("punc", "{")) {
1884 next();
1885 while (!is("punc", "}")) {
1886 if (first) {
1887 first = false;
1888 } else {
1889 expect(",");
1890 }
1891 if (is("expand", "...")) {
1892 is_expand = true;
1893 expand_token = S.token;
1894 used_parameters.mark_spread(S.token);
1895 next();
1896 }
1897 if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) {
1898 used_parameters.add_parameter(S.token);
1899 var start = prev();
1900 var value = as_symbol(symbol_type);
1901 if (is_expand) {
1902 elements.push(new AST_Expansion({
1903 start: expand_token,
1904 expression: value,
1905 end: value.end,
1906 }));
1907 } else {
1908 elements.push(new AST_ObjectKeyVal({
1909 start: start,
1910 key: value.name,
1911 value: value,
1912 end: value.end,
1913 }));
1914 }
1915 } else if (is("punc", "}")) {
1916 continue; // Allow trailing hole
1917 } else {
1918 var property_token = S.token;
1919 var property = as_property_name();
1920 if (property === null) {
1921 unexpected(prev());
1922 } else if (prev().type === "name" && !is("punc", ":")) {
1923 elements.push(new AST_ObjectKeyVal({
1924 start: prev(),
1925 key: property,
1926 value: new symbol_type({
1927 start: prev(),
1928 name: property,
1929 end: prev()
1930 }),
1931 end: prev()
1932 }));
1933 } else {
1934 expect(":");
1935 elements.push(new AST_ObjectKeyVal({
1936 start: property_token,
1937 quote: property_token.quote,
1938 key: property,
1939 value: binding_element(used_parameters, symbol_type),
1940 end: prev()
1941 }));
1942 }
1943 }
1944 if (is_expand) {
1945 if (!is("punc", "}")) {
1946 croak("Rest element must be last element");
1947 }
1948 } else if (is("operator", "=")) {
1949 used_parameters.mark_default_assignment(S.token);
1950 next();
1951 elements[elements.length - 1].value = new AST_DefaultAssign({
1952 start: elements[elements.length - 1].value.start,
1953 left: elements[elements.length - 1].value,
1954 operator: "=",
1955 right: expression(false),
1956 end: S.token
1957 });
1958 }
1959 }
1960 expect("}");
1961 used_parameters.check_strict();
1962 return new AST_Destructuring({
1963 start: first_token,
1964 names: elements,
1965 is_array: false,
1966 end: prev()
1967 });
1968 } else if (is("name")) {
1969 used_parameters.add_parameter(S.token);
1970 return as_symbol(symbol_type);
1971 } else {
1972 croak("Invalid function parameter");
1973 }
1974 }
1975
1976 function params_or_seq_(allow_arrows, maybe_sequence) {
1977 var spread_token;
1978 var invalid_sequence;
1979 var trailing_comma;
1980 var a = [];
1981 expect("(");
1982 while (!is("punc", ")")) {
1983 if (spread_token) unexpected(spread_token);
1984 if (is("expand", "...")) {
1985 spread_token = S.token;
1986 if (maybe_sequence) invalid_sequence = S.token;
1987 next();
1988 a.push(new AST_Expansion({
1989 start: prev(),
1990 expression: expression(),
1991 end: S.token,
1992 }));
1993 } else {
1994 a.push(expression());
1995 }
1996 if (!is("punc", ")")) {
1997 expect(",");
1998 if (is("punc", ")")) {
1999 trailing_comma = prev();
2000 if (maybe_sequence) invalid_sequence = trailing_comma;
2001 }
2002 }
2003 }
2004 expect(")");
2005 if (allow_arrows && is("arrow", "=>")) {
2006 if (spread_token && trailing_comma) unexpected(trailing_comma);
2007 } else if (invalid_sequence) {
2008 unexpected(invalid_sequence);
2009 }
2010 return a;
2011 }
2012
2013 function _function_body(block, generator, is_async, name, args) {
2014 var loop = S.in_loop;
2015 var labels = S.labels;
2016 var current_generator = S.in_generator;
2017 var current_async = S.in_async;
2018 ++S.in_function;
2019 if (generator)
2020 S.in_generator = S.in_function;
2021 if (is_async)
2022 S.in_async = S.in_function;
2023 if (args) parameters(args);
2024 if (block)
2025 S.in_directives = true;
2026 S.in_loop = 0;
2027 S.labels = [];
2028 if (block) {
2029 S.input.push_directives_stack();
2030 var a = block_();
2031 if (name) _verify_symbol(name);
2032 if (args) args.forEach(_verify_symbol);
2033 S.input.pop_directives_stack();
2034 } else {
2035 var a = [new AST_Return({
2036 start: S.token,
2037 value: expression(false),
2038 end: S.token
2039 })];
2040 }
2041 --S.in_function;
2042 S.in_loop = loop;
2043 S.labels = labels;
2044 S.in_generator = current_generator;
2045 S.in_async = current_async;
2046 return a;
2047 }
2048
2049 function _await_expression() {
2050 // Previous token must be "await" and not be interpreted as an identifier
2051 if (!can_await()) {
2052 croak("Unexpected await expression outside async function",
2053 S.prev.line, S.prev.col, S.prev.pos);
2054 }
2055 // the await expression is parsed as a unary expression in Babel
2056 return new AST_Await({
2057 start: prev(),
2058 end: S.token,
2059 expression : maybe_unary(true),
2060 });
2061 }
2062
2063 function _yield_expression() {
2064 var start = S.token;
2065 var star = false;
2066 var has_expression = true;
2067
2068 // Attempt to get expression or star (and then the mandatory expression)
2069 // behind yield on the same line.
2070 //
2071 // If nothing follows on the same line of the yieldExpression,
2072 // it should default to the value `undefined` for yield to return.
2073 // In that case, the `undefined` stored as `null` in ast.
2074 //
2075 // Note 1: It isn't allowed for yield* to close without an expression
2076 // Note 2: If there is a nlb between yield and star, it is interpret as
2077 // yield <explicit undefined> <inserted automatic semicolon> *
2078 if (
2079 can_insert_semicolon()
2080 || is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value)
2081 || is("template_cont")
2082 ) {
2083 has_expression = false;
2084 } else if (is("operator", "*")) {
2085 star = true;
2086 next();
2087 }
2088
2089 return new AST_Yield({
2090 start : start,
2091 is_star : star,
2092 expression : has_expression ? expression() : null,
2093 end : prev()
2094 });
2095 }
2096
2097 function if_() {
2098 var cond = parenthesised(), body = statement(false, false, true), belse = null;
2099 if (is("keyword", "else")) {
2100 next();
2101 belse = statement(false, false, true);
2102 }
2103 return new AST_If({
2104 condition : cond,
2105 body : body,
2106 alternative : belse
2107 });
2108 }
2109
2110 function block_() {
2111 expect("{");
2112 var a = [];
2113 while (!is("punc", "}")) {
2114 if (is("eof")) unexpected();
2115 a.push(statement());
2116 }
2117 next();
2118 return a;
2119 }
2120
2121 function switch_body_() {
2122 expect("{");
2123 var a = [], cur = null, branch = null, tmp;
2124 while (!is("punc", "}")) {
2125 if (is("eof")) unexpected();
2126 if (is("keyword", "case")) {
2127 if (branch) branch.end = prev();
2128 cur = [];
2129 branch = new AST_Case({
2130 start : (tmp = S.token, next(), tmp),
2131 expression : expression(true),
2132 body : cur
2133 });
2134 a.push(branch);
2135 expect(":");
2136 } else if (is("keyword", "default")) {
2137 if (branch) branch.end = prev();
2138 cur = [];
2139 branch = new AST_Default({
2140 start : (tmp = S.token, next(), expect(":"), tmp),
2141 body : cur
2142 });
2143 a.push(branch);
2144 } else {
2145 if (!cur) unexpected();
2146 cur.push(statement());
2147 }
2148 }
2149 if (branch) branch.end = prev();
2150 next();
2151 return a;
2152 }
2153
2154 function try_() {
2155 var body, bcatch = null, bfinally = null;
2156 body = new AST_TryBlock({
2157 start : S.token,
2158 body : block_(),
2159 end : prev(),
2160 });
2161 if (is("keyword", "catch")) {
2162 var start = S.token;
2163 next();
2164 if (is("punc", "{")) {
2165 var name = null;
2166 } else {
2167 expect("(");
2168 var name = parameter(undefined, AST_SymbolCatch);
2169 expect(")");
2170 }
2171 bcatch = new AST_Catch({
2172 start : start,
2173 argname : name,
2174 body : block_(),
2175 end : prev()
2176 });
2177 }
2178 if (is("keyword", "finally")) {
2179 var start = S.token;
2180 next();
2181 bfinally = new AST_Finally({
2182 start : start,
2183 body : block_(),
2184 end : prev()
2185 });
2186 }
2187 if (!bcatch && !bfinally)
2188 croak("Missing catch/finally blocks");
2189 return new AST_Try({
2190 body : body,
2191 bcatch : bcatch,
2192 bfinally : bfinally
2193 });
2194 }
2195
2196 /**
2197 * var
2198 * vardef1 = 2,
2199 * vardef2 = 3;
2200 */
2201 function vardefs(no_in, kind) {
2202 var var_defs = [];
2203 var def;
2204 for (;;) {
2205 var sym_type =
2206 kind === "var" ? AST_SymbolVar :
2207 kind === "const" ? AST_SymbolConst :
2208 kind === "let" ? AST_SymbolLet :
2209 kind === "using" ? AST_SymbolUsing :
2210 kind === "await using" ? AST_SymbolUsing : null;
2211 var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef;
2212 // var { a } = b
2213 if (is("punc", "{") || is("punc", "[")) {
2214 def = new def_type({
2215 start: S.token,
2216 name: binding_element(undefined, sym_type),
2217 value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
2218 end: prev()
2219 });
2220 } else {
2221 def = new def_type({
2222 start : S.token,
2223 name : as_symbol(sym_type),
2224 value : is("operator", "=")
2225 ? (next(), expression(false, no_in))
2226 : !no_in && (kind === "const" || kind === "using" || kind === "await using")
2227 ? croak("Missing initializer in " + kind + " declaration") : null,
2228 end : prev()
2229 });
2230 if (def.name.name == "import") croak("Unexpected token: import");
2231 }
2232 var_defs.push(def);
2233 if (!is("punc", ","))
2234 break;
2235 next();
2236 }
2237 return var_defs;
2238 }
2239
2240 var var_ = function(no_in) {
2241 return new AST_Var({
2242 start : prev(),
2243 definitions : vardefs(no_in, "var"),
2244 end : prev()
2245 });
2246 };
2247
2248 var let_ = function(no_in) {
2249 return new AST_Let({
2250 start : prev(),
2251 definitions : vardefs(no_in, "let"),
2252 end : prev()
2253 });
2254 };
2255
2256 var const_ = function(no_in) {
2257 return new AST_Const({
2258 start : prev(),
2259 definitions : vardefs(no_in, "const"),
2260 end : prev()
2261 });
2262 };
2263
2264 var using_ = function(no_in) {
2265 return new AST_Using({
2266 start : prev(),
2267 await : false,
2268 definitions : vardefs(no_in, "using"),
2269 end : prev()
2270 });
2271 };
2272
2273 var await_using_ = function(no_in) {
2274 // Assumption: When await_using_ is called, only the `await` token has been consumed.
2275 return new AST_Using({
2276 start : prev(),
2277 await : true,
2278 definitions : (next(), vardefs(no_in, "await using")),
2279 end : prev()
2280 });
2281 };
2282
2283 var new_ = function(allow_calls) {
2284 var start = S.token;
2285 expect_token("operator", "new");
2286 if (is("punc", ".")) {
2287 next();
2288 expect_token("name", "target");
2289 return subscripts(new AST_NewTarget({
2290 start : start,
2291 end : prev()
2292 }), allow_calls);
2293 }
2294 var newexp = expr_atom(false), args;
2295 if (is("punc", "(")) {
2296 next();
2297 args = expr_list(")", true);
2298 } else {
2299 args = [];
2300 }
2301 var call = new AST_New({
2302 start : start,
2303 expression : newexp,
2304 args : args,
2305 end : prev()
2306 });
2307 annotate(call);
2308 return subscripts(call, allow_calls);
2309 };
2310
2311 function as_atom_node() {
2312 var tok = S.token, ret;
2313 switch (tok.type) {
2314 case "name":
2315 ret = _make_symbol(AST_SymbolRef);
2316 break;
2317 case "num":
2318 if (tok.value === Infinity) {
2319 // very large float values are parsed as Infinity
2320 ret = new AST_Infinity({
2321 start: tok,
2322 end: tok,
2323 });
2324 } else {
2325 ret = new AST_Number({
2326 start: tok,
2327 end: tok,
2328 value: tok.value,
2329 raw: LATEST_RAW
2330 });
2331 }
2332 break;
2333 case "big_int":
2334 ret = new AST_BigInt({
2335 start: tok,
2336 end: tok,
2337 value: tok.value,
2338 raw: LATEST_RAW,
2339 });
2340 break;
2341 case "string":
2342 ret = new AST_String({
2343 start : tok,
2344 end : tok,
2345 value : tok.value,
2346 quote : tok.quote
2347 });
2348 annotate(ret);
2349 break;
2350 case "regexp":
2351 const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/);
2352
2353 ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } });
2354 break;
2355 case "atom":
2356 switch (tok.value) {
2357 case "false":
2358 ret = new AST_False({ start: tok, end: tok });
2359 break;
2360 case "true":
2361 ret = new AST_True({ start: tok, end: tok });
2362 break;
2363 case "null":
2364 ret = new AST_Null({ start: tok, end: tok });
2365 break;
2366 }
2367 break;
2368 }
2369 next();
2370 return ret;
2371 }
2372
2373 function to_fun_args(ex, default_seen_above) {
2374 var insert_default = function(ex, default_value) {
2375 if (default_value) {
2376 return new AST_DefaultAssign({
2377 start: ex.start,
2378 left: ex,
2379 operator: "=",
2380 right: default_value,
2381 end: default_value.end
2382 });
2383 }
2384 return ex;
2385 };
2386 if (ex instanceof AST_Object) {
2387 return insert_default(new AST_Destructuring({
2388 start: ex.start,
2389 end: ex.end,
2390 is_array: false,
2391 names: ex.properties.map(prop => to_fun_args(prop))
2392 }), default_seen_above);
2393 } else if (ex instanceof AST_ObjectKeyVal) {
2394 ex.value = to_fun_args(ex.value);
2395 return insert_default(ex, default_seen_above);
2396 } else if (ex instanceof AST_Hole) {
2397 return ex;
2398 } else if (ex instanceof AST_Destructuring) {
2399 ex.names = ex.names.map(name => to_fun_args(name));
2400 return insert_default(ex, default_seen_above);
2401 } else if (ex instanceof AST_SymbolRef) {
2402 return insert_default(new AST_SymbolFunarg({
2403 name: ex.name,
2404 start: ex.start,
2405 end: ex.end
2406 }), default_seen_above);
2407 } else if (ex instanceof AST_Expansion) {
2408 ex.expression = to_fun_args(ex.expression);
2409 return insert_default(ex, default_seen_above);
2410 } else if (ex instanceof AST_Array) {
2411 return insert_default(new AST_Destructuring({
2412 start: ex.start,
2413 end: ex.end,
2414 is_array: true,
2415 names: ex.elements.map(elm => to_fun_args(elm))
2416 }), default_seen_above);
2417 } else if (ex instanceof AST_Assign) {
2418 return insert_default(to_fun_args(ex.left, ex.right), default_seen_above);
2419 } else if (ex instanceof AST_DefaultAssign) {
2420 ex.left = to_fun_args(ex.left);
2421 return ex;
2422 } else {
2423 croak("Invalid function parameter", ex.start.line, ex.start.col);
2424 }
2425 }
2426
2427 var expr_atom = function(allow_calls, allow_arrows) {
2428 if (is("operator", "new")) {
2429 return new_(allow_calls);
2430 }
2431 if (is("name", "import") && is_token(peek(), "punc", ".")) {
2432 return parse_import_expr(allow_calls);
2433 }
2434 var start = S.token;
2435 var peeked;
2436 var async = is("name", "async")
2437 && (peeked = peek()).value != "["
2438 && peeked.type != "arrow"
2439 && as_atom_node();
2440 if (is("punc")) {
2441 switch (S.token.value) {
2442 case "(":
2443 if (async && !allow_calls) break;
2444 var exprs = params_or_seq_(allow_arrows, !async);
2445 if (allow_arrows && is("arrow", "=>")) {
2446 return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async);
2447 }
2448 var ex = async ? new AST_Call({
2449 expression: async,
2450 args: exprs
2451 }) : to_expr_or_sequence(start, exprs);
2452 if (ex.start) {
2453 const outer_comments_before = start.comments_before.length;
2454 outer_comments_before_counts.set(start, outer_comments_before);
2455 ex.start.comments_before.unshift(...start.comments_before);
2456 start.comments_before = ex.start.comments_before;
2457 if (outer_comments_before == 0 && start.comments_before.length > 0) {
2458 var comment = start.comments_before[0];
2459 if (!comment.nlb) {
2460 comment.nlb = start.nlb;
2461 start.nlb = false;
2462 }
2463 }
2464 start.comments_after = ex.start.comments_after;
2465 }
2466 ex.start = start;
2467 var end = prev();
2468 if (ex.end) {
2469 end.comments_before = ex.end.comments_before;
2470 ex.end.comments_after.push(...end.comments_after);
2471 end.comments_after = ex.end.comments_after;
2472 }
2473 ex.end = end;
2474 if (ex instanceof AST_Call) annotate(ex);
2475 return subscripts(ex, allow_calls);
2476 case "[":
2477 return subscripts(array_(), allow_calls);
2478 case "{":
2479 return subscripts(object_or_destructuring_(), allow_calls);
2480 }
2481 if (!async) unexpected();
2482 }
2483 if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
2484 var param = new AST_SymbolFunarg({
2485 name: S.token.value,
2486 start: start,
2487 end: start,
2488 });
2489 next();
2490 return arrow_function(start, [param], !!async);
2491 }
2492 if (is("keyword", "function")) {
2493 next();
2494 var func = function_(AST_Function, false, !!async);
2495 func.start = start;
2496 func.end = prev();
2497 return subscripts(func, allow_calls);
2498 }
2499 if (async) return subscripts(async, allow_calls);
2500 if (is("keyword", "class")) {
2501 next();
2502 var cls = class_(AST_ClassExpression);
2503 cls.start = start;
2504 cls.end = prev();
2505 return subscripts(cls, allow_calls);
2506 }
2507 if (is("template_head")) {
2508 return subscripts(template_string(), allow_calls);
2509 }
2510 if (ATOMIC_START_TOKEN.has(S.token.type)) {
2511 return subscripts(as_atom_node(), allow_calls);
2512 }
2513 unexpected();
2514 };
2515
2516 function template_string() {
2517 var segments = [], start = S.token;
2518
2519 segments.push(new AST_TemplateSegment({
2520 start: S.token,
2521 raw: TEMPLATE_RAWS.get(S.token),
2522 value: S.token.value,
2523 end: S.token
2524 }));
2525
2526 while (!S.token.template_end) {
2527 next();
2528 handle_regexp();
2529 segments.push(expression(true));
2530
2531 segments.push(new AST_TemplateSegment({
2532 start: S.token,
2533 raw: TEMPLATE_RAWS.get(S.token),
2534 value: S.token.value,
2535 end: S.token
2536 }));
2537 }
2538 next();
2539
2540 return new AST_TemplateString({
2541 start: start,
2542 segments: segments,
2543 end: S.token
2544 });
2545 }
2546
2547 function expr_list(closing, allow_trailing_comma, allow_empty) {
2548 var first = true, a = [];
2549 while (!is("punc", closing)) {
2550 if (first) first = false; else expect(",");
2551 if (allow_trailing_comma && is("punc", closing)) break;
2552 if (is("punc", ",") && allow_empty) {
2553 a.push(new AST_Hole({ start: S.token, end: S.token }));
2554 } else if (is("expand", "...")) {
2555 next();
2556 a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token}));
2557 } else {
2558 a.push(expression(false));
2559 }
2560 }
2561 next();
2562 return a;
2563 }
2564
2565 var array_ = embed_tokens(function() {
2566 expect("[");
2567 return new AST_Array({
2568 elements: expr_list("]", !options.strict, true)
2569 });
2570 });
2571
2572 var create_accessor = embed_tokens((is_generator, is_async) => {
2573 return function_(AST_Accessor, is_generator, is_async);
2574 });
2575
2576 var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
2577 var start = S.token, first = true, a = [];
2578 expect("{");
2579 while (!is("punc", "}")) {
2580 if (first) first = false; else expect(",");
2581 if (!options.strict && is("punc", "}"))
2582 // allow trailing comma
2583 break;
2584
2585 start = S.token;
2586 if (start.type == "expand") {
2587 next();
2588 a.push(new AST_Expansion({
2589 start: start,
2590 expression: expression(false),
2591 end: prev(),
2592 }));
2593 continue;
2594 }
2595 if(is("privatename")) {
2596 croak("private fields are not allowed in an object");
2597 }
2598 var name = as_property_name();
2599 var value;
2600
2601 // Check property and fetch value
2602 if (!is("punc", ":")) {
2603 var concise = object_or_class_property(name, start);
2604 if (concise) {
2605 a.push(concise);
2606 continue;
2607 }
2608
2609 value = new AST_SymbolRef({
2610 start: prev(),
2611 name: name,
2612 end: prev()
2613 });
2614 } else if (name === null) {
2615 unexpected(prev());
2616 } else {
2617 next(); // `:` - see first condition
2618 value = expression(false);
2619 }
2620
2621 // Check for default value and alter value accordingly if necessary
2622 if (is("operator", "=")) {
2623 next();
2624 value = new AST_Assign({
2625 start: start,
2626 left: value,
2627 operator: "=",
2628 right: expression(false),
2629 logical: false,
2630 end: prev()
2631 });
2632 }
2633
2634 // Create property
2635 const kv = new AST_ObjectKeyVal({
2636 start: start,
2637 quote: start.quote,
2638 key: name,
2639 value: value,
2640 end: prev()
2641 });
2642 a.push(annotate(kv));
2643 }
2644 next();
2645 return new AST_Object({ properties: a });
2646 });
2647
2648 function class_(KindOfClass, is_export_default) {
2649 var start, method, class_name, extends_, properties = [];
2650
2651 S.input.push_directives_stack(); // Push directive stack, but not scope stack
2652 S.input.add_directive("use strict");
2653
2654 if (S.token.type == "name" && S.token.value != "extends") {
2655 class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
2656 }
2657
2658 if (KindOfClass === AST_DefClass && !class_name) {
2659 if (is_export_default) {
2660 KindOfClass = AST_ClassExpression;
2661 } else {
2662 unexpected();
2663 }
2664 }
2665
2666 if (S.token.value == "extends") {
2667 next();
2668 extends_ = expression(true);
2669 }
2670
2671 expect("{");
2672 // mark in class feild,
2673 const save_in_class = S.in_class;
2674 S.in_class = true;
2675 while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
2676 while (!is("punc", "}")) {
2677 start = S.token;
2678 method = object_or_class_property(as_property_name(), start, true);
2679 if (!method) { unexpected(); }
2680 properties.push(method);
2681 while (is("punc", ";")) { next(); }
2682 }
2683 // mark in class feild,
2684 S.in_class = save_in_class;
2685
2686 S.input.pop_directives_stack();
2687
2688 next();
2689
2690 return new KindOfClass({
2691 start: start,
2692 name: class_name,
2693 extends: extends_,
2694 properties: properties,
2695 end: prev(),
2696 });
2697 }
2698
2699 function object_or_class_property(name, start, is_class) {
2700 const get_symbol_ast = (name, SymbolClass) => {
2701 if (typeof name === "string") {
2702 return new SymbolClass({ start, name, end: prev() });
2703 } else if (name === null) {
2704 unexpected();
2705 }
2706 return name;
2707 };
2708
2709 var is_private = prev().type === "privatename";
2710 const is_not_method_start = () =>
2711 !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private;
2712
2713 var is_async = false;
2714 var is_static = false;
2715 var is_generator = false;
2716 var accessor_type = null;
2717
2718 if (is_class && name === "static" && is_not_method_start()) {
2719 const static_block = class_static_block();
2720 if (static_block != null) {
2721 return static_block;
2722 }
2723 is_static = true;
2724 name = as_property_name();
2725 }
2726 if (name === "async" && is_not_method_start()) {
2727 is_async = true;
2728 name = as_property_name();
2729 }
2730 if (prev().type === "operator" && prev().value === "*") {
2731 is_generator = true;
2732 name = as_property_name();
2733 }
2734 if ((name === "get" || name === "set") && is_not_method_start()) {
2735 accessor_type = name;
2736 name = as_property_name();
2737 }
2738 if (!is_private && prev().type === "privatename") {
2739 is_private = true;
2740 }
2741
2742 const property_token = prev();
2743
2744 if (accessor_type != null) {
2745 if (!is_private) {
2746 const AccessorClass = accessor_type === "get"
2747 ? AST_ObjectGetter
2748 : AST_ObjectSetter;
2749
2750 name = get_symbol_ast(name, AST_SymbolMethod);
2751 return annotate(new AccessorClass({
2752 start,
2753 static: is_static,
2754 key: name,
2755 quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
2756 value: create_accessor(),
2757 end: prev()
2758 }));
2759 } else {
2760 const AccessorClass = accessor_type === "get"
2761 ? AST_PrivateGetter
2762 : AST_PrivateSetter;
2763
2764 return annotate(new AccessorClass({
2765 start,
2766 static: is_static,
2767 key: get_symbol_ast(name, AST_SymbolMethod),
2768 value: create_accessor(),
2769 end: prev(),
2770 }));
2771 }
2772 }
2773
2774 if (is("punc", "(")) {
2775 name = get_symbol_ast(name, AST_SymbolMethod);
2776 const AST_MethodVariant = is_private
2777 ? AST_PrivateMethod
2778 : AST_ConciseMethod;
2779 var node = new AST_MethodVariant({
2780 start : start,
2781 static : is_static,
2782 key : name,
2783 quote : name instanceof AST_SymbolMethod ?
2784 property_token.quote : undefined,
2785 value : create_accessor(is_generator, is_async),
2786 end : prev()
2787 });
2788 return annotate(node);
2789 }
2790
2791 if (is_class) {
2792 const AST_SymbolVariant = is_private
2793 ? AST_SymbolPrivateProperty
2794 : AST_SymbolClassProperty;
2795 const AST_ClassPropertyVariant = is_private
2796 ? AST_ClassPrivateProperty
2797 : AST_ClassProperty;
2798
2799 const key = get_symbol_ast(name, AST_SymbolVariant);
2800 const quote = key instanceof AST_SymbolClassProperty
2801 ? property_token.quote
2802 : undefined;
2803 if (is("operator", "=")) {
2804 next();
2805 return annotate(
2806 new AST_ClassPropertyVariant({
2807 start,
2808 static: is_static,
2809 quote,
2810 key,
2811 value: expression(false),
2812 end: prev()
2813 })
2814 );
2815 } else if (
2816 is("name")
2817 || is("privatename")
2818 || is("punc", "[")
2819 || is("operator", "*")
2820 || is("punc", ";")
2821 || is("punc", "}")
2822 || is("string")
2823 || is("num")
2824 || is("big_int")
2825 ) {
2826 return annotate(
2827 new AST_ClassPropertyVariant({
2828 start,
2829 static: is_static,
2830 quote,
2831 key,
2832 end: prev()
2833 })
2834 );
2835 }
2836 }
2837 }
2838
2839 function class_static_block() {
2840 if (!is("punc", "{")) {
2841 return null;
2842 }
2843
2844 const start = S.token;
2845 const body = [];
2846
2847 next();
2848
2849 while (!is("punc", "}")) {
2850 body.push(statement());
2851 }
2852
2853 next();
2854
2855 return new AST_ClassStaticBlock({ start, body, end: prev() });
2856 }
2857
2858 function maybe_import_attributes() {
2859 if (
2860 (is("keyword", "with") || is("name", "assert"))
2861 && !has_newline_before(S.token)
2862 ) {
2863 next();
2864 return object_or_destructuring_();
2865 }
2866 return null;
2867 }
2868
2869 function import_statement() {
2870 var start = prev();
2871
2872 // import source x from "..."
2873 // import defer * as x from "..."
2874 var phase = null;
2875 if (is("name", "source") || is("name", "defer")) {
2876 var peeked = peek();
2877 if (!is_token(peeked, "name", "from") && !is_token(peeked, "punc", ",")) {
2878 phase = S.token.value;
2879 next();
2880 }
2881 }
2882
2883 var imported_name;
2884 var imported_names;
2885 if (is("name")) {
2886 imported_name = as_symbol(AST_SymbolImport);
2887 }
2888
2889 if (is("punc", ",")) {
2890 next();
2891 }
2892
2893 imported_names = map_names(true);
2894
2895 if (imported_names || imported_name) {
2896 expect_token("name", "from");
2897 }
2898 var mod_str = S.token;
2899 if (mod_str.type !== "string") {
2900 unexpected();
2901 }
2902 next();
2903
2904 const attributes = maybe_import_attributes();
2905
2906 return new AST_Import({
2907 start,
2908 imported_name,
2909 imported_names,
2910 module_name: new AST_String({
2911 start: mod_str,
2912 value: mod_str.value,
2913 quote: mod_str.quote,
2914 end: mod_str,
2915 }),
2916 attributes,
2917 phase,
2918 end: S.token,
2919 });
2920 }
2921
2922 // import.meta
2923 // import.source("module")
2924 // import.defer("module")
2925 function parse_import_expr(allow_calls) {
2926 var start = S.token;
2927 expect_token("name", "import");
2928 expect_token("punc", ".");
2929 if (is("name", "source") || is("name", "defer")) {
2930 var phase = S.token.value;
2931 next();
2932 if (!is("punc", "(")) {
2933 croak("'import." + phase + "' can only be used in a dynamic import");
2934 }
2935 next();
2936 var args = expr_list(")");
2937 return subscripts(new AST_DynamicImport({
2938 start: start,
2939 phase: phase,
2940 args: args,
2941 end: prev()
2942 }), allow_calls);
2943 }
2944 expect_token("name", "meta");
2945 return subscripts(new AST_ImportMeta({
2946 start: start,
2947 end: prev()
2948 }), allow_calls);
2949 }
2950
2951 function map_name(is_import) {
2952 function make_symbol(type, quote) {
2953 return new type({
2954 name: as_property_name(),
2955 quote: quote || undefined,
2956 start: prev(),
2957 end: prev()
2958 });
2959 }
2960
2961 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2962 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2963 var start = S.token;
2964 var foreign_name;
2965 var name;
2966
2967 if (is_import) {
2968 foreign_name = make_symbol(foreign_type, start.quote);
2969 } else {
2970 name = make_symbol(type, start.quote);
2971 }
2972 if (is("name", "as")) {
2973 next(); // The "as" word
2974 if (is_import) {
2975 name = make_symbol(type);
2976 } else {
2977 foreign_name = make_symbol(foreign_type, S.token.quote);
2978 }
2979 } else {
2980 if (is_import) {
2981 name = new type(foreign_name);
2982 } else {
2983 foreign_name = new foreign_type(name);
2984 }
2985 }
2986
2987 return new AST_NameMapping({
2988 start: start,
2989 foreign_name: foreign_name,
2990 name: name,
2991 end: prev(),
2992 });
2993 }
2994
2995 function map_nameAsterisk(is_import, import_or_export_foreign_name) {
2996 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2997 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2998 var start = S.token;
2999 var name, foreign_name;
3000 var end = prev();
3001
3002 if (is_import) {
3003 name = import_or_export_foreign_name;
3004 } else {
3005 foreign_name = import_or_export_foreign_name;
3006 }
3007
3008 name = name || new type({
3009 start: start,
3010 name: "*",
3011 end: end,
3012 });
3013
3014 foreign_name = foreign_name || new foreign_type({
3015 start: start,
3016 name: "*",
3017 end: end,
3018 });
3019
3020 return new AST_NameMapping({
3021 start: start,
3022 foreign_name: foreign_name,
3023 name: name,
3024 end: end,
3025 });
3026 }
3027
3028 function map_names(is_import) {
3029 var names;
3030 if (is("punc", "{")) {
3031 next();
3032 names = [];
3033 while (!is("punc", "}")) {
3034 names.push(map_name(is_import));
3035 if (is("punc", ",")) {
3036 next();
3037 }
3038 }
3039 next();
3040 } else if (is("operator", "*")) {
3041 var name;
3042 next();
3043 if (is("name", "as")) {
3044 next(); // The "as" word
3045 name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
3046 }
3047 names = [map_nameAsterisk(is_import, name)];
3048 }
3049 return names;
3050 }
3051
3052 function export_statement() {
3053 var start = S.token;
3054 var is_default;
3055 var exported_names;
3056
3057 if (is("keyword", "default")) {
3058 is_default = true;
3059 next();
3060 } else if (exported_names = map_names(false)) {
3061 if (is("name", "from")) {
3062 next();
3063
3064 var mod_str = S.token;
3065 if (mod_str.type !== "string") {
3066 unexpected();
3067 }
3068 next();
3069
3070 const attributes = maybe_import_attributes();
3071
3072 return new AST_Export({
3073 start: start,
3074 is_default: is_default,
3075 exported_names: exported_names,
3076 module_name: new AST_String({
3077 start: mod_str,
3078 value: mod_str.value,
3079 quote: mod_str.quote,
3080 end: mod_str,
3081 }),
3082 end: prev(),
3083 attributes
3084 });
3085 } else {
3086 return new AST_Export({
3087 start: start,
3088 is_default: is_default,
3089 exported_names: exported_names,
3090 end: prev(),
3091 });
3092 }
3093 }
3094
3095 var node;
3096 var exported_value;
3097 var exported_definition;
3098 if (is("punc", "{")
3099 || is_default
3100 && (is("keyword", "class") || is("keyword", "function"))
3101 && is_token(peek(), "punc")) {
3102 exported_value = expression(false);
3103 semicolon();
3104 } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
3105 unexpected(node.start);
3106 } else if (
3107 node instanceof AST_Definitions
3108 || node instanceof AST_Defun
3109 || node instanceof AST_DefClass
3110 ) {
3111 exported_definition = node;
3112 } else if (
3113 node instanceof AST_ClassExpression
3114 || node instanceof AST_Function
3115 ) {
3116 exported_value = node;
3117 } else if (node instanceof AST_SimpleStatement) {
3118 exported_value = node.body;
3119 } else {
3120 unexpected(node.start);
3121 }
3122
3123 return new AST_Export({
3124 start: start,
3125 is_default: is_default,
3126 exported_value: exported_value,
3127 exported_definition: exported_definition,
3128 end: prev(),
3129 attributes: null
3130 });
3131 }
3132
3133 function as_property_name() {
3134 var tmp = S.token;
3135 switch (tmp.type) {
3136 case "punc":
3137 if (tmp.value === "[") {
3138 next();
3139 var ex = expression(false);
3140 expect("]");
3141 return ex;
3142 } else unexpected(tmp);
3143 case "operator":
3144 if (tmp.value === "*") {
3145 next();
3146 return null;
3147 }
3148 if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) {
3149 unexpected(tmp);
3150 }
3151 /* falls through */
3152 case "name":
3153 case "privatename":
3154 case "string":
3155 case "keyword":
3156 case "atom":
3157 next();
3158 return tmp.value;
3159 case "num":
3160 case "big_int":
3161 next();
3162 return "" + tmp.value;
3163 default:
3164 unexpected(tmp);
3165 }
3166 }
3167
3168 function as_name() {
3169 var tmp = S.token;
3170 if (tmp.type != "name" && tmp.type != "privatename") unexpected();
3171 next();
3172 return tmp.value;
3173 }
3174
3175 function _make_symbol(type) {
3176 var name = S.token.value;
3177 return new (name == "this" ? AST_This :
3178 name == "super" ? AST_Super :
3179 type)({
3180 name : String(name),
3181 start : S.token,
3182 end : S.token
3183 });
3184 }
3185
3186 function _verify_symbol(sym) {
3187 var name = sym.name;
3188 if (is_in_generator() && name == "yield") {
3189 token_error(sym.start, "Yield cannot be used as identifier inside generators");
3190 }
3191 if (S.input.has_directive("use strict")) {
3192 if (name == "yield") {
3193 token_error(sym.start, "Unexpected yield identifier inside strict mode");
3194 }
3195 if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
3196 token_error(sym.start, "Unexpected " + name + " in strict mode");
3197 }
3198 }
3199 }
3200
3201 function as_symbol(type, noerror) {
3202 if (!is("name")) {
3203 if (!noerror) croak("Name expected");
3204 return null;
3205 }
3206 var sym = _make_symbol(type);
3207 _verify_symbol(sym);
3208 next();
3209 return sym;
3210 }
3211
3212 function as_symbol_or_string(type) {
3213 if (!is("name")) {
3214 if (!is("string")) {
3215 croak("Name or string expected");
3216 }
3217 var tok = S.token;
3218 var ret = new type({
3219 start : tok,
3220 end : tok,
3221 name : tok.value,
3222 quote : tok.quote
3223 });
3224 next();
3225 return ret;
3226 }
3227 var sym = _make_symbol(type);
3228 _verify_symbol(sym);
3229 next();
3230 return sym;
3231 }
3232
3233 // Annotate AST_Call, AST_Lambda or AST_New with the special comments
3234 function annotate(node, before_token = node.start) {
3235 var comments = before_token.comments_before;
3236 const comments_outside_parens = outer_comments_before_counts.get(before_token);
3237 var i = comments_outside_parens != null ? comments_outside_parens : comments.length;
3238 while (--i >= 0) {
3239 var comment = comments[i];
3240 if (/[@#]__/.test(comment.value)) {
3241 if (/[@#]__PURE__/.test(comment.value)) {
3242 set_annotation(node, _PURE);
3243 break;
3244 }
3245 if (/[@#]__INLINE__/.test(comment.value)) {
3246 set_annotation(node, _INLINE);
3247 break;
3248 }
3249 if (/[@#]__NOINLINE__/.test(comment.value)) {
3250 set_annotation(node, _NOINLINE);
3251 break;
3252 }
3253 if (/[@#]__KEY__/.test(comment.value)) {
3254 set_annotation(node, _KEY);
3255 break;
3256 }
3257 if (/[@#]__MANGLE_PROP__/.test(comment.value)) {
3258 set_annotation(node, _MANGLEPROP);
3259 break;
3260 }
3261 }
3262 }
3263 return node;
3264 }
3265
3266 var subscripts = function(expr, allow_calls, is_chain) {
3267 var start = expr.start;
3268 if (is("punc", ".")) {
3269 next();
3270 if(is("privatename") && !S.in_class)
3271 croak("Private field must be used in an enclosing class");
3272 const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
3273 return annotate(subscripts(new AST_DotVariant({
3274 start : start,
3275 expression : expr,
3276 optional : false,
3277 property : as_name(),
3278 end : prev()
3279 }), allow_calls, is_chain));
3280 }
3281 if (is("punc", "[")) {
3282 next();
3283 var prop = expression(true);
3284 expect("]");
3285 return annotate(subscripts(new AST_Sub({
3286 start : start,
3287 expression : expr,
3288 optional : false,
3289 property : prop,
3290 end : prev()
3291 }), allow_calls, is_chain));
3292 }
3293 if (allow_calls && is("punc", "(")) {
3294 next();
3295 var call = new AST_Call({
3296 start : start,
3297 expression : expr,
3298 optional : false,
3299 args : call_args(),
3300 end : prev()
3301 });
3302 annotate(call);
3303 return subscripts(call, true, is_chain);
3304 }
3305
3306 // Optional chain
3307 if (is("punc", "?.")) {
3308 next();
3309
3310 let chain_contents;
3311
3312 if (allow_calls && is("punc", "(")) {
3313 next();
3314
3315 const call = new AST_Call({
3316 start,
3317 optional: true,
3318 expression: expr,
3319 args: call_args(),
3320 end: prev()
3321 });
3322 annotate(call);
3323
3324 chain_contents = subscripts(call, true, true);
3325 } else if (is("name") || is("privatename")) {
3326 if(is("privatename") && !S.in_class)
3327 croak("Private field must be used in an enclosing class");
3328 const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
3329 chain_contents = annotate(subscripts(new AST_DotVariant({
3330 start,
3331 expression: expr,
3332 optional: true,
3333 property: as_name(),
3334 end: prev()
3335 }), allow_calls, true));
3336 } else if (is("punc", "[")) {
3337 next();
3338 const property = expression(true);
3339 expect("]");
3340 chain_contents = annotate(subscripts(new AST_Sub({
3341 start,
3342 expression: expr,
3343 optional: true,
3344 property,
3345 end: prev()
3346 }), allow_calls, true));
3347 }
3348
3349 if (!chain_contents) unexpected();
3350
3351 if (chain_contents instanceof AST_Chain) return chain_contents;
3352
3353 return new AST_Chain({
3354 start,
3355 expression: chain_contents,
3356 end: prev()
3357 });
3358 }
3359
3360 if (is("template_head")) {
3361 if (is_chain) {
3362 // a?.b`c` is a syntax error
3363 unexpected();
3364 }
3365
3366 return subscripts(new AST_PrefixedTemplateString({
3367 start: start,
3368 prefix: expr,
3369 template_string: template_string(),
3370 end: prev()
3371 }), allow_calls);
3372 }
3373 return expr;
3374 };
3375
3376 function call_args() {
3377 var args = [];
3378 while (!is("punc", ")")) {
3379 if (is("expand", "...")) {
3380 next();
3381 args.push(new AST_Expansion({
3382 start: prev(),
3383 expression: expression(false),
3384 end: prev()
3385 }));
3386 } else {
3387 args.push(expression(false));
3388 }
3389 if (!is("punc", ")")) {
3390 expect(",");
3391 }
3392 }
3393 next();
3394 return args;
3395 }
3396
3397 var maybe_unary = function(allow_calls, allow_arrows) {
3398 var start = S.token;
3399 if (start.type == "name" && start.value == "await" && can_await()) {
3400 next();
3401 return _await_expression();
3402 }
3403 if (is("operator") && UNARY_PREFIX.has(start.value)) {
3404 next();
3405 handle_regexp();
3406 var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
3407 ex.start = start;
3408 ex.end = prev();
3409 return ex;
3410 }
3411 var val = expr_atom(allow_calls, allow_arrows);
3412 while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) {
3413 if (val instanceof AST_Arrow) unexpected();
3414 val = make_unary(AST_UnaryPostfix, S.token, val);
3415 val.start = start;
3416 val.end = S.token;
3417 next();
3418 }
3419 return val;
3420 };
3421
3422 function make_unary(ctor, token, expr) {
3423 var op = token.value;
3424 switch (op) {
3425 case "++":
3426 case "--":
3427 if (!is_assignable(expr))
3428 croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
3429 break;
3430 case "delete":
3431 if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
3432 croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
3433 break;
3434 }
3435 return new ctor({ operator: op, expression: expr });
3436 }
3437
3438 var expr_op = function(left, min_prec, no_in) {
3439 var op = is("operator") ? S.token.value : null;
3440 if (op == "in" && no_in) op = null;
3441 if (op == "**" && left instanceof AST_UnaryPrefix
3442 /* unary token in front not allowed - parenthesis required */
3443 && !is_token(left.start, "punc", "(")
3444 && left.operator !== "--" && left.operator !== "++")
3445 unexpected(left.start);
3446 var prec = op != null ? PRECEDENCE[op] : null;
3447 if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) {
3448 next();
3449 var right = expr_ops(no_in, prec, true);
3450 return expr_op(new AST_Binary({
3451 start : left.start,
3452 left : left,
3453 operator : op,
3454 right : right,
3455 end : right.end
3456 }), min_prec, no_in);
3457 }
3458 return left;
3459 };
3460
3461 function expr_ops(no_in, min_prec, allow_calls, allow_arrows) {
3462 // maybe_unary won't return us a AST_SymbolPrivateProperty
3463 if (!no_in && min_prec < PRECEDENCE["in"] && is("privatename")) {
3464 if(!S.in_class) {
3465 croak("Private field must be used in an enclosing class");
3466 }
3467
3468 const start = S.token;
3469 const key = new AST_SymbolPrivateProperty({
3470 start,
3471 name: start.value,
3472 end: start
3473 });
3474 next();
3475 expect_token("operator", "in");
3476
3477 const private_in = new AST_PrivateIn({
3478 start,
3479 key,
3480 value: expr_ops(no_in, PRECEDENCE["in"], true),
3481 end: prev()
3482 });
3483
3484 return expr_op(private_in, 0, no_in);
3485 } else {
3486 return expr_op(maybe_unary(allow_calls, allow_arrows), min_prec, no_in);
3487 }
3488 }
3489
3490 var maybe_conditional = function(no_in) {
3491 var start = S.token;
3492 var expr = expr_ops(no_in, 0, true, true);
3493 if (is("operator", "?")) {
3494 next();
3495 var yes = expression(false);
3496 expect(":");
3497 return new AST_Conditional({
3498 start : start,
3499 condition : expr,
3500 consequent : yes,
3501 alternative : expression(false, no_in),
3502 end : prev()
3503 });
3504 }
3505 return expr;
3506 };
3507
3508 function is_assignable(expr) {
3509 return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
3510 }
3511
3512 function to_destructuring(node) {
3513 if (node instanceof AST_Object) {
3514 node = new AST_Destructuring({
3515 start: node.start,
3516 names: node.properties.map(to_destructuring),
3517 is_array: false,
3518 end: node.end
3519 });
3520 } else if (node instanceof AST_Array) {
3521 var names = [];
3522
3523 for (var i = 0; i < node.elements.length; i++) {
3524 // Only allow expansion as last element
3525 if (node.elements[i] instanceof AST_Expansion) {
3526 if (i + 1 !== node.elements.length) {
3527 token_error(node.elements[i].start, "Spread must the be last element in destructuring array");
3528 }
3529 node.elements[i].expression = to_destructuring(node.elements[i].expression);
3530 }
3531
3532 names.push(to_destructuring(node.elements[i]));
3533 }
3534
3535 node = new AST_Destructuring({
3536 start: node.start,
3537 names: names,
3538 is_array: true,
3539 end: node.end
3540 });
3541 } else if (node instanceof AST_ObjectProperty) {
3542 node.value = to_destructuring(node.value);
3543 } else if (node instanceof AST_Assign) {
3544 node = new AST_DefaultAssign({
3545 start: node.start,
3546 left: node.left,
3547 operator: "=",
3548 right: node.right,
3549 end: node.end
3550 });
3551 }
3552 return node;
3553 }
3554
3555 // In ES6, AssignmentExpression can also be an ArrowFunction
3556 var maybe_assign = function(no_in) {
3557 handle_regexp();
3558 var start = S.token;
3559
3560 if (start.type == "name" && start.value == "yield") {
3561 if (is_in_generator()) {
3562 next();
3563 return _yield_expression();
3564 } else if (S.input.has_directive("use strict")) {
3565 token_error(S.token, "Unexpected yield identifier inside strict mode");
3566 }
3567 }
3568
3569 var left = maybe_conditional(no_in);
3570 var val = S.token.value;
3571
3572 if (is("operator") && ASSIGNMENT.has(val)) {
3573 if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
3574 next();
3575
3576 return new AST_Assign({
3577 start : start,
3578 left : left,
3579 operator : val,
3580 right : maybe_assign(no_in),
3581 logical : LOGICAL_ASSIGNMENT.has(val),
3582 end : prev()
3583 });
3584 }
3585 croak("Invalid assignment");
3586 }
3587 return left;
3588 };
3589
3590 var to_expr_or_sequence = function(start, exprs) {
3591 if (exprs.length === 1) {
3592 return exprs[0];
3593 } else if (exprs.length > 1) {
3594 return new AST_Sequence({ start, expressions: exprs, end: peek() });
3595 } else {
3596 croak("Invalid parenthesized expression");
3597 }
3598 };
3599
3600 var expression = function(commas, no_in) {
3601 var start = S.token;
3602 var exprs = [];
3603 while (true) {
3604 exprs.push(maybe_assign(no_in));
3605 if (!commas || !is("punc", ",")) break;
3606 next();
3607 commas = true;
3608 }
3609 return to_expr_or_sequence(start, exprs);
3610 };
3611
3612 function in_loop(cont) {
3613 ++S.in_loop;
3614 var ret = cont();
3615 --S.in_loop;
3616 return ret;
3617 }
3618
3619 if (options.expression) {
3620 return expression(true);
3621 }
3622
3623 return (function parse_toplevel() {
3624 var start = S.token;
3625 var body = [];
3626 S.input.push_directives_stack();
3627 if (options.module) S.input.add_directive("use strict");
3628 while (!is("eof")) {
3629 body.push(statement());
3630 }
3631 S.input.pop_directives_stack();
3632 var end = prev();
3633 var toplevel = options.toplevel;
3634 if (toplevel) {
3635 toplevel.body = toplevel.body.concat(body);
3636 toplevel.end = end;
3637 } else {
3638 toplevel = new AST_Toplevel({ start: start, body: body, end: end });
3639 }
3640 TEMPLATE_RAWS = new Map();
3641 return toplevel;
3642 })();
3643
3644}
3645
3646export {
3647 get_full_char_code,
3648 get_full_char,
3649 is_identifier_char,
3650 is_basic_identifier_string,
3651 is_identifier_string,
3652 is_surrogate_pair_head,
3653 is_surrogate_pair_tail,
3654 js_error,
3655 JS_Parse_Error,
3656 parse,
3657 PRECEDENCE,
3658 ALL_RESERVED_WORDS,
3659 tokenizer,
3660};
Note: See TracBrowser for help on using the repository browser.