UNPKG

120 kBJavaScriptView Raw
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_ClassProperty,
69 AST_ConciseMethod,
70 AST_Conditional,
71 AST_Const,
72 AST_Continue,
73 AST_Debugger,
74 AST_Default,
75 AST_DefaultAssign,
76 AST_DefClass,
77 AST_Definitions,
78 AST_Defun,
79 AST_Destructuring,
80 AST_Directive,
81 AST_Do,
82 AST_Dot,
83 AST_EmptyStatement,
84 AST_Expansion,
85 AST_Export,
86 AST_False,
87 AST_Finally,
88 AST_For,
89 AST_ForIn,
90 AST_ForOf,
91 AST_Function,
92 AST_Hole,
93 AST_If,
94 AST_Import,
95 AST_ImportMeta,
96 AST_IterationStatement,
97 AST_Label,
98 AST_LabeledStatement,
99 AST_LabelRef,
100 AST_Lambda,
101 AST_Let,
102 AST_NameMapping,
103 AST_New,
104 AST_NewTarget,
105 AST_Node,
106 AST_Null,
107 AST_Number,
108 AST_Object,
109 AST_ObjectGetter,
110 AST_ObjectKeyVal,
111 AST_ObjectProperty,
112 AST_ObjectSetter,
113 AST_PrefixedTemplateString,
114 AST_PropAccess,
115 AST_RegExp,
116 AST_Return,
117 AST_Sequence,
118 AST_SimpleStatement,
119 AST_String,
120 AST_Sub,
121 AST_Super,
122 AST_Switch,
123 AST_SymbolCatch,
124 AST_SymbolClass,
125 AST_SymbolClassProperty,
126 AST_SymbolConst,
127 AST_SymbolDeclaration,
128 AST_SymbolDefClass,
129 AST_SymbolDefun,
130 AST_SymbolExport,
131 AST_SymbolExportForeign,
132 AST_SymbolFunarg,
133 AST_SymbolImport,
134 AST_SymbolImportForeign,
135 AST_SymbolLambda,
136 AST_SymbolLet,
137 AST_SymbolMethod,
138 AST_SymbolRef,
139 AST_SymbolVar,
140 AST_TemplateSegment,
141 AST_TemplateString,
142 AST_This,
143 AST_Throw,
144 AST_Token,
145 AST_Toplevel,
146 AST_True,
147 AST_Try,
148 AST_UnaryPostfix,
149 AST_UnaryPrefix,
150 AST_Var,
151 AST_VarDef,
152 AST_While,
153 AST_With,
154 AST_Yield,
155 _INLINE,
156 _NOINLINE,
157 _PURE
158} from "./ast.js";
159
160var 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";
161var KEYWORDS_ATOM = "false null true";
162var RESERVED_WORDS = "enum implements import interface package private protected public static super this " + KEYWORDS_ATOM + " " + KEYWORDS;
163var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
164
165KEYWORDS = makePredicate(KEYWORDS);
166RESERVED_WORDS = makePredicate(RESERVED_WORDS);
167KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
168KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
169
170var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
171
172var RE_NUM_LITERAL = /[0-9a-f]/i;
173var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
174var RE_OCT_NUMBER = /^0[0-7]+$/;
175var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i;
176var RE_BIN_NUMBER = /^0b[01]+$/i;
177var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
178var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
179
180var OPERATORS = makePredicate([
181 "in",
182 "instanceof",
183 "typeof",
184 "new",
185 "void",
186 "delete",
187 "++",
188 "--",
189 "+",
190 "-",
191 "!",
192 "~",
193 "&",
194 "|",
195 "^",
196 "*",
197 "**",
198 "/",
199 "%",
200 ">>",
201 "<<",
202 ">>>",
203 "<",
204 ">",
205 "<=",
206 ">=",
207 "==",
208 "===",
209 "!=",
210 "!==",
211 "?",
212 "=",
213 "+=",
214 "-=",
215 "/=",
216 "*=",
217 "**=",
218 "%=",
219 ">>=",
220 "<<=",
221 ">>>=",
222 "|=",
223 "^=",
224 "&=",
225 "&&",
226 "??",
227 "||",
228]);
229
230var 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"));
231
232var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
233
234var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
235
236var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
237
238var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
239
240/* -----[ Tokenizer ]----- */
241
242// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
243var UNICODE = {
244 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]/,
245 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])+/,
246};
247
248function get_full_char(str, pos) {
249 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
250 if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
251 return str.charAt(pos) + str.charAt(pos + 1);
252 }
253 } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) {
254 if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) {
255 return str.charAt(pos - 1) + str.charAt(pos);
256 }
257 }
258 return str.charAt(pos);
259}
260
261function get_full_char_code(str, pos) {
262 // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
263 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
264 return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
265 }
266 return str.charCodeAt(pos);
267}
268
269function get_full_char_length(str) {
270 var surrogates = 0;
271
272 for (var i = 0; i < str.length; i++) {
273 if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
274 surrogates++;
275 i++;
276 }
277 }
278
279 return str.length - surrogates;
280}
281
282function from_char_code(code) {
283 // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
284 if (code > 0xFFFF) {
285 code -= 0x10000;
286 return (String.fromCharCode((code >> 10) + 0xD800) +
287 String.fromCharCode((code % 0x400) + 0xDC00));
288 }
289 return String.fromCharCode(code);
290}
291
292function is_surrogate_pair_head(code) {
293 return code >= 0xd800 && code <= 0xdbff;
294}
295
296function is_surrogate_pair_tail(code) {
297 return code >= 0xdc00 && code <= 0xdfff;
298}
299
300function is_digit(code) {
301 return code >= 48 && code <= 57;
302}
303
304function is_identifier_start(ch) {
305 return UNICODE.ID_Start.test(ch);
306}
307
308function is_identifier_char(ch) {
309 return UNICODE.ID_Continue.test(ch);
310}
311
312function is_basic_identifier_string(str) {
313 return /^[a-z_$][a-z0-9_$]*$/i.test(str);
314}
315
316function is_identifier_string(str, allow_surrogates) {
317 if (/^[a-z_$][a-z0-9_$]*$/i.test(str)) {
318 return true;
319 }
320 if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
321 return false;
322 }
323 var match = UNICODE.ID_Start.exec(str);
324 if (!match || match.index !== 0) {
325 return false;
326 }
327
328 str = str.slice(match[0].length);
329 if (!str) {
330 return true;
331 }
332
333 match = UNICODE.ID_Continue.exec(str);
334 return !!match && match[0].length === str.length;
335}
336
337function parse_js_number(num, allow_e = true) {
338 if (!allow_e && num.includes("e")) {
339 return NaN;
340 }
341 if (RE_HEX_NUMBER.test(num)) {
342 return parseInt(num.substr(2), 16);
343 } else if (RE_OCT_NUMBER.test(num)) {
344 return parseInt(num.substr(1), 8);
345 } else if (RE_ES6_OCT_NUMBER.test(num)) {
346 return parseInt(num.substr(2), 8);
347 } else if (RE_BIN_NUMBER.test(num)) {
348 return parseInt(num.substr(2), 2);
349 } else if (RE_DEC_NUMBER.test(num)) {
350 return parseFloat(num);
351 } else {
352 var val = parseFloat(num);
353 if (val == num) return val;
354 }
355}
356
357class JS_Parse_Error extends Error {
358 constructor(message, filename, line, col, pos) {
359 super();
360
361 this.name = "SyntaxError";
362 this.message = message;
363 this.filename = filename;
364 this.line = line;
365 this.col = col;
366 this.pos = pos;
367 }
368}
369
370function js_error(message, filename, line, col, pos) {
371 throw new JS_Parse_Error(message, filename, line, col, pos);
372}
373
374function is_token(token, type, val) {
375 return token.type == type && (val == null || token.value == val);
376}
377
378var EX_EOF = {};
379
380function tokenizer($TEXT, filename, html5_comments, shebang) {
381 var S = {
382 text : $TEXT,
383 filename : filename,
384 pos : 0,
385 tokpos : 0,
386 line : 1,
387 tokline : 0,
388 col : 0,
389 tokcol : 0,
390 newline_before : false,
391 regex_allowed : false,
392 brace_counter : 0,
393 template_braces : [],
394 comments_before : [],
395 directives : {},
396 directive_stack : []
397 };
398
399 function peek() { return get_full_char(S.text, S.pos); }
400
401 // Used because parsing ?. involves a lookahead for a digit
402 function is_option_chain_op() {
403 const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
404 if (!must_be_dot) return false;
405
406 const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
407 return cannot_be_digit < 48 || cannot_be_digit > 57;
408 }
409
410 function next(signal_eof, in_string) {
411 var ch = get_full_char(S.text, S.pos++);
412 if (signal_eof && !ch)
413 throw EX_EOF;
414 if (NEWLINE_CHARS.has(ch)) {
415 S.newline_before = S.newline_before || !in_string;
416 ++S.line;
417 S.col = 0;
418 if (ch == "\r" && peek() == "\n") {
419 // treat a \r\n sequence as a single \n
420 ++S.pos;
421 ch = "\n";
422 }
423 } else {
424 if (ch.length > 1) {
425 ++S.pos;
426 ++S.col;
427 }
428 ++S.col;
429 }
430 return ch;
431 }
432
433 function forward(i) {
434 while (i--) next();
435 }
436
437 function looking_at(str) {
438 return S.text.substr(S.pos, str.length) == str;
439 }
440
441 function find_eol() {
442 var text = S.text;
443 for (var i = S.pos, n = S.text.length; i < n; ++i) {
444 var ch = text[i];
445 if (NEWLINE_CHARS.has(ch))
446 return i;
447 }
448 return -1;
449 }
450
451 function find(what, signal_eof) {
452 var pos = S.text.indexOf(what, S.pos);
453 if (signal_eof && pos == -1) throw EX_EOF;
454 return pos;
455 }
456
457 function start_token() {
458 S.tokline = S.line;
459 S.tokcol = S.col;
460 S.tokpos = S.pos;
461 }
462
463 var prev_was_dot = false;
464 var previous_token = null;
465 function token(type, value, is_comment) {
466 S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) ||
467 (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
468 (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
469 (type == "arrow");
470 if (type == "punc" && (value == "." || value == "?.")) {
471 prev_was_dot = true;
472 } else if (!is_comment) {
473 prev_was_dot = false;
474 }
475 var ret = {
476 type : type,
477 value : value,
478 line : S.tokline,
479 col : S.tokcol,
480 pos : S.tokpos,
481 endline : S.line,
482 endcol : S.col,
483 endpos : S.pos,
484 nlb : S.newline_before,
485 file : filename
486 };
487 if (/^(?:num|string|regexp)$/i.test(type)) {
488 ret.raw = $TEXT.substring(ret.pos, ret.endpos);
489 }
490 if (!is_comment) {
491 ret.comments_before = S.comments_before;
492 ret.comments_after = S.comments_before = [];
493 }
494 S.newline_before = false;
495 ret = new AST_Token(ret);
496 if (!is_comment) previous_token = ret;
497 return ret;
498 }
499
500 function skip_whitespace() {
501 while (WHITESPACE_CHARS.has(peek()))
502 next();
503 }
504
505 function read_while(pred) {
506 var ret = "", ch, i = 0;
507 while ((ch = peek()) && pred(ch, i++))
508 ret += next();
509 return ret;
510 }
511
512 function parse_error(err) {
513 js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
514 }
515
516 function read_num(prefix) {
517 var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
518 var num = read_while(function(ch, i) {
519 if (is_big_int) return false;
520
521 var code = ch.charCodeAt(0);
522 switch (code) {
523 case 95: // _
524 return (numeric_separator = true);
525 case 98: case 66: // bB
526 return (has_x = true); // Can occur in hex sequence, don't return false yet
527 case 111: case 79: // oO
528 case 120: case 88: // xX
529 return has_x ? false : (has_x = true);
530 case 101: case 69: // eE
531 return has_x ? true : has_e ? false : (has_e = after_e = true);
532 case 45: // -
533 return after_e || (i == 0 && !prefix);
534 case 43: // +
535 return after_e;
536 case (after_e = false, 46): // .
537 return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
538 }
539
540 if (ch === "n") {
541 is_big_int = true;
542
543 return true;
544 }
545
546 return RE_NUM_LITERAL.test(ch);
547 });
548 if (prefix) num = prefix + num;
549 if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
550 parse_error("Legacy octal literals are not allowed in strict mode");
551 }
552 if (numeric_separator) {
553 if (num.endsWith("_")) {
554 parse_error("Numeric separators are not allowed at the end of numeric literals");
555 } else if (num.includes("__")) {
556 parse_error("Only one underscore is allowed as numeric separator");
557 }
558 num = num.replace(/_/g, "");
559 }
560 if (num.endsWith("n")) {
561 const without_n = num.slice(0, -1);
562 const allow_e = RE_HEX_NUMBER.test(without_n);
563 const valid = parse_js_number(without_n, allow_e);
564 if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid))
565 return token("big_int", without_n);
566 parse_error("Invalid or unexpected token");
567 }
568 var valid = parse_js_number(num);
569 if (!isNaN(valid)) {
570 return token("num", valid);
571 } else {
572 parse_error("Invalid syntax: " + num);
573 }
574 }
575
576 function is_octal(ch) {
577 return ch >= "0" && ch <= "7";
578 }
579
580 function read_escaped_char(in_string, strict_hex, template_string) {
581 var ch = next(true, in_string);
582 switch (ch.charCodeAt(0)) {
583 case 110 : return "\n";
584 case 114 : return "\r";
585 case 116 : return "\t";
586 case 98 : return "\b";
587 case 118 : return "\u000b"; // \v
588 case 102 : return "\f";
589 case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x
590 case 117 : // \u
591 if (peek() == "{") {
592 next(true);
593 if (peek() === "}")
594 parse_error("Expecting hex-character between {}");
595 while (peek() == "0") next(true); // No significance
596 var result, length = find("}", true) - S.pos;
597 // Avoid 32 bit integer overflow (1 << 32 === 1)
598 // We know first character isn't 0 and thus out of range anyway
599 if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) {
600 parse_error("Unicode reference out of bounds");
601 }
602 next(true);
603 return from_char_code(result);
604 }
605 return String.fromCharCode(hex_bytes(4, strict_hex));
606 case 10 : return ""; // newline
607 case 13 : // \r
608 if (peek() == "\n") { // DOS newline
609 next(true, in_string);
610 return "";
611 }
612 }
613 if (is_octal(ch)) {
614 if (template_string && strict_hex) {
615 const represents_null_character = ch === "0" && !is_octal(peek());
616 if (!represents_null_character) {
617 parse_error("Octal escape sequences are not allowed in template strings");
618 }
619 }
620 return read_octal_escape_sequence(ch, strict_hex);
621 }
622 return ch;
623 }
624
625 function read_octal_escape_sequence(ch, strict_octal) {
626 // Read
627 var p = peek();
628 if (p >= "0" && p <= "7") {
629 ch += next(true);
630 if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
631 ch += next(true);
632 }
633
634 // Parse
635 if (ch === "0") return "\0";
636 if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal)
637 parse_error("Legacy octal escape sequences are not allowed in strict mode");
638 return String.fromCharCode(parseInt(ch, 8));
639 }
640
641 function hex_bytes(n, strict_hex) {
642 var num = 0;
643 for (; n > 0; --n) {
644 if (!strict_hex && isNaN(parseInt(peek(), 16))) {
645 return parseInt(num, 16) || "";
646 }
647 var digit = next(true);
648 if (isNaN(parseInt(digit, 16)))
649 parse_error("Invalid hex-character pattern in string");
650 num += digit;
651 }
652 return parseInt(num, 16);
653 }
654
655 var read_string = with_eof_error("Unterminated string constant", function() {
656 var quote = next(), ret = "";
657 for (;;) {
658 var ch = next(true, true);
659 if (ch == "\\") ch = read_escaped_char(true, true);
660 else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
661 else if (ch == quote) break;
662 ret += ch;
663 }
664 var tok = token("string", ret);
665 tok.quote = quote;
666 return tok;
667 });
668
669 var read_template_characters = with_eof_error("Unterminated template", function(begin) {
670 if (begin) {
671 S.template_braces.push(S.brace_counter);
672 }
673 var content = "", raw = "", ch, tok;
674 next(true, true);
675 while ((ch = next(true, true)) != "`") {
676 if (ch == "\r") {
677 if (peek() == "\n") ++S.pos;
678 ch = "\n";
679 } else if (ch == "$" && peek() == "{") {
680 next(true, true);
681 S.brace_counter++;
682 tok = token(begin ? "template_head" : "template_substitution", content);
683 tok.raw = raw;
684 return tok;
685 }
686
687 raw += ch;
688 if (ch == "\\") {
689 var tmp = S.pos;
690 var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]"));
691 ch = read_escaped_char(true, !prev_is_tag, true);
692 raw += S.text.substr(tmp, S.pos - tmp);
693 }
694
695 content += ch;
696 }
697 S.template_braces.pop();
698 tok = token(begin ? "template_head" : "template_substitution", content);
699 tok.raw = raw;
700 tok.end = true;
701 return tok;
702 });
703
704 function skip_line_comment(type) {
705 var regex_allowed = S.regex_allowed;
706 var i = find_eol(), ret;
707 if (i == -1) {
708 ret = S.text.substr(S.pos);
709 S.pos = S.text.length;
710 } else {
711 ret = S.text.substring(S.pos, i);
712 S.pos = i;
713 }
714 S.col = S.tokcol + (S.pos - S.tokpos);
715 S.comments_before.push(token(type, ret, true));
716 S.regex_allowed = regex_allowed;
717 return next_token;
718 }
719
720 var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
721 var regex_allowed = S.regex_allowed;
722 var i = find("*/", true);
723 var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n");
724 // update stream position
725 forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2);
726 S.comments_before.push(token("comment2", text, true));
727 S.newline_before = S.newline_before || text.includes("\n");
728 S.regex_allowed = regex_allowed;
729 return next_token;
730 });
731
732 var read_name = with_eof_error("Unterminated identifier name", function() {
733 var name, ch, escaped = false;
734 var read_escaped_identifier_char = function() {
735 escaped = true;
736 next();
737 if (peek() !== "u") {
738 parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}");
739 }
740 return read_escaped_char(false, true);
741 };
742
743 // Read first character (ID_Start)
744 if ((name = peek()) === "\\") {
745 name = read_escaped_identifier_char();
746 if (!is_identifier_start(name)) {
747 parse_error("First identifier char is an invalid identifier char");
748 }
749 } else if (is_identifier_start(name)) {
750 next();
751 } else {
752 return "";
753 }
754
755 // Read ID_Continue
756 while ((ch = peek()) != null) {
757 if ((ch = peek()) === "\\") {
758 ch = read_escaped_identifier_char();
759 if (!is_identifier_char(ch)) {
760 parse_error("Invalid escaped identifier char");
761 }
762 } else {
763 if (!is_identifier_char(ch)) {
764 break;
765 }
766 next();
767 }
768 name += ch;
769 }
770 if (RESERVED_WORDS.has(name) && escaped) {
771 parse_error("Escaped characters are not allowed in keywords");
772 }
773 return name;
774 });
775
776 var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
777 var prev_backslash = false, ch, in_class = false;
778 while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) {
779 parse_error("Unexpected line terminator");
780 } else if (prev_backslash) {
781 source += "\\" + ch;
782 prev_backslash = false;
783 } else if (ch == "[") {
784 in_class = true;
785 source += ch;
786 } else if (ch == "]" && in_class) {
787 in_class = false;
788 source += ch;
789 } else if (ch == "/" && !in_class) {
790 break;
791 } else if (ch == "\\") {
792 prev_backslash = true;
793 } else {
794 source += ch;
795 }
796 const flags = read_name();
797 return token("regexp", { source, flags });
798 });
799
800 function read_operator(prefix) {
801 function grow(op) {
802 if (!peek()) return op;
803 var bigger = op + peek();
804 if (OPERATORS.has(bigger)) {
805 next();
806 return grow(bigger);
807 } else {
808 return op;
809 }
810 }
811 return token("operator", grow(prefix || next()));
812 }
813
814 function handle_slash() {
815 next();
816 switch (peek()) {
817 case "/":
818 next();
819 return skip_line_comment("comment1");
820 case "*":
821 next();
822 return skip_multiline_comment();
823 }
824 return S.regex_allowed ? read_regexp("") : read_operator("/");
825 }
826
827 function handle_eq_sign() {
828 next();
829 if (peek() === ">") {
830 next();
831 return token("arrow", "=>");
832 } else {
833 return read_operator("=");
834 }
835 }
836
837 function handle_dot() {
838 next();
839 if (is_digit(peek().charCodeAt(0))) {
840 return read_num(".");
841 }
842 if (peek() === ".") {
843 next(); // Consume second dot
844 next(); // Consume third dot
845 return token("expand", "...");
846 }
847
848 return token("punc", ".");
849 }
850
851 function read_word() {
852 var word = read_name();
853 if (prev_was_dot) return token("name", word);
854 return KEYWORDS_ATOM.has(word) ? token("atom", word)
855 : !KEYWORDS.has(word) ? token("name", word)
856 : OPERATORS.has(word) ? token("operator", word)
857 : token("keyword", word);
858 }
859
860 function with_eof_error(eof_error, cont) {
861 return function(x) {
862 try {
863 return cont(x);
864 } catch(ex) {
865 if (ex === EX_EOF) parse_error(eof_error);
866 else throw ex;
867 }
868 };
869 }
870
871 function next_token(force_regexp) {
872 if (force_regexp != null)
873 return read_regexp(force_regexp);
874 if (shebang && S.pos == 0 && looking_at("#!")) {
875 start_token();
876 forward(2);
877 skip_line_comment("comment5");
878 }
879 for (;;) {
880 skip_whitespace();
881 start_token();
882 if (html5_comments) {
883 if (looking_at("<!--")) {
884 forward(4);
885 skip_line_comment("comment3");
886 continue;
887 }
888 if (looking_at("-->") && S.newline_before) {
889 forward(3);
890 skip_line_comment("comment4");
891 continue;
892 }
893 }
894 var ch = peek();
895 if (!ch) return token("eof");
896 var code = ch.charCodeAt(0);
897 switch (code) {
898 case 34: case 39: return read_string();
899 case 46: return handle_dot();
900 case 47: {
901 var tok = handle_slash();
902 if (tok === next_token) continue;
903 return tok;
904 }
905 case 61: return handle_eq_sign();
906 case 63: {
907 if (!is_option_chain_op()) break; // Handled below
908
909 next(); // ?
910 next(); // .
911
912 return token("punc", "?.");
913 }
914 case 96: return read_template_characters(true);
915 case 123:
916 S.brace_counter++;
917 break;
918 case 125:
919 S.brace_counter--;
920 if (S.template_braces.length > 0
921 && S.template_braces[S.template_braces.length - 1] === S.brace_counter)
922 return read_template_characters(false);
923 break;
924 }
925 if (is_digit(code)) return read_num();
926 if (PUNC_CHARS.has(ch)) return token("punc", next());
927 if (OPERATOR_CHARS.has(ch)) return read_operator();
928 if (code == 92 || is_identifier_start(ch)) return read_word();
929 break;
930 }
931 parse_error("Unexpected character '" + ch + "'");
932 }
933
934 next_token.next = next;
935 next_token.peek = peek;
936
937 next_token.context = function(nc) {
938 if (nc) S = nc;
939 return S;
940 };
941
942 next_token.add_directive = function(directive) {
943 S.directive_stack[S.directive_stack.length - 1].push(directive);
944
945 if (S.directives[directive] === undefined) {
946 S.directives[directive] = 1;
947 } else {
948 S.directives[directive]++;
949 }
950 };
951
952 next_token.push_directives_stack = function() {
953 S.directive_stack.push([]);
954 };
955
956 next_token.pop_directives_stack = function() {
957 var directives = S.directive_stack[S.directive_stack.length - 1];
958
959 for (var i = 0; i < directives.length; i++) {
960 S.directives[directives[i]]--;
961 }
962
963 S.directive_stack.pop();
964 };
965
966 next_token.has_directive = function(directive) {
967 return S.directives[directive] > 0;
968 };
969
970 return next_token;
971
972}
973
974/* -----[ Parser (constants) ]----- */
975
976var UNARY_PREFIX = makePredicate([
977 "typeof",
978 "void",
979 "delete",
980 "--",
981 "++",
982 "!",
983 "~",
984 "-",
985 "+"
986]);
987
988var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
989
990var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
991
992var PRECEDENCE = (function(a, ret) {
993 for (var i = 0; i < a.length; ++i) {
994 var b = a[i];
995 for (var j = 0; j < b.length; ++j) {
996 ret[b[j]] = i + 1;
997 }
998 }
999 return ret;
1000})(
1001 [
1002 ["||"],
1003 ["??"],
1004 ["&&"],
1005 ["|"],
1006 ["^"],
1007 ["&"],
1008 ["==", "===", "!=", "!=="],
1009 ["<", ">", "<=", ">=", "in", "instanceof"],
1010 [">>", "<<", ">>>"],
1011 ["+", "-"],
1012 ["*", "/", "%"],
1013 ["**"]
1014 ],
1015 {}
1016);
1017
1018var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name" ]);
1019
1020/* -----[ Parser ]----- */
1021
1022function parse($TEXT, options) {
1023 // maps start tokens to count of comments found outside of their parens
1024 // Example: /* I count */ ( /* I don't */ foo() )
1025 // Useful because comments_before property of call with parens outside
1026 // contains both comments inside and outside these parens. Used to find the
1027 // right #__PURE__ comments for an expression
1028 const outer_comments_before_counts = new Map();
1029
1030 options = defaults(options, {
1031 bare_returns : false,
1032 ecma : null, // Legacy
1033 expression : false,
1034 filename : null,
1035 html5_comments : true,
1036 module : false,
1037 shebang : true,
1038 strict : false,
1039 toplevel : null,
1040 }, true);
1041
1042 var S = {
1043 input : (typeof $TEXT == "string"
1044 ? tokenizer($TEXT, options.filename,
1045 options.html5_comments, options.shebang)
1046 : $TEXT),
1047 token : null,
1048 prev : null,
1049 peeked : null,
1050 in_function : 0,
1051 in_async : -1,
1052 in_generator : -1,
1053 in_directives : true,
1054 in_loop : 0,
1055 labels : []
1056 };
1057
1058 S.token = next();
1059
1060 function is(type, value) {
1061 return is_token(S.token, type, value);
1062 }
1063
1064 function peek() { return S.peeked || (S.peeked = S.input()); }
1065
1066 function next() {
1067 S.prev = S.token;
1068
1069 if (!S.peeked) peek();
1070 S.token = S.peeked;
1071 S.peeked = null;
1072 S.in_directives = S.in_directives && (
1073 S.token.type == "string" || is("punc", ";")
1074 );
1075 return S.token;
1076 }
1077
1078 function prev() {
1079 return S.prev;
1080 }
1081
1082 function croak(msg, line, col, pos) {
1083 var ctx = S.input.context();
1084 js_error(msg,
1085 ctx.filename,
1086 line != null ? line : ctx.tokline,
1087 col != null ? col : ctx.tokcol,
1088 pos != null ? pos : ctx.tokpos);
1089 }
1090
1091 function token_error(token, msg) {
1092 croak(msg, token.line, token.col);
1093 }
1094
1095 function unexpected(token) {
1096 if (token == null)
1097 token = S.token;
1098 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1099 }
1100
1101 function expect_token(type, val) {
1102 if (is(type, val)) {
1103 return next();
1104 }
1105 token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
1106 }
1107
1108 function expect(punc) { return expect_token("punc", punc); }
1109
1110 function has_newline_before(token) {
1111 return token.nlb || !token.comments_before.every((comment) => !comment.nlb);
1112 }
1113
1114 function can_insert_semicolon() {
1115 return !options.strict
1116 && (is("eof") || is("punc", "}") || has_newline_before(S.token));
1117 }
1118
1119 function is_in_generator() {
1120 return S.in_generator === S.in_function;
1121 }
1122
1123 function is_in_async() {
1124 return S.in_async === S.in_function;
1125 }
1126
1127 function semicolon(optional) {
1128 if (is("punc", ";")) next();
1129 else if (!optional && !can_insert_semicolon()) unexpected();
1130 }
1131
1132 function parenthesised() {
1133 expect("(");
1134 var exp = expression(true);
1135 expect(")");
1136 return exp;
1137 }
1138
1139 function embed_tokens(parser) {
1140 return function _embed_tokens_wrapper(...args) {
1141 const start = S.token;
1142 const expr = parser(...args);
1143 expr.start = start;
1144 expr.end = prev();
1145 return expr;
1146 };
1147 }
1148
1149 function handle_regexp() {
1150 if (is("operator", "/") || is("operator", "/=")) {
1151 S.peeked = null;
1152 S.token = S.input(S.token.value.substr(1)); // force regexp
1153 }
1154 }
1155
1156 var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
1157 handle_regexp();
1158 switch (S.token.type) {
1159 case "string":
1160 if (S.in_directives) {
1161 var token = peek();
1162 if (!S.token.raw.includes("\\")
1163 && (is_token(token, "punc", ";")
1164 || is_token(token, "punc", "}")
1165 || has_newline_before(token)
1166 || is_token(token, "eof"))) {
1167 S.input.add_directive(S.token.value);
1168 } else {
1169 S.in_directives = false;
1170 }
1171 }
1172 var dir = S.in_directives, stat = simple_statement();
1173 return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat;
1174 case "template_head":
1175 case "num":
1176 case "big_int":
1177 case "regexp":
1178 case "operator":
1179 case "atom":
1180 return simple_statement();
1181
1182 case "name":
1183 if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
1184 next();
1185 next();
1186 if (is_for_body) {
1187 croak("functions are not allowed as the body of a loop");
1188 }
1189 return function_(AST_Defun, false, true, is_export_default);
1190 }
1191 if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
1192 next();
1193 var node = import_();
1194 semicolon();
1195 return node;
1196 }
1197 return is_token(peek(), "punc", ":")
1198 ? labeled_statement()
1199 : simple_statement();
1200
1201 case "punc":
1202 switch (S.token.value) {
1203 case "{":
1204 return new AST_BlockStatement({
1205 start : S.token,
1206 body : block_(),
1207 end : prev()
1208 });
1209 case "[":
1210 case "(":
1211 return simple_statement();
1212 case ";":
1213 S.in_directives = false;
1214 next();
1215 return new AST_EmptyStatement();
1216 default:
1217 unexpected();
1218 }
1219
1220 case "keyword":
1221 switch (S.token.value) {
1222 case "break":
1223 next();
1224 return break_cont(AST_Break);
1225
1226 case "continue":
1227 next();
1228 return break_cont(AST_Continue);
1229
1230 case "debugger":
1231 next();
1232 semicolon();
1233 return new AST_Debugger();
1234
1235 case "do":
1236 next();
1237 var body = in_loop(statement);
1238 expect_token("keyword", "while");
1239 var condition = parenthesised();
1240 semicolon(true);
1241 return new AST_Do({
1242 body : body,
1243 condition : condition
1244 });
1245
1246 case "while":
1247 next();
1248 return new AST_While({
1249 condition : parenthesised(),
1250 body : in_loop(function() { return statement(false, true); })
1251 });
1252
1253 case "for":
1254 next();
1255 return for_();
1256
1257 case "class":
1258 next();
1259 if (is_for_body) {
1260 croak("classes are not allowed as the body of a loop");
1261 }
1262 if (is_if_body) {
1263 croak("classes are not allowed as the body of an if");
1264 }
1265 return class_(AST_DefClass);
1266
1267 case "function":
1268 next();
1269 if (is_for_body) {
1270 croak("functions are not allowed as the body of a loop");
1271 }
1272 return function_(AST_Defun, false, false, is_export_default);
1273
1274 case "if":
1275 next();
1276 return if_();
1277
1278 case "return":
1279 if (S.in_function == 0 && !options.bare_returns)
1280 croak("'return' outside of function");
1281 next();
1282 var value = null;
1283 if (is("punc", ";")) {
1284 next();
1285 } else if (!can_insert_semicolon()) {
1286 value = expression(true);
1287 semicolon();
1288 }
1289 return new AST_Return({
1290 value: value
1291 });
1292
1293 case "switch":
1294 next();
1295 return new AST_Switch({
1296 expression : parenthesised(),
1297 body : in_loop(switch_body_)
1298 });
1299
1300 case "throw":
1301 next();
1302 if (has_newline_before(S.token))
1303 croak("Illegal newline after 'throw'");
1304 var value = expression(true);
1305 semicolon();
1306 return new AST_Throw({
1307 value: value
1308 });
1309
1310 case "try":
1311 next();
1312 return try_();
1313
1314 case "var":
1315 next();
1316 var node = var_();
1317 semicolon();
1318 return node;
1319
1320 case "let":
1321 next();
1322 var node = let_();
1323 semicolon();
1324 return node;
1325
1326 case "const":
1327 next();
1328 var node = const_();
1329 semicolon();
1330 return node;
1331
1332 case "with":
1333 if (S.input.has_directive("use strict")) {
1334 croak("Strict mode may not include a with statement");
1335 }
1336 next();
1337 return new AST_With({
1338 expression : parenthesised(),
1339 body : statement()
1340 });
1341
1342 case "export":
1343 if (!is_token(peek(), "punc", "(")) {
1344 next();
1345 var node = export_();
1346 if (is("punc", ";")) semicolon();
1347 return node;
1348 }
1349 }
1350 }
1351 unexpected();
1352 });
1353
1354 function labeled_statement() {
1355 var label = as_symbol(AST_Label);
1356 if (label.name === "await" && is_in_async()) {
1357 token_error(S.prev, "await cannot be used as label inside async function");
1358 }
1359 if (S.labels.some((l) => l.name === label.name)) {
1360 // ECMA-262, 12.12: An ECMAScript program is considered
1361 // syntactically incorrect if it contains a
1362 // LabelledStatement that is enclosed by a
1363 // LabelledStatement with the same Identifier as label.
1364 croak("Label " + label.name + " defined twice");
1365 }
1366 expect(":");
1367 S.labels.push(label);
1368 var stat = statement();
1369 S.labels.pop();
1370 if (!(stat instanceof AST_IterationStatement)) {
1371 // check for `continue` that refers to this label.
1372 // those should be reported as syntax errors.
1373 // https://github.com/mishoo/UglifyJS2/issues/287
1374 label.references.forEach(function(ref) {
1375 if (ref instanceof AST_Continue) {
1376 ref = ref.label.start;
1377 croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
1378 ref.line, ref.col, ref.pos);
1379 }
1380 });
1381 }
1382 return new AST_LabeledStatement({ body: stat, label: label });
1383 }
1384
1385 function simple_statement(tmp) {
1386 return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
1387 }
1388
1389 function break_cont(type) {
1390 var label = null, ldef;
1391 if (!can_insert_semicolon()) {
1392 label = as_symbol(AST_LabelRef, true);
1393 }
1394 if (label != null) {
1395 ldef = S.labels.find((l) => l.name === label.name);
1396 if (!ldef)
1397 croak("Undefined label " + label.name);
1398 label.thedef = ldef;
1399 } else if (S.in_loop == 0)
1400 croak(type.TYPE + " not inside a loop or switch");
1401 semicolon();
1402 var stat = new type({ label: label });
1403 if (ldef) ldef.references.push(stat);
1404 return stat;
1405 }
1406
1407 function for_() {
1408 var for_await_error = "`for await` invalid in this context";
1409 var await_tok = S.token;
1410 if (await_tok.type == "name" && await_tok.value == "await") {
1411 if (!is_in_async()) {
1412 token_error(await_tok, for_await_error);
1413 }
1414 next();
1415 } else {
1416 await_tok = false;
1417 }
1418 expect("(");
1419 var init = null;
1420 if (!is("punc", ";")) {
1421 init =
1422 is("keyword", "var") ? (next(), var_(true)) :
1423 is("keyword", "let") ? (next(), let_(true)) :
1424 is("keyword", "const") ? (next(), const_(true)) :
1425 expression(true, true);
1426 var is_in = is("operator", "in");
1427 var is_of = is("name", "of");
1428 if (await_tok && !is_of) {
1429 token_error(await_tok, for_await_error);
1430 }
1431 if (is_in || is_of) {
1432 if (init instanceof AST_Definitions) {
1433 if (init.definitions.length > 1)
1434 token_error(init.start, "Only one variable declaration allowed in for..in loop");
1435 } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
1436 token_error(init.start, "Invalid left-hand side in for..in loop");
1437 }
1438 next();
1439 if (is_in) {
1440 return for_in(init);
1441 } else {
1442 return for_of(init, !!await_tok);
1443 }
1444 }
1445 } else if (await_tok) {
1446 token_error(await_tok, for_await_error);
1447 }
1448 return regular_for(init);
1449 }
1450
1451 function regular_for(init) {
1452 expect(";");
1453 var test = is("punc", ";") ? null : expression(true);
1454 expect(";");
1455 var step = is("punc", ")") ? null : expression(true);
1456 expect(")");
1457 return new AST_For({
1458 init : init,
1459 condition : test,
1460 step : step,
1461 body : in_loop(function() { return statement(false, true); })
1462 });
1463 }
1464
1465 function for_of(init, is_await) {
1466 var lhs = init instanceof AST_Definitions ? init.definitions[0].name : null;
1467 var obj = expression(true);
1468 expect(")");
1469 return new AST_ForOf({
1470 await : is_await,
1471 init : init,
1472 name : lhs,
1473 object : obj,
1474 body : in_loop(function() { return statement(false, true); })
1475 });
1476 }
1477
1478 function for_in(init) {
1479 var obj = expression(true);
1480 expect(")");
1481 return new AST_ForIn({
1482 init : init,
1483 object : obj,
1484 body : in_loop(function() { return statement(false, true); })
1485 });
1486 }
1487
1488 var arrow_function = function(start, argnames, is_async) {
1489 if (has_newline_before(S.token)) {
1490 croak("Unexpected newline before arrow (=>)");
1491 }
1492
1493 expect_token("arrow", "=>");
1494
1495 var body = _function_body(is("punc", "{"), false, is_async);
1496
1497 var end =
1498 body instanceof Array && body.length ? body[body.length - 1].end :
1499 body instanceof Array ? start :
1500 body.end;
1501
1502 return new AST_Arrow({
1503 start : start,
1504 end : end,
1505 async : is_async,
1506 argnames : argnames,
1507 body : body
1508 });
1509 };
1510
1511 var function_ = function(ctor, is_generator_property, is_async, is_export_default) {
1512 var in_statement = ctor === AST_Defun;
1513 var is_generator = is("operator", "*");
1514 if (is_generator) {
1515 next();
1516 }
1517
1518 var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
1519 if (in_statement && !name) {
1520 if (is_export_default) {
1521 ctor = AST_Function;
1522 } else {
1523 unexpected();
1524 }
1525 }
1526
1527 if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
1528 unexpected(prev());
1529
1530 var args = [];
1531 var body = _function_body(true, is_generator || is_generator_property, is_async, name, args);
1532 return new ctor({
1533 start : args.start,
1534 end : body.end,
1535 is_generator: is_generator,
1536 async : is_async,
1537 name : name,
1538 argnames: args,
1539 body : body
1540 });
1541 };
1542
1543 function track_used_binding_identifiers(is_parameter, strict) {
1544 var parameters = new Set();
1545 var duplicate = false;
1546 var default_assignment = false;
1547 var spread = false;
1548 var strict_mode = !!strict;
1549 var tracker = {
1550 add_parameter: function(token) {
1551 if (parameters.has(token.value)) {
1552 if (duplicate === false) {
1553 duplicate = token;
1554 }
1555 tracker.check_strict();
1556 } else {
1557 parameters.add(token.value);
1558 if (is_parameter) {
1559 switch (token.value) {
1560 case "arguments":
1561 case "eval":
1562 case "yield":
1563 if (strict_mode) {
1564 token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode");
1565 }
1566 break;
1567 default:
1568 if (RESERVED_WORDS.has(token.value)) {
1569 unexpected();
1570 }
1571 }
1572 }
1573 }
1574 },
1575 mark_default_assignment: function(token) {
1576 if (default_assignment === false) {
1577 default_assignment = token;
1578 }
1579 },
1580 mark_spread: function(token) {
1581 if (spread === false) {
1582 spread = token;
1583 }
1584 },
1585 mark_strict_mode: function() {
1586 strict_mode = true;
1587 },
1588 is_strict: function() {
1589 return default_assignment !== false || spread !== false || strict_mode;
1590 },
1591 check_strict: function() {
1592 if (tracker.is_strict() && duplicate !== false) {
1593 token_error(duplicate, "Parameter " + duplicate.value + " was used already");
1594 }
1595 }
1596 };
1597
1598 return tracker;
1599 }
1600
1601 function parameters(params) {
1602 var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
1603
1604 expect("(");
1605
1606 while (!is("punc", ")")) {
1607 var param = parameter(used_parameters);
1608 params.push(param);
1609
1610 if (!is("punc", ")")) {
1611 expect(",");
1612 }
1613
1614 if (param instanceof AST_Expansion) {
1615 break;
1616 }
1617 }
1618
1619 next();
1620 }
1621
1622 function parameter(used_parameters, symbol_type) {
1623 var param;
1624 var expand = false;
1625 if (used_parameters === undefined) {
1626 used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
1627 }
1628 if (is("expand", "...")) {
1629 expand = S.token;
1630 used_parameters.mark_spread(S.token);
1631 next();
1632 }
1633 param = binding_element(used_parameters, symbol_type);
1634
1635 if (is("operator", "=") && expand === false) {
1636 used_parameters.mark_default_assignment(S.token);
1637 next();
1638 param = new AST_DefaultAssign({
1639 start: param.start,
1640 left: param,
1641 operator: "=",
1642 right: expression(false),
1643 end: S.token
1644 });
1645 }
1646
1647 if (expand !== false) {
1648 if (!is("punc", ")")) {
1649 unexpected();
1650 }
1651 param = new AST_Expansion({
1652 start: expand,
1653 expression: param,
1654 end: expand
1655 });
1656 }
1657 used_parameters.check_strict();
1658
1659 return param;
1660 }
1661
1662 function binding_element(used_parameters, symbol_type) {
1663 var elements = [];
1664 var first = true;
1665 var is_expand = false;
1666 var expand_token;
1667 var first_token = S.token;
1668 if (used_parameters === undefined) {
1669 used_parameters = track_used_binding_identifiers(false, S.input.has_directive("use strict"));
1670 }
1671 symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type;
1672 if (is("punc", "[")) {
1673 next();
1674 while (!is("punc", "]")) {
1675 if (first) {
1676 first = false;
1677 } else {
1678 expect(",");
1679 }
1680
1681 if (is("expand", "...")) {
1682 is_expand = true;
1683 expand_token = S.token;
1684 used_parameters.mark_spread(S.token);
1685 next();
1686 }
1687 if (is("punc")) {
1688 switch (S.token.value) {
1689 case ",":
1690 elements.push(new AST_Hole({
1691 start: S.token,
1692 end: S.token
1693 }));
1694 continue;
1695 case "]": // Trailing comma after last element
1696 break;
1697 case "[":
1698 case "{":
1699 elements.push(binding_element(used_parameters, symbol_type));
1700 break;
1701 default:
1702 unexpected();
1703 }
1704 } else if (is("name")) {
1705 used_parameters.add_parameter(S.token);
1706 elements.push(as_symbol(symbol_type));
1707 } else {
1708 croak("Invalid function parameter");
1709 }
1710 if (is("operator", "=") && is_expand === false) {
1711 used_parameters.mark_default_assignment(S.token);
1712 next();
1713 elements[elements.length - 1] = new AST_DefaultAssign({
1714 start: elements[elements.length - 1].start,
1715 left: elements[elements.length - 1],
1716 operator: "=",
1717 right: expression(false),
1718 end: S.token
1719 });
1720 }
1721 if (is_expand) {
1722 if (!is("punc", "]")) {
1723 croak("Rest element must be last element");
1724 }
1725 elements[elements.length - 1] = new AST_Expansion({
1726 start: expand_token,
1727 expression: elements[elements.length - 1],
1728 end: expand_token
1729 });
1730 }
1731 }
1732 expect("]");
1733 used_parameters.check_strict();
1734 return new AST_Destructuring({
1735 start: first_token,
1736 names: elements,
1737 is_array: true,
1738 end: prev()
1739 });
1740 } else if (is("punc", "{")) {
1741 next();
1742 while (!is("punc", "}")) {
1743 if (first) {
1744 first = false;
1745 } else {
1746 expect(",");
1747 }
1748 if (is("expand", "...")) {
1749 is_expand = true;
1750 expand_token = S.token;
1751 used_parameters.mark_spread(S.token);
1752 next();
1753 }
1754 if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) {
1755 used_parameters.add_parameter(S.token);
1756 var start = prev();
1757 var value = as_symbol(symbol_type);
1758 if (is_expand) {
1759 elements.push(new AST_Expansion({
1760 start: expand_token,
1761 expression: value,
1762 end: value.end,
1763 }));
1764 } else {
1765 elements.push(new AST_ObjectKeyVal({
1766 start: start,
1767 key: value.name,
1768 value: value,
1769 end: value.end,
1770 }));
1771 }
1772 } else if (is("punc", "}")) {
1773 continue; // Allow trailing hole
1774 } else {
1775 var property_token = S.token;
1776 var property = as_property_name();
1777 if (property === null) {
1778 unexpected(prev());
1779 } else if (prev().type === "name" && !is("punc", ":")) {
1780 elements.push(new AST_ObjectKeyVal({
1781 start: prev(),
1782 key: property,
1783 value: new symbol_type({
1784 start: prev(),
1785 name: property,
1786 end: prev()
1787 }),
1788 end: prev()
1789 }));
1790 } else {
1791 expect(":");
1792 elements.push(new AST_ObjectKeyVal({
1793 start: property_token,
1794 quote: property_token.quote,
1795 key: property,
1796 value: binding_element(used_parameters, symbol_type),
1797 end: prev()
1798 }));
1799 }
1800 }
1801 if (is_expand) {
1802 if (!is("punc", "}")) {
1803 croak("Rest element must be last element");
1804 }
1805 } else if (is("operator", "=")) {
1806 used_parameters.mark_default_assignment(S.token);
1807 next();
1808 elements[elements.length - 1].value = new AST_DefaultAssign({
1809 start: elements[elements.length - 1].value.start,
1810 left: elements[elements.length - 1].value,
1811 operator: "=",
1812 right: expression(false),
1813 end: S.token
1814 });
1815 }
1816 }
1817 expect("}");
1818 used_parameters.check_strict();
1819 return new AST_Destructuring({
1820 start: first_token,
1821 names: elements,
1822 is_array: false,
1823 end: prev()
1824 });
1825 } else if (is("name")) {
1826 used_parameters.add_parameter(S.token);
1827 return as_symbol(symbol_type);
1828 } else {
1829 croak("Invalid function parameter");
1830 }
1831 }
1832
1833 function params_or_seq_(allow_arrows, maybe_sequence) {
1834 var spread_token;
1835 var invalid_sequence;
1836 var trailing_comma;
1837 var a = [];
1838 expect("(");
1839 while (!is("punc", ")")) {
1840 if (spread_token) unexpected(spread_token);
1841 if (is("expand", "...")) {
1842 spread_token = S.token;
1843 if (maybe_sequence) invalid_sequence = S.token;
1844 next();
1845 a.push(new AST_Expansion({
1846 start: prev(),
1847 expression: expression(),
1848 end: S.token,
1849 }));
1850 } else {
1851 a.push(expression());
1852 }
1853 if (!is("punc", ")")) {
1854 expect(",");
1855 if (is("punc", ")")) {
1856 trailing_comma = prev();
1857 if (maybe_sequence) invalid_sequence = trailing_comma;
1858 }
1859 }
1860 }
1861 expect(")");
1862 if (allow_arrows && is("arrow", "=>")) {
1863 if (spread_token && trailing_comma) unexpected(trailing_comma);
1864 } else if (invalid_sequence) {
1865 unexpected(invalid_sequence);
1866 }
1867 return a;
1868 }
1869
1870 function _function_body(block, generator, is_async, name, args) {
1871 var loop = S.in_loop;
1872 var labels = S.labels;
1873 var current_generator = S.in_generator;
1874 var current_async = S.in_async;
1875 ++S.in_function;
1876 if (generator)
1877 S.in_generator = S.in_function;
1878 if (is_async)
1879 S.in_async = S.in_function;
1880 if (args) parameters(args);
1881 if (block)
1882 S.in_directives = true;
1883 S.in_loop = 0;
1884 S.labels = [];
1885 if (block) {
1886 S.input.push_directives_stack();
1887 var a = block_();
1888 if (name) _verify_symbol(name);
1889 if (args) args.forEach(_verify_symbol);
1890 S.input.pop_directives_stack();
1891 } else {
1892 var a = [new AST_Return({
1893 start: S.token,
1894 value: expression(false),
1895 end: S.token
1896 })];
1897 }
1898 --S.in_function;
1899 S.in_loop = loop;
1900 S.labels = labels;
1901 S.in_generator = current_generator;
1902 S.in_async = current_async;
1903 return a;
1904 }
1905
1906 function _await_expression() {
1907 // Previous token must be "await" and not be interpreted as an identifier
1908 if (!is_in_async()) {
1909 croak("Unexpected await expression outside async function",
1910 S.prev.line, S.prev.col, S.prev.pos);
1911 }
1912 // the await expression is parsed as a unary expression in Babel
1913 return new AST_Await({
1914 start: prev(),
1915 end: S.token,
1916 expression : maybe_unary(true),
1917 });
1918 }
1919
1920 function _yield_expression() {
1921 // Previous token must be keyword yield and not be interpret as an identifier
1922 if (!is_in_generator()) {
1923 croak("Unexpected yield expression outside generator function",
1924 S.prev.line, S.prev.col, S.prev.pos);
1925 }
1926 var start = S.token;
1927 var star = false;
1928 var has_expression = true;
1929
1930 // Attempt to get expression or star (and then the mandatory expression)
1931 // behind yield on the same line.
1932 //
1933 // If nothing follows on the same line of the yieldExpression,
1934 // it should default to the value `undefined` for yield to return.
1935 // In that case, the `undefined` stored as `null` in ast.
1936 //
1937 // Note 1: It isn't allowed for yield* to close without an expression
1938 // Note 2: If there is a nlb between yield and star, it is interpret as
1939 // yield <explicit undefined> <inserted automatic semicolon> *
1940 if (can_insert_semicolon() ||
1941 (is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value))) {
1942 has_expression = false;
1943
1944 } else if (is("operator", "*")) {
1945 star = true;
1946 next();
1947 }
1948
1949 return new AST_Yield({
1950 start : start,
1951 is_star : star,
1952 expression : has_expression ? expression() : null,
1953 end : prev()
1954 });
1955 }
1956
1957 function if_() {
1958 var cond = parenthesised(), body = statement(false, false, true), belse = null;
1959 if (is("keyword", "else")) {
1960 next();
1961 belse = statement(false, false, true);
1962 }
1963 return new AST_If({
1964 condition : cond,
1965 body : body,
1966 alternative : belse
1967 });
1968 }
1969
1970 function block_() {
1971 expect("{");
1972 var a = [];
1973 while (!is("punc", "}")) {
1974 if (is("eof")) unexpected();
1975 a.push(statement());
1976 }
1977 next();
1978 return a;
1979 }
1980
1981 function switch_body_() {
1982 expect("{");
1983 var a = [], cur = null, branch = null, tmp;
1984 while (!is("punc", "}")) {
1985 if (is("eof")) unexpected();
1986 if (is("keyword", "case")) {
1987 if (branch) branch.end = prev();
1988 cur = [];
1989 branch = new AST_Case({
1990 start : (tmp = S.token, next(), tmp),
1991 expression : expression(true),
1992 body : cur
1993 });
1994 a.push(branch);
1995 expect(":");
1996 } else if (is("keyword", "default")) {
1997 if (branch) branch.end = prev();
1998 cur = [];
1999 branch = new AST_Default({
2000 start : (tmp = S.token, next(), expect(":"), tmp),
2001 body : cur
2002 });
2003 a.push(branch);
2004 } else {
2005 if (!cur) unexpected();
2006 cur.push(statement());
2007 }
2008 }
2009 if (branch) branch.end = prev();
2010 next();
2011 return a;
2012 }
2013
2014 function try_() {
2015 var body = block_(), bcatch = null, bfinally = null;
2016 if (is("keyword", "catch")) {
2017 var start = S.token;
2018 next();
2019 if (is("punc", "{")) {
2020 var name = null;
2021 } else {
2022 expect("(");
2023 var name = parameter(undefined, AST_SymbolCatch);
2024 expect(")");
2025 }
2026 bcatch = new AST_Catch({
2027 start : start,
2028 argname : name,
2029 body : block_(),
2030 end : prev()
2031 });
2032 }
2033 if (is("keyword", "finally")) {
2034 var start = S.token;
2035 next();
2036 bfinally = new AST_Finally({
2037 start : start,
2038 body : block_(),
2039 end : prev()
2040 });
2041 }
2042 if (!bcatch && !bfinally)
2043 croak("Missing catch/finally blocks");
2044 return new AST_Try({
2045 body : body,
2046 bcatch : bcatch,
2047 bfinally : bfinally
2048 });
2049 }
2050
2051 function vardefs(no_in, kind) {
2052 var a = [];
2053 var def;
2054 for (;;) {
2055 var sym_type =
2056 kind === "var" ? AST_SymbolVar :
2057 kind === "const" ? AST_SymbolConst :
2058 kind === "let" ? AST_SymbolLet : null;
2059 if (is("punc", "{") || is("punc", "[")) {
2060 def = new AST_VarDef({
2061 start: S.token,
2062 name: binding_element(undefined ,sym_type),
2063 value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
2064 end: prev()
2065 });
2066 } else {
2067 def = new AST_VarDef({
2068 start : S.token,
2069 name : as_symbol(sym_type),
2070 value : is("operator", "=")
2071 ? (next(), expression(false, no_in))
2072 : !no_in && kind === "const"
2073 ? croak("Missing initializer in const declaration") : null,
2074 end : prev()
2075 });
2076 if (def.name.name == "import") croak("Unexpected token: import");
2077 }
2078 a.push(def);
2079 if (!is("punc", ","))
2080 break;
2081 next();
2082 }
2083 return a;
2084 }
2085
2086 var var_ = function(no_in) {
2087 return new AST_Var({
2088 start : prev(),
2089 definitions : vardefs(no_in, "var"),
2090 end : prev()
2091 });
2092 };
2093
2094 var let_ = function(no_in) {
2095 return new AST_Let({
2096 start : prev(),
2097 definitions : vardefs(no_in, "let"),
2098 end : prev()
2099 });
2100 };
2101
2102 var const_ = function(no_in) {
2103 return new AST_Const({
2104 start : prev(),
2105 definitions : vardefs(no_in, "const"),
2106 end : prev()
2107 });
2108 };
2109
2110 var new_ = function(allow_calls) {
2111 var start = S.token;
2112 expect_token("operator", "new");
2113 if (is("punc", ".")) {
2114 next();
2115 expect_token("name", "target");
2116 return subscripts(new AST_NewTarget({
2117 start : start,
2118 end : prev()
2119 }), allow_calls);
2120 }
2121 var newexp = expr_atom(false), args;
2122 if (is("punc", "(")) {
2123 next();
2124 args = expr_list(")", true);
2125 } else {
2126 args = [];
2127 }
2128 var call = new AST_New({
2129 start : start,
2130 expression : newexp,
2131 args : args,
2132 end : prev()
2133 });
2134 annotate(call);
2135 return subscripts(call, allow_calls);
2136 };
2137
2138 function as_atom_node() {
2139 var tok = S.token, ret;
2140 switch (tok.type) {
2141 case "name":
2142 ret = _make_symbol(AST_SymbolRef);
2143 break;
2144 case "num":
2145 ret = new AST_Number({ start: tok, end: tok, value: tok.value });
2146 break;
2147 case "big_int":
2148 ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
2149 break;
2150 case "string":
2151 ret = new AST_String({
2152 start : tok,
2153 end : tok,
2154 value : tok.value,
2155 quote : tok.quote
2156 });
2157 break;
2158 case "regexp":
2159 ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
2160 break;
2161 case "atom":
2162 switch (tok.value) {
2163 case "false":
2164 ret = new AST_False({ start: tok, end: tok });
2165 break;
2166 case "true":
2167 ret = new AST_True({ start: tok, end: tok });
2168 break;
2169 case "null":
2170 ret = new AST_Null({ start: tok, end: tok });
2171 break;
2172 }
2173 break;
2174 }
2175 next();
2176 return ret;
2177 }
2178
2179 function to_fun_args(ex, default_seen_above) {
2180 var insert_default = function(ex, default_value) {
2181 if (default_value) {
2182 return new AST_DefaultAssign({
2183 start: ex.start,
2184 left: ex,
2185 operator: "=",
2186 right: default_value,
2187 end: default_value.end
2188 });
2189 }
2190 return ex;
2191 };
2192 if (ex instanceof AST_Object) {
2193 return insert_default(new AST_Destructuring({
2194 start: ex.start,
2195 end: ex.end,
2196 is_array: false,
2197 names: ex.properties.map(prop => to_fun_args(prop))
2198 }), default_seen_above);
2199 } else if (ex instanceof AST_ObjectKeyVal) {
2200 ex.value = to_fun_args(ex.value);
2201 return insert_default(ex, default_seen_above);
2202 } else if (ex instanceof AST_Hole) {
2203 return ex;
2204 } else if (ex instanceof AST_Destructuring) {
2205 ex.names = ex.names.map(name => to_fun_args(name));
2206 return insert_default(ex, default_seen_above);
2207 } else if (ex instanceof AST_SymbolRef) {
2208 return insert_default(new AST_SymbolFunarg({
2209 name: ex.name,
2210 start: ex.start,
2211 end: ex.end
2212 }), default_seen_above);
2213 } else if (ex instanceof AST_Expansion) {
2214 ex.expression = to_fun_args(ex.expression);
2215 return insert_default(ex, default_seen_above);
2216 } else if (ex instanceof AST_Array) {
2217 return insert_default(new AST_Destructuring({
2218 start: ex.start,
2219 end: ex.end,
2220 is_array: true,
2221 names: ex.elements.map(elm => to_fun_args(elm))
2222 }), default_seen_above);
2223 } else if (ex instanceof AST_Assign) {
2224 return insert_default(to_fun_args(ex.left, ex.right), default_seen_above);
2225 } else if (ex instanceof AST_DefaultAssign) {
2226 ex.left = to_fun_args(ex.left);
2227 return ex;
2228 } else {
2229 croak("Invalid function parameter", ex.start.line, ex.start.col);
2230 }
2231 }
2232
2233 var expr_atom = function(allow_calls, allow_arrows) {
2234 if (is("operator", "new")) {
2235 return new_(allow_calls);
2236 }
2237 if (is("operator", "import")) {
2238 return import_meta();
2239 }
2240 var start = S.token;
2241 var peeked;
2242 var async = is("name", "async")
2243 && (peeked = peek()).value != "["
2244 && peeked.type != "arrow"
2245 && as_atom_node();
2246 if (is("punc")) {
2247 switch (S.token.value) {
2248 case "(":
2249 if (async && !allow_calls) break;
2250 var exprs = params_or_seq_(allow_arrows, !async);
2251 if (allow_arrows && is("arrow", "=>")) {
2252 return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async);
2253 }
2254 var ex = async ? new AST_Call({
2255 expression: async,
2256 args: exprs
2257 }) : exprs.length == 1 ? exprs[0] : new AST_Sequence({
2258 expressions: exprs
2259 });
2260 if (ex.start) {
2261 const outer_comments_before = start.comments_before.length;
2262 outer_comments_before_counts.set(start, outer_comments_before);
2263 ex.start.comments_before.unshift(...start.comments_before);
2264 start.comments_before = ex.start.comments_before;
2265 if (outer_comments_before == 0 && start.comments_before.length > 0) {
2266 var comment = start.comments_before[0];
2267 if (!comment.nlb) {
2268 comment.nlb = start.nlb;
2269 start.nlb = false;
2270 }
2271 }
2272 start.comments_after = ex.start.comments_after;
2273 }
2274 ex.start = start;
2275 var end = prev();
2276 if (ex.end) {
2277 end.comments_before = ex.end.comments_before;
2278 ex.end.comments_after.push(...end.comments_after);
2279 end.comments_after = ex.end.comments_after;
2280 }
2281 ex.end = end;
2282 if (ex instanceof AST_Call) annotate(ex);
2283 return subscripts(ex, allow_calls);
2284 case "[":
2285 return subscripts(array_(), allow_calls);
2286 case "{":
2287 return subscripts(object_or_destructuring_(), allow_calls);
2288 }
2289 if (!async) unexpected();
2290 }
2291 if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
2292 var param = new AST_SymbolFunarg({
2293 name: S.token.value,
2294 start: start,
2295 end: start,
2296 });
2297 next();
2298 return arrow_function(start, [param], !!async);
2299 }
2300 if (is("keyword", "function")) {
2301 next();
2302 var func = function_(AST_Function, false, !!async);
2303 func.start = start;
2304 func.end = prev();
2305 return subscripts(func, allow_calls);
2306 }
2307 if (async) return subscripts(async, allow_calls);
2308 if (is("keyword", "class")) {
2309 next();
2310 var cls = class_(AST_ClassExpression);
2311 cls.start = start;
2312 cls.end = prev();
2313 return subscripts(cls, allow_calls);
2314 }
2315 if (is("template_head")) {
2316 return subscripts(template_string(false), allow_calls);
2317 }
2318 if (ATOMIC_START_TOKEN.has(S.token.type)) {
2319 return subscripts(as_atom_node(), allow_calls);
2320 }
2321 unexpected();
2322 };
2323
2324 function template_string() {
2325 var segments = [], start = S.token;
2326
2327 segments.push(new AST_TemplateSegment({
2328 start: S.token,
2329 raw: S.token.raw,
2330 value: S.token.value,
2331 end: S.token
2332 }));
2333 while (!S.token.end) {
2334 next();
2335 handle_regexp();
2336 segments.push(expression(true));
2337
2338 if (!is_token("template_substitution")) {
2339 unexpected();
2340 }
2341
2342 segments.push(new AST_TemplateSegment({
2343 start: S.token,
2344 raw: S.token.raw,
2345 value: S.token.value,
2346 end: S.token
2347 }));
2348 }
2349 next();
2350
2351 return new AST_TemplateString({
2352 start: start,
2353 segments: segments,
2354 end: S.token
2355 });
2356 }
2357
2358 function expr_list(closing, allow_trailing_comma, allow_empty) {
2359 var first = true, a = [];
2360 while (!is("punc", closing)) {
2361 if (first) first = false; else expect(",");
2362 if (allow_trailing_comma && is("punc", closing)) break;
2363 if (is("punc", ",") && allow_empty) {
2364 a.push(new AST_Hole({ start: S.token, end: S.token }));
2365 } else if (is("expand", "...")) {
2366 next();
2367 a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token}));
2368 } else {
2369 a.push(expression(false));
2370 }
2371 }
2372 next();
2373 return a;
2374 }
2375
2376 var array_ = embed_tokens(function() {
2377 expect("[");
2378 return new AST_Array({
2379 elements: expr_list("]", !options.strict, true)
2380 });
2381 });
2382
2383 var create_accessor = embed_tokens((is_generator, is_async) => {
2384 return function_(AST_Accessor, is_generator, is_async);
2385 });
2386
2387 var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
2388 var start = S.token, first = true, a = [];
2389 expect("{");
2390 while (!is("punc", "}")) {
2391 if (first) first = false; else expect(",");
2392 if (!options.strict && is("punc", "}"))
2393 // allow trailing comma
2394 break;
2395
2396 start = S.token;
2397 if (start.type == "expand") {
2398 next();
2399 a.push(new AST_Expansion({
2400 start: start,
2401 expression: expression(false),
2402 end: prev(),
2403 }));
2404 continue;
2405 }
2406
2407 var name = as_property_name();
2408 var value;
2409
2410 // Check property and fetch value
2411 if (!is("punc", ":")) {
2412 var concise = concise_method_or_getset(name, start);
2413 if (concise) {
2414 a.push(concise);
2415 continue;
2416 }
2417
2418 value = new AST_SymbolRef({
2419 start: prev(),
2420 name: name,
2421 end: prev()
2422 });
2423 } else if (name === null) {
2424 unexpected(prev());
2425 } else {
2426 next(); // `:` - see first condition
2427 value = expression(false);
2428 }
2429
2430 // Check for default value and alter value accordingly if necessary
2431 if (is("operator", "=")) {
2432 next();
2433 value = new AST_Assign({
2434 start: start,
2435 left: value,
2436 operator: "=",
2437 right: expression(false),
2438 end: prev()
2439 });
2440 }
2441
2442 // Create property
2443 a.push(new AST_ObjectKeyVal({
2444 start: start,
2445 quote: start.quote,
2446 key: name instanceof AST_Node ? name : "" + name,
2447 value: value,
2448 end: prev()
2449 }));
2450 }
2451 next();
2452 return new AST_Object({ properties: a });
2453 });
2454
2455 function class_(KindOfClass) {
2456 var start, method, class_name, extends_, a = [];
2457
2458 S.input.push_directives_stack(); // Push directive stack, but not scope stack
2459 S.input.add_directive("use strict");
2460
2461 if (S.token.type == "name" && S.token.value != "extends") {
2462 class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
2463 }
2464
2465 if (KindOfClass === AST_DefClass && !class_name) {
2466 unexpected();
2467 }
2468
2469 if (S.token.value == "extends") {
2470 next();
2471 extends_ = expression(true);
2472 }
2473
2474 expect("{");
2475
2476 while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
2477 while (!is("punc", "}")) {
2478 start = S.token;
2479 method = concise_method_or_getset(as_property_name(), start, true);
2480 if (!method) { unexpected(); }
2481 a.push(method);
2482 while (is("punc", ";")) { next(); }
2483 }
2484
2485 S.input.pop_directives_stack();
2486
2487 next();
2488
2489 return new KindOfClass({
2490 start: start,
2491 name: class_name,
2492 extends: extends_,
2493 properties: a,
2494 end: prev(),
2495 });
2496 }
2497
2498 function concise_method_or_getset(name, start, is_class) {
2499 var get_method_name_ast = function(name, start) {
2500 if (typeof name === "string" || typeof name === "number") {
2501 return new AST_SymbolMethod({
2502 start,
2503 name: "" + name,
2504 end: prev()
2505 });
2506 } else if (name === null) {
2507 unexpected();
2508 }
2509 return name;
2510 };
2511 const get_class_property_key_ast = (name) => {
2512 if (typeof name === "string" || typeof name === "number") {
2513 return new AST_SymbolClassProperty({
2514 start: property_token,
2515 end: property_token,
2516 name: "" + name
2517 });
2518 } else if (name === null) {
2519 unexpected();
2520 }
2521 return name;
2522 };
2523 var is_async = false;
2524 var is_static = false;
2525 var is_generator = false;
2526 var property_token = start;
2527 if (is_class && name === "static" && !is("punc", "(")) {
2528 is_static = true;
2529 property_token = S.token;
2530 name = as_property_name();
2531 }
2532 if (name === "async" && !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=")) {
2533 is_async = true;
2534 property_token = S.token;
2535 name = as_property_name();
2536 }
2537 if (name === null) {
2538 is_generator = true;
2539 property_token = S.token;
2540 name = as_property_name();
2541 if (name === null) {
2542 unexpected();
2543 }
2544 }
2545 if (is("punc", "(")) {
2546 name = get_method_name_ast(name, start);
2547 var node = new AST_ConciseMethod({
2548 start : start,
2549 static : is_static,
2550 is_generator: is_generator,
2551 async : is_async,
2552 key : name,
2553 quote : name instanceof AST_SymbolMethod ?
2554 property_token.quote : undefined,
2555 value : create_accessor(is_generator, is_async),
2556 end : prev()
2557 });
2558 return node;
2559 }
2560 const setter_token = S.token;
2561 if (name == "get") {
2562 if (!is("punc") || is("punc", "[")) {
2563 name = get_method_name_ast(as_property_name(), start);
2564 return new AST_ObjectGetter({
2565 start : start,
2566 static: is_static,
2567 key : name,
2568 quote : name instanceof AST_SymbolMethod ?
2569 setter_token.quote : undefined,
2570 value : create_accessor(),
2571 end : prev()
2572 });
2573 }
2574 } else if (name == "set") {
2575 if (!is("punc") || is("punc", "[")) {
2576 name = get_method_name_ast(as_property_name(), start);
2577 return new AST_ObjectSetter({
2578 start : start,
2579 static: is_static,
2580 key : name,
2581 quote : name instanceof AST_SymbolMethod ?
2582 setter_token.quote : undefined,
2583 value : create_accessor(),
2584 end : prev()
2585 });
2586 }
2587 }
2588 if (is_class) {
2589 const key = get_class_property_key_ast(name, property_token);
2590 const quote = key instanceof AST_SymbolClassProperty
2591 ? property_token.quote
2592 : undefined;
2593 if (is("operator", "=")) {
2594 next();
2595 return new AST_ClassProperty({
2596 start,
2597 static: is_static,
2598 quote,
2599 key,
2600 value: expression(false),
2601 end: prev()
2602 });
2603 } else if (is("name") || is("punc", ";") || is("punc", "}")) {
2604 return new AST_ClassProperty({
2605 start,
2606 static: is_static,
2607 quote,
2608 key,
2609 end: prev()
2610 });
2611 }
2612 }
2613 }
2614
2615 function import_() {
2616 var start = prev();
2617
2618 var imported_name;
2619 var imported_names;
2620 if (is("name")) {
2621 imported_name = as_symbol(AST_SymbolImport);
2622 }
2623
2624 if (is("punc", ",")) {
2625 next();
2626 }
2627
2628 imported_names = map_names(true);
2629
2630 if (imported_names || imported_name) {
2631 expect_token("name", "from");
2632 }
2633 var mod_str = S.token;
2634 if (mod_str.type !== "string") {
2635 unexpected();
2636 }
2637 next();
2638 return new AST_Import({
2639 start: start,
2640 imported_name: imported_name,
2641 imported_names: imported_names,
2642 module_name: new AST_String({
2643 start: mod_str,
2644 value: mod_str.value,
2645 quote: mod_str.quote,
2646 end: mod_str,
2647 }),
2648 end: S.token,
2649 });
2650 }
2651
2652 function import_meta() {
2653 var start = S.token;
2654 expect_token("operator", "import");
2655 expect_token("punc", ".");
2656 expect_token("name", "meta");
2657 return subscripts(new AST_ImportMeta({
2658 start: start,
2659 end: prev()
2660 }), false);
2661 }
2662
2663 function map_name(is_import) {
2664 function make_symbol(type) {
2665 return new type({
2666 name: as_property_name(),
2667 start: prev(),
2668 end: prev()
2669 });
2670 }
2671
2672 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2673 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2674 var start = S.token;
2675 var foreign_name;
2676 var name;
2677
2678 if (is_import) {
2679 foreign_name = make_symbol(foreign_type);
2680 } else {
2681 name = make_symbol(type);
2682 }
2683 if (is("name", "as")) {
2684 next(); // The "as" word
2685 if (is_import) {
2686 name = make_symbol(type);
2687 } else {
2688 foreign_name = make_symbol(foreign_type);
2689 }
2690 } else if (is_import) {
2691 name = new type(foreign_name);
2692 } else {
2693 foreign_name = new foreign_type(name);
2694 }
2695
2696 return new AST_NameMapping({
2697 start: start,
2698 foreign_name: foreign_name,
2699 name: name,
2700 end: prev(),
2701 });
2702 }
2703
2704 function map_nameAsterisk(is_import, name) {
2705 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2706 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2707 var start = S.token;
2708 var foreign_name;
2709 var end = prev();
2710
2711 name = name || new type({
2712 name: "*",
2713 start: start,
2714 end: end,
2715 });
2716
2717 foreign_name = new foreign_type({
2718 name: "*",
2719 start: start,
2720 end: end,
2721 });
2722
2723 return new AST_NameMapping({
2724 start: start,
2725 foreign_name: foreign_name,
2726 name: name,
2727 end: end,
2728 });
2729 }
2730
2731 function map_names(is_import) {
2732 var names;
2733 if (is("punc", "{")) {
2734 next();
2735 names = [];
2736 while (!is("punc", "}")) {
2737 names.push(map_name(is_import));
2738 if (is("punc", ",")) {
2739 next();
2740 }
2741 }
2742 next();
2743 } else if (is("operator", "*")) {
2744 var name;
2745 next();
2746 if (is_import && is("name", "as")) {
2747 next(); // The "as" word
2748 name = as_symbol(is_import ? AST_SymbolImport : AST_SymbolExportForeign);
2749 }
2750 names = [map_nameAsterisk(is_import, name)];
2751 }
2752 return names;
2753 }
2754
2755 function export_() {
2756 var start = S.token;
2757 var is_default;
2758 var exported_names;
2759
2760 if (is("keyword", "default")) {
2761 is_default = true;
2762 next();
2763 } else if (exported_names = map_names(false)) {
2764 if (is("name", "from")) {
2765 next();
2766
2767 var mod_str = S.token;
2768 if (mod_str.type !== "string") {
2769 unexpected();
2770 }
2771 next();
2772
2773 return new AST_Export({
2774 start: start,
2775 is_default: is_default,
2776 exported_names: exported_names,
2777 module_name: new AST_String({
2778 start: mod_str,
2779 value: mod_str.value,
2780 quote: mod_str.quote,
2781 end: mod_str,
2782 }),
2783 end: prev(),
2784 });
2785 } else {
2786 return new AST_Export({
2787 start: start,
2788 is_default: is_default,
2789 exported_names: exported_names,
2790 end: prev(),
2791 });
2792 }
2793 }
2794
2795 var node;
2796 var exported_value;
2797 var exported_definition;
2798 if (is("punc", "{")
2799 || is_default
2800 && (is("keyword", "class") || is("keyword", "function"))
2801 && is_token(peek(), "punc")) {
2802 exported_value = expression(false);
2803 semicolon();
2804 } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
2805 unexpected(node.start);
2806 } else if (node instanceof AST_Definitions || node instanceof AST_Lambda || node instanceof AST_DefClass) {
2807 exported_definition = node;
2808 } else if (node instanceof AST_SimpleStatement) {
2809 exported_value = node.body;
2810 } else {
2811 unexpected(node.start);
2812 }
2813
2814 return new AST_Export({
2815 start: start,
2816 is_default: is_default,
2817 exported_value: exported_value,
2818 exported_definition: exported_definition,
2819 end: prev(),
2820 });
2821 }
2822
2823 function as_property_name() {
2824 var tmp = S.token;
2825 switch (tmp.type) {
2826 case "punc":
2827 if (tmp.value === "[") {
2828 next();
2829 var ex = expression(false);
2830 expect("]");
2831 return ex;
2832 } else unexpected(tmp);
2833 case "operator":
2834 if (tmp.value === "*") {
2835 next();
2836 return null;
2837 }
2838 if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) {
2839 unexpected(tmp);
2840 }
2841 /* falls through */
2842 case "name":
2843 case "string":
2844 case "num":
2845 case "big_int":
2846 case "keyword":
2847 case "atom":
2848 next();
2849 return tmp.value;
2850 default:
2851 unexpected(tmp);
2852 }
2853 }
2854
2855 function as_name() {
2856 var tmp = S.token;
2857 if (tmp.type != "name") unexpected();
2858 next();
2859 return tmp.value;
2860 }
2861
2862 function _make_symbol(type) {
2863 var name = S.token.value;
2864 return new (name == "this" ? AST_This :
2865 name == "super" ? AST_Super :
2866 type)({
2867 name : String(name),
2868 start : S.token,
2869 end : S.token
2870 });
2871 }
2872
2873 function _verify_symbol(sym) {
2874 var name = sym.name;
2875 if (is_in_generator() && name == "yield") {
2876 token_error(sym.start, "Yield cannot be used as identifier inside generators");
2877 }
2878 if (S.input.has_directive("use strict")) {
2879 if (name == "yield") {
2880 token_error(sym.start, "Unexpected yield identifier inside strict mode");
2881 }
2882 if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
2883 token_error(sym.start, "Unexpected " + name + " in strict mode");
2884 }
2885 }
2886 }
2887
2888 function as_symbol(type, noerror) {
2889 if (!is("name")) {
2890 if (!noerror) croak("Name expected");
2891 return null;
2892 }
2893 var sym = _make_symbol(type);
2894 _verify_symbol(sym);
2895 next();
2896 return sym;
2897 }
2898
2899 // Annotate AST_Call, AST_Lambda or AST_New with the special comments
2900 function annotate(node) {
2901 var start = node.start;
2902 var comments = start.comments_before;
2903 const comments_outside_parens = outer_comments_before_counts.get(start);
2904 var i = comments_outside_parens != null ? comments_outside_parens : comments.length;
2905 while (--i >= 0) {
2906 var comment = comments[i];
2907 if (/[@#]__/.test(comment.value)) {
2908 if (/[@#]__PURE__/.test(comment.value)) {
2909 set_annotation(node, _PURE);
2910 break;
2911 }
2912 if (/[@#]__INLINE__/.test(comment.value)) {
2913 set_annotation(node, _INLINE);
2914 break;
2915 }
2916 if (/[@#]__NOINLINE__/.test(comment.value)) {
2917 set_annotation(node, _NOINLINE);
2918 break;
2919 }
2920 }
2921 }
2922 }
2923
2924 var subscripts = function(expr, allow_calls, is_chain) {
2925 var start = expr.start;
2926 if (is("punc", ".")) {
2927 next();
2928 return subscripts(new AST_Dot({
2929 start : start,
2930 expression : expr,
2931 optional : false,
2932 property : as_name(),
2933 end : prev()
2934 }), allow_calls, is_chain);
2935 }
2936 if (is("punc", "[")) {
2937 next();
2938 var prop = expression(true);
2939 expect("]");
2940 return subscripts(new AST_Sub({
2941 start : start,
2942 expression : expr,
2943 optional : false,
2944 property : prop,
2945 end : prev()
2946 }), allow_calls, is_chain);
2947 }
2948 if (allow_calls && is("punc", "(")) {
2949 next();
2950 var call = new AST_Call({
2951 start : start,
2952 expression : expr,
2953 optional : false,
2954 args : call_args(),
2955 end : prev()
2956 });
2957 annotate(call);
2958 return subscripts(call, true, is_chain);
2959 }
2960
2961 if (is("punc", "?.")) {
2962 next();
2963
2964 let chain_contents;
2965
2966 if (allow_calls && is("punc", "(")) {
2967 next();
2968
2969 const call = new AST_Call({
2970 start,
2971 optional: true,
2972 expression: expr,
2973 args: call_args(),
2974 end: prev()
2975 });
2976 annotate(call);
2977
2978 chain_contents = subscripts(call, true, true);
2979 } else if (is("name")) {
2980 chain_contents = subscripts(new AST_Dot({
2981 start,
2982 expression: expr,
2983 optional: true,
2984 property: as_name(),
2985 end: prev()
2986 }), allow_calls, true);
2987 } else if (is("punc", "[")) {
2988 next();
2989 const property = expression(true);
2990 expect("]");
2991 chain_contents = subscripts(new AST_Sub({
2992 start,
2993 expression: expr,
2994 optional: true,
2995 property,
2996 end: prev()
2997 }), allow_calls, true);
2998 }
2999
3000 if (!chain_contents) unexpected();
3001
3002 if (chain_contents instanceof AST_Chain) return chain_contents;
3003
3004 return new AST_Chain({
3005 start,
3006 expression: chain_contents,
3007 end: prev()
3008 });
3009 }
3010
3011 if (is("template_head")) {
3012 if (is_chain) {
3013 // a?.b`c` is a syntax error
3014 unexpected();
3015 }
3016
3017 return subscripts(new AST_PrefixedTemplateString({
3018 start: start,
3019 prefix: expr,
3020 template_string: template_string(true),
3021 end: prev()
3022 }), allow_calls);
3023 }
3024
3025 return expr;
3026 };
3027
3028 function call_args() {
3029 var args = [];
3030 while (!is("punc", ")")) {
3031 if (is("expand", "...")) {
3032 next();
3033 args.push(new AST_Expansion({
3034 start: prev(),
3035 expression: expression(false),
3036 end: prev()
3037 }));
3038 } else {
3039 args.push(expression(false));
3040 }
3041 if (!is("punc", ")")) {
3042 expect(",");
3043 }
3044 }
3045 next();
3046 return args;
3047 }
3048
3049 var maybe_unary = function(allow_calls, allow_arrows) {
3050 var start = S.token;
3051 if (start.type == "name" && start.value == "await") {
3052 if (is_in_async()) {
3053 next();
3054 return _await_expression();
3055 } else if (S.input.has_directive("use strict")) {
3056 token_error(S.token, "Unexpected await identifier inside strict mode");
3057 }
3058 }
3059 if (is("operator") && UNARY_PREFIX.has(start.value)) {
3060 next();
3061 handle_regexp();
3062 var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
3063 ex.start = start;
3064 ex.end = prev();
3065 return ex;
3066 }
3067 var val = expr_atom(allow_calls, allow_arrows);
3068 while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) {
3069 if (val instanceof AST_Arrow) unexpected();
3070 val = make_unary(AST_UnaryPostfix, S.token, val);
3071 val.start = start;
3072 val.end = S.token;
3073 next();
3074 }
3075 return val;
3076 };
3077
3078 function make_unary(ctor, token, expr) {
3079 var op = token.value;
3080 switch (op) {
3081 case "++":
3082 case "--":
3083 if (!is_assignable(expr))
3084 croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
3085 break;
3086 case "delete":
3087 if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
3088 croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
3089 break;
3090 }
3091 return new ctor({ operator: op, expression: expr });
3092 }
3093
3094 var expr_op = function(left, min_prec, no_in) {
3095 var op = is("operator") ? S.token.value : null;
3096 if (op == "in" && no_in) op = null;
3097 if (op == "**" && left instanceof AST_UnaryPrefix
3098 /* unary token in front not allowed - parenthesis required */
3099 && !is_token(left.start, "punc", "(")
3100 && left.operator !== "--" && left.operator !== "++")
3101 unexpected(left.start);
3102 var prec = op != null ? PRECEDENCE[op] : null;
3103 if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) {
3104 next();
3105 var right = expr_op(maybe_unary(true), prec, no_in);
3106 return expr_op(new AST_Binary({
3107 start : left.start,
3108 left : left,
3109 operator : op,
3110 right : right,
3111 end : right.end
3112 }), min_prec, no_in);
3113 }
3114 return left;
3115 };
3116
3117 function expr_ops(no_in) {
3118 return expr_op(maybe_unary(true, true), 0, no_in);
3119 }
3120
3121 var maybe_conditional = function(no_in) {
3122 var start = S.token;
3123 var expr = expr_ops(no_in);
3124 if (is("operator", "?")) {
3125 next();
3126 var yes = expression(false);
3127 expect(":");
3128 return new AST_Conditional({
3129 start : start,
3130 condition : expr,
3131 consequent : yes,
3132 alternative : expression(false, no_in),
3133 end : prev()
3134 });
3135 }
3136 return expr;
3137 };
3138
3139 function is_assignable(expr) {
3140 return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
3141 }
3142
3143 function to_destructuring(node) {
3144 if (node instanceof AST_Object) {
3145 node = new AST_Destructuring({
3146 start: node.start,
3147 names: node.properties.map(to_destructuring),
3148 is_array: false,
3149 end: node.end
3150 });
3151 } else if (node instanceof AST_Array) {
3152 var names = [];
3153
3154 for (var i = 0; i < node.elements.length; i++) {
3155 // Only allow expansion as last element
3156 if (node.elements[i] instanceof AST_Expansion) {
3157 if (i + 1 !== node.elements.length) {
3158 token_error(node.elements[i].start, "Spread must the be last element in destructuring array");
3159 }
3160 node.elements[i].expression = to_destructuring(node.elements[i].expression);
3161 }
3162
3163 names.push(to_destructuring(node.elements[i]));
3164 }
3165
3166 node = new AST_Destructuring({
3167 start: node.start,
3168 names: names,
3169 is_array: true,
3170 end: node.end
3171 });
3172 } else if (node instanceof AST_ObjectProperty) {
3173 node.value = to_destructuring(node.value);
3174 } else if (node instanceof AST_Assign) {
3175 node = new AST_DefaultAssign({
3176 start: node.start,
3177 left: node.left,
3178 operator: "=",
3179 right: node.right,
3180 end: node.end
3181 });
3182 }
3183 return node;
3184 }
3185
3186 // In ES6, AssignmentExpression can also be an ArrowFunction
3187 var maybe_assign = function(no_in) {
3188 handle_regexp();
3189 var start = S.token;
3190
3191 if (start.type == "name" && start.value == "yield") {
3192 if (is_in_generator()) {
3193 next();
3194 return _yield_expression();
3195 } else if (S.input.has_directive("use strict")) {
3196 token_error(S.token, "Unexpected yield identifier inside strict mode");
3197 }
3198 }
3199
3200 var left = maybe_conditional(no_in);
3201 var val = S.token.value;
3202
3203 if (is("operator") && ASSIGNMENT.has(val)) {
3204 if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
3205 next();
3206 return new AST_Assign({
3207 start : start,
3208 left : left,
3209 operator : val,
3210 right : maybe_assign(no_in),
3211 end : prev()
3212 });
3213 }
3214 croak("Invalid assignment");
3215 }
3216 return left;
3217 };
3218
3219 var expression = function(commas, no_in) {
3220 var start = S.token;
3221 var exprs = [];
3222 while (true) {
3223 exprs.push(maybe_assign(no_in));
3224 if (!commas || !is("punc", ",")) break;
3225 next();
3226 commas = true;
3227 }
3228 return exprs.length == 1 ? exprs[0] : new AST_Sequence({
3229 start : start,
3230 expressions : exprs,
3231 end : peek()
3232 });
3233 };
3234
3235 function in_loop(cont) {
3236 ++S.in_loop;
3237 var ret = cont();
3238 --S.in_loop;
3239 return ret;
3240 }
3241
3242 if (options.expression) {
3243 return expression(true);
3244 }
3245
3246 return (function parse_toplevel() {
3247 var start = S.token;
3248 var body = [];
3249 S.input.push_directives_stack();
3250 if (options.module) S.input.add_directive("use strict");
3251 while (!is("eof")) {
3252 body.push(statement());
3253 }
3254 S.input.pop_directives_stack();
3255 var end = prev();
3256 var toplevel = options.toplevel;
3257 if (toplevel) {
3258 toplevel.body = toplevel.body.concat(body);
3259 toplevel.end = end;
3260 } else {
3261 toplevel = new AST_Toplevel({ start: start, body: body, end: end });
3262 }
3263 return toplevel;
3264 })();
3265
3266}
3267
3268export {
3269 get_full_char_code,
3270 get_full_char,
3271 is_identifier_char,
3272 is_basic_identifier_string,
3273 is_identifier_string,
3274 is_surrogate_pair_head,
3275 is_surrogate_pair_tail,
3276 js_error,
3277 JS_Parse_Error,
3278 parse,
3279 PRECEDENCE,
3280 RESERVED_WORDS,
3281 tokenizer,
3282};