UNPKG

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