source: imaps-frontend/node_modules/terser/lib/parse.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

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