/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
A JavaScript tokenizer / parser / beautifier / compressor .
https : //github.com/mishoo/UglifyJS2
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ( C ) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
Author : Mihai Bazon
< mihai . bazon @ gmail . com >
http : //mihai.bazon.net/blog
Distributed under the BSD license :
Copyright 2012 ( c ) Mihai Bazon < mihai . bazon @ gmail . com >
Parser based on parse - js ( http : //marijn.haverbeke.nl/parse-js/).
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
* Redistributions of source code must retain the above
copyright notice , this list of conditions and the following
disclaimer .
* Redistributions in binary form must reproduce the above
copyright notice , this list of conditions and the following
disclaimer in the documentation and / or other materials
provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “ AS IS ” AND ANY
EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY ,
OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO ,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR
TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
"use strict" ;
import {
characters ,
defaults ,
makePredicate ,
set _annotation ,
} from "./utils/index.js" ;
import {
AST _Accessor ,
AST _Array ,
AST _Arrow ,
AST _Assign ,
AST _Await ,
AST _BigInt ,
AST _Binary ,
AST _BlockStatement ,
AST _Break ,
AST _Call ,
AST _Case ,
AST _Catch ,
AST _Chain ,
AST _ClassExpression ,
AST _ClassPrivateProperty ,
AST _ClassProperty ,
AST _ConciseMethod ,
AST _PrivateGetter ,
AST _PrivateMethod ,
AST _PrivateSetter ,
AST _Conditional ,
AST _Const ,
AST _Continue ,
AST _Debugger ,
AST _Default ,
AST _DefaultAssign ,
AST _DefClass ,
AST _Definitions ,
AST _Defun ,
AST _Destructuring ,
AST _Directive ,
AST _Do ,
AST _Dot ,
AST _DotHash ,
AST _EmptyStatement ,
AST _Expansion ,
AST _Export ,
AST _False ,
AST _Finally ,
AST _For ,
AST _ForIn ,
AST _ForOf ,
AST _Function ,
AST _Hole ,
AST _If ,
AST _Import ,
AST _ImportMeta ,
AST _IterationStatement ,
AST _Label ,
AST _LabeledStatement ,
AST _LabelRef ,
AST _Let ,
AST _NameMapping ,
AST _New ,
AST _NewTarget ,
AST _Node ,
AST _Null ,
AST _Number ,
AST _Object ,
AST _ObjectGetter ,
AST _ObjectKeyVal ,
AST _ObjectProperty ,
AST _ObjectSetter ,
AST _PrefixedTemplateString ,
AST _PropAccess ,
AST _RegExp ,
AST _Return ,
AST _Sequence ,
AST _SimpleStatement ,
AST _String ,
AST _Sub ,
AST _Super ,
AST _Switch ,
AST _SymbolCatch ,
AST _SymbolClass ,
AST _SymbolClassProperty ,
AST _SymbolConst ,
AST _SymbolDeclaration ,
AST _SymbolDefClass ,
AST _SymbolDefun ,
AST _SymbolExport ,
AST _SymbolExportForeign ,
AST _SymbolFunarg ,
AST _SymbolImport ,
AST _SymbolImportForeign ,
AST _SymbolLambda ,
AST _SymbolLet ,
AST _SymbolMethod ,
AST _SymbolRef ,
AST _SymbolVar ,
AST _TemplateSegment ,
AST _TemplateString ,
AST _This ,
AST _Throw ,
AST _Token ,
AST _Toplevel ,
AST _True ,
AST _Try ,
AST _UnaryPostfix ,
AST _UnaryPrefix ,
AST _Var ,
AST _VarDef ,
AST _While ,
AST _With ,
AST _Yield ,
_INLINE ,
_NOINLINE ,
_PURE
} from "./ast.js" ;
var LATEST _RAW = "" ; // Only used for numbers and template strings
var LATEST _TEMPLATE _END = true ;
var 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" ;
var KEYWORDS _ATOM = "false null true" ;
var RESERVED _WORDS = "enum import super this " + KEYWORDS _ATOM + " " + KEYWORDS ;
var ALL _RESERVED _WORDS = "implements interface package private protected public static " + RESERVED _WORDS ;
var KEYWORDS _BEFORE _EXPRESSION = "return new delete throw else case yield await" ;
KEYWORDS = makePredicate ( KEYWORDS ) ;
RESERVED _WORDS = makePredicate ( RESERVED _WORDS ) ;
KEYWORDS _BEFORE _EXPRESSION = makePredicate ( KEYWORDS _BEFORE _EXPRESSION ) ;
KEYWORDS _ATOM = makePredicate ( KEYWORDS _ATOM ) ;
ALL _RESERVED _WORDS = makePredicate ( ALL _RESERVED _WORDS ) ;
var OPERATOR _CHARS = makePredicate ( characters ( "+-*&%=<>!?|~^" ) ) ;
var RE _NUM _LITERAL = /[0-9a-f]/i ;
var RE _HEX _NUMBER = /^0x[0-9a-f]+$/i ;
var RE _OCT _NUMBER = /^0[0-7]+$/ ;
var RE _ES6 _OCT _NUMBER = /^0o[0-7]+$/i ;
var RE _BIN _NUMBER = /^0b[01]+$/i ;
var RE _DEC _NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i ;
var RE _BIG _INT = /^(0[xob])?[0-9a-f]+n$/i ;
var OPERATORS = makePredicate ( [
"in" ,
"instanceof" ,
"typeof" ,
"new" ,
"void" ,
"delete" ,
"++" ,
"--" ,
"+" ,
"-" ,
"!" ,
"~" ,
"&" ,
"|" ,
"^" ,
"*" ,
"**" ,
"/" ,
"%" ,
">>" ,
"<<" ,
">>>" ,
"<" ,
">" ,
"<=" ,
">=" ,
"==" ,
"===" ,
"!=" ,
"!==" ,
"?" ,
"=" ,
"+=" ,
"-=" ,
"||=" ,
"&&=" ,
"??=" ,
"/=" ,
"*=" ,
"**=" ,
"%=" ,
">>=" ,
"<<=" ,
">>>=" ,
"|=" ,
"^=" ,
"&=" ,
"&&" ,
"??" ,
"||" ,
] ) ;
var 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" ) ) ;
var NEWLINE _CHARS = makePredicate ( characters ( "\n\r\u2028\u2029" ) ) ;
var PUNC _AFTER _EXPRESSION = makePredicate ( characters ( ";]),:" ) ) ;
var PUNC _BEFORE _EXPRESSION = makePredicate ( characters ( "[{(,;:" ) ) ;
var PUNC _CHARS = makePredicate ( characters ( "[]{}(),;:" ) ) ;
/* -----[ Tokenizer ]----- */
// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
var UNICODE = {
ID _Start : / [ $ A - Z _ a - z \ x A A \ x B 5 \ x B A \ x C 0 - \ x D 6 \ x D 8 - \ x F 6 \ x F 8 - \ u 0 2 C 1 \ u 0 2 C 6 - \ u 0 2 D 1 \ u 0 2 E 0 - \ u 0 2 E 4 \ u 0 2 E C \ u 0 2 E E \ u 0 3 7 0 - \ u 0 3 7 4 \ u 0 3 7 6 \ u 0 3 7 7 \ u 0 3 7 A - \ u 0 3 7 D \ u 0 3 7 F \ u 0 3 8 6 \ u 0 3 8 8 - \ u 0 3 8 A \ u 0 3 8 C \ u 0 3 8 E - \ u 0 3 A 1 \ u 0 3 A 3 - \ u 0 3 F 5 \ u 0 3 F 7 - \ u 0 4 8 1 \ u 0 4 8 A - \ u 0 5 2 F \ u 0 5 3 1 - \ u 0 5 5 6 \ u 0 5 5 9 \ u 0 5 6 1 - \ u 0 5 8 7 \ u 0 5 D 0 - \ u 0 5 E A \ u 0 5 F 0 - \ u 0 5 F 2 \ u 0 6 2 0 - \ u 0 6 4 A \ u 0 6 6 E \ u 0 6 6 F \ u 0 6 7 1 - \ u 0 6 D 3 \ u 0 6 D 5 \ u 0 6 E 5 \ u 0 6 E 6 \ u 0 6 E E \ u 0 6 E F \ u 0 6 F A - \ u 0 6 F C \ u 0 6 F F \ u 0 7 1 0 \ u 0 7 1 2 - \ u 0 7 2 F \ u 0 7 4 D - \ u 0 7 A 5 \ u 0 7 B 1 \ u 0 7 C A - \ u 0 7 E A \ u 0 7 F 4 \ u 0 7 F 5 \ u 0 7 F A \ u 0 8 0 0 - \ u 0 8 1 5 \ u 0 8 1 A \ u 0 8 2 4 \ u 0 8 2 8 \ u 0 8 4 0 - \ u 0 8 5 8 \ u 0 8 A 0 - \ u 0 8 B 4 \ u 0 9 0 4 - \ u 0 9 3 9 \ u 0 9 3 D \ u 0 9 5 0 \ u 0 9 5 8 - \ u 0 9 6 1 \ u 0 9 7 1 - \ u 0 9 8 0 \ u 0 9 8 5 - \ u 0 9 8 C \ u 0 9 8 F \ u 0 9 9 0 \ u 0 9 9 3 - \ u 0 9 A 8 \ u 0 9 A A - \ u 0 9 B 0 \ u 0 9 B 2 \ u 0 9 B 6 - \ u 0 9 B 9 \ u 0 9 B D \ u 0 9 C E \ u 0 9 D C \ u 0 9 D D \ u 0 9 D F - \ u 0 9 E 1 \ u 0 9 F 0 \ u 0 9 F 1 \ u 0 A 0 5 - \ u 0 A 0 A \ u 0 A 0 F \ u 0 A 1 0 \ u 0 A 1 3 - \ u 0 A 2 8 \ u 0 A 2 A - \ u 0 A 3 0 \ u 0 A 3 2 \ u 0 A 3 3 \ u 0 A 3 5 \ u 0 A 3 6 \ u 0 A 3 8 \ u 0 A 3 9 \ u 0 A 5 9 - \ u 0 A 5 C \ u 0 A 5 E \ u 0 A 7 2 - \ u 0 A 7 4 \ u 0 A 8 5 - \ u 0 A 8 D \ u 0 A 8 F - \ u 0 A 9 1 \ u 0 A 9 3 - \ u 0 A A 8 \ u 0 A A A - \ u 0 A B 0 \ u 0 A B 2 \ u 0 A B 3 \ u 0 A B 5 - \ u 0 A B 9 \ u 0 A B D \ u 0 A D 0 \ u 0 A E 0 \ u 0 A E 1 \ u 0 A F 9 \ u 0 B 0 5 - \ u 0 B 0 C \ u 0 B 0 F \ u 0 B 1 0 \ u 0 B 1 3 - \ u 0 B 2 8 \ u 0 B 2 A - \ u 0 B 3 0 \ u 0 B 3 2 \ u 0 B 3 3 \ u 0 B 3 5 - \ u 0 B 3 9 \ u 0 B 3 D \ u 0 B 5 C \ u 0 B 5 D \ u 0 B 5 F - \ u 0 B 6 1 \ u 0 B 7 1 \ u 0 B 8 3 \ u 0 B 8 5 - \ u 0 B 8 A \ u 0 B 8 E - \ u 0 B 9 0 \ u 0 B 9 2 - \ u 0 B 9 5 \ u 0 B 9 9 \ u 0 B 9 A \ u 0 B 9 C \ u 0 B 9 E \ u 0 B 9 F \ u 0 B A 3 \ u 0 B A 4 \ u 0 B A 8 - \ u 0 B A A \ u 0 B A E - \ u 0 B B 9 \ u 0 B D 0 \ u 0 C 0 5 - \ u 0 C 0 C \ u 0 C 0 E - \ u 0 C 1 0 \ u 0 C 1 2 - \ u 0 C 2 8 \ u 0 C 2 A - \ u 0 C 3 9 \ u 0 C 3 D \ u 0 C 5 8 - \ u 0 C 5 A \ u 0 C 6 0 \ u 0 C 6 1 \ u 0 C 8 5 - \ u 0 C 8 C \ u 0 C 8 E - \ u 0 C 9 0 \ u 0 C 9 2 - \ u 0 C A 8 \ u 0 C A A - \ u 0 C B 3 \ u 0 C B 5 - \ u 0 C B 9 \ u 0 C B D \ u 0 C D E \ u 0 C E 0 \ u 0 C E 1 \ u 0 C F 1 \ u 0 C F 2 \ u 0 D 0 5 - \ u 0 D 0 C \ u 0 D 0 E - \ u 0 D 1 0 \ u 0 D 1 2 - \ u 0 D 3 A \ u 0 D 3 D \ u 0 D 4 E \ u 0 D 5 F - \ u 0 D 6 1 \ u 0 D 7 A - \ u 0 D 7 F \ u 0 D 8 5 - \ u 0 D 9 6 \ u 0 D 9 A - \ u 0 D B 1 \ u 0 D B 3 - \ u 0 D B B \ u 0 D B D \ u 0 D C 0 - \ u 0 D C 6 \ u 0 E 0 1 - \ u 0 E 3 0 \ u 0 E 3 2 \ u 0 E 3 3 \ u 0 E 4 0 - \ u 0 E 4 6 \ u 0 E 8 1 \ u 0 E 8 2 \ u 0 E 8 4 \ u 0 E 8 7 \ u 0 E 8 8 \ u 0 E 8 A \ u 0 E 8 D \ u 0 E 9 4 - \ u 0 E 9 7 \ u 0 E 9 9 - \ u 0 E 9 F \ u 0 E A 1 - \ u 0 E A 3 \ u 0 E A 5 \ u 0 E A 7 \ u 0 E A A \ u 0 E A B \ u 0 E A D - \ u 0 E B 0 \ u 0 E B 2 \ u 0 E B 3 \ u 0 E B D \ u 0 E C 0 - \ u 0 E C 4 \ u 0 E C 6 \ u 0 E D C - \ u 0 E D F \ u 0 F 0 0 \ u 0 F 4 0 - \ u 0 F 4 7 \ u 0 F 4 9 - \ u 0 F 6 C \ u 0 F 8 8 - \ u 0 F 8 C \ u 1 0 0 0 - \ u 1 0 2 A \ u 1 0 3 F \ u 1 0 5 0 - \ u 1 0 5 5 \ u 1 0 5 A - \ u 1 0 5 D \ u 1 0 6 1 \ u 1 0 6 5 \ u 1 0 6 6 \ u 1 0 6 E - \ u 1 0 7 0 \ u 1 0 7 5 - \ u 1 0 8 1 \ u 1 0 8 E \ u 1 0 A 0 - \ u 1 0 C 5 \ u 1 0 C 7 \ u 1 0 C D \ u 1 0 D 0 - \ u 1 0 F A \ u 1 0 F C - \ u 1 2 4 8 \ u 1 2 4 A - \ u 1 2 4 D \ u 1 2 5 0 - \ u 1 2 5 6 \ u 1 2 5 8 \ u 1 2 5 A - \ u 1 2 5 D \ u 1 2 6 0 - \ u 1 2 8 8 \ u 1 2 8 A - \ u 1 2 8 D \ u 1 2 9 0 - \ u 1 2 B 0 \ u 1 2 B 2 - \ u 1 2 B 5 \ u 1 2 B 8 - \ u 1 2 B E \ u 1 2 C 0 \ u 1 2 C 2 - \ u 1 2 C 5 \ u 1 2 C 8 - \ u 1 2 D 6 \ u 1 2 D 8 - \ u 1 3 1 0 \ u 1 3 1 2 - \ u 1 3 1 5 \ u 1 3 1 8 - \ u 1 3 5 A \ u 1 3 8 0 - \ u 1 3 8 F \ u 1 3 A 0 - \ u 1 3 F 5 \ u 1 3 F 8 - \ u 1 3 F D \ u 1 4 0 1 - \ u 1 6 6 C \ u 1 6 6 F - \ u 1 6 7 F \ u 1 6 8 1 - \ u 1 6 9 A \ u 1 6 A 0 - \ u 1 6 E A \ u 1 6 E E - \ u 1 6 F 8 \ u 1 7 0 0 - \ u 1 7 0 C \ u 1 7 0 E - \ u 1 7 1 1 \ u 1 7 2 0 - \ u 1 7 3 1 \ u 1 7 4 0 - \ u 1 7 5 1 \ u 1 7 6 0 - \ u 1 7 6 C \ u 1 7 6 E - \ u 1 7 7 0 \ u 1 7 8 0 - \ u 1 7 B 3 \ u 1 7 D 7 \ u 1 7 D C \ u 1 8 2 0 - \ u 1 8 7 7 \ u 1 8 8 0 - \ u 1 8 A 8 \ u 1 8 A A \ u 1 8 B 0 - \ u 1 8 F 5 \ u 1 9 0 0 - \ u 1 9 1 E \ u 1 9 5 0 - \ u 1 9 6 D \ u 1 9 7 0 - \ u 1 9 7 4 \ u 1 9 8 0 - \ u 1 9 A B \ u 1 9 B 0 - \ u 1 9 C 9 \ u 1 A 0 0 - \ u 1 A 1 6 \ u 1 A 2 0 - \ u 1 A 5 4 \ u 1 A A 7 \ u 1 B 0 5 - \ u 1 B 3 3 \ u 1 B 4 5 - \ u 1 B 4 B \ u 1 B 8 3 - \ u 1 B A 0 \ u 1 B A E \ u 1 B A F \ u 1 B B A - \ u 1 B E 5 \ u 1 C 0 0 - \ u 1 C 2 3 \ u 1 C 4 D - \ u 1 C 4 F \ u 1 C 5 A - \ u 1 C 7 D \ u 1 C E 9 - \ u 1 C E C \ u 1 C E E - \ u 1 C F 1 \ u 1 C F 5 \ u 1 C F 6 \ u 1 D 0 0 - \ u 1 D B F \ u 1 E 0 0 - \ u 1 F 1 5 \ u 1 F 1 8 - \ u 1 F 1 D \ u 1 F 2 0 - \ u 1 F 4 5 \ u 1 F 4 8 - \ u 1 F 4 D \ u 1 F 5 0 - \ u 1 F 5 7 \ u 1 F 5 9 \ u 1 F 5 B \ u 1 F 5 D \ u 1 F 5 F - \ u 1 F 7 D \ u 1 F 8 0 - \ u 1 F B 4 \ u 1 F B 6 - \ u 1 F B C \ u 1 F B E \ u 1 F C 2 - \ u 1 F C 4 \ u 1 F C 6 - \ u 1 F C C \ u 1 F D 0 - \ u 1 F D 3 \ u 1 F D 6 - \ u 1 F D B \ u 1 F E 0 - \ u 1 F E C \ u 1 F F 2 - \ u 1 F F 4 \ u 1 F F 6 - \ u 1 F F C \ u 2 0 7 1 \ u 2 0 7 F \ u 2 0 9 0 - \ u 2 0 9 C \ u 2 1 0 2 \ u 2 1 0 7 \ u 2 1 0 A - \ u 2 1 1 3 \ u 2 1 1 5 \ u 2 1 1 8 - \ u 2 1 1 D \ u 2 1 2 4 \ u 2 1 2 6 \ u 2 1 2 8 \ u 2 1 2 A - \ u 2 1 3 9 \ u 2 1 3 C - \ u 2 1 3 F \ u 2 1 4 5 - \ u 2 1 4 9 \ u 2 1 4 E \ u 2 1 6 0 - \ u 2 1 8 8 \ u 2 C 0 0 - \ u 2 C 2 E \ u 2 C 3 0 - \ u 2 C 5 E \ u 2 C 6 0 - \ u 2 C E 4 \ u 2 C E B - \ u 2 C E E \ u 2 C F 2 \ u 2 C F 3 \ u 2 D 0 0 - \ u 2 D 2 5 \ u 2 D 2 7 \ u 2 D 2 D \ u 2 D 3 0 - \ u 2 D 6 7 \ u 2 D 6 F \ u 2 D 8 0 - \ u 2 D 9 6 \ u 2 D A 0 - \ u 2 D A 6 \ u 2 D A 8 - \ u 2 D A E \ u 2 D B 0 - \ u 2 D B 6 \ u 2 D B 8 - \ u 2 D B E \ u 2 D C 0 - \ u 2 D C 6 \ u 2 D C 8 - \ u 2 D C E \ u 2 D D 0 - \ u 2 D D 6 \ u 2 D D 8 - \ u 2 D D E \ u 3 0 0 5 - \ u 3 0 0 7 \ u 3 0 2 1 - \ u 3 0 2 9 \ u 3 0 3 1 - \ u 3 0 3 5 \ u 3 0 3 8 - \ u 3 0 3 C \ u 3 0 4 1 - \ u 3 0 9 6 \ u 3 0 9 B - \ u 3 0 9 F \ u 3 0 A 1 - \ u 3 0 F A \ u 3 0 F C - \ u 3 0 F F \ u 3 1 0 5 - \ u 3 1 2 D \ u 3 1 3 1 - \ u 3 1 8 E \ u 3 1 A 0 - \ u 3 1 B A \ u 3 1 F 0 - \ u 3 1 F F \ u 3 4 0 0 - \ u 4 D B 5 \ u 4 E 0 0 - \ u 9 F D 5 \ u A 0 0 0 - \ u A 4 8 C \ u A 4 D 0 - \ u A 4 F D \ u A 5 0 0 - \ u A 6 0 C \ u A 6 1 0 - \ u A 6 1 F \ u A 6 2 A \ u A 6 2 B \ u A 6 4 0 - \ u A 6 6 E \ u A 6 7 F - \ u A 6 9 D \ u A 6 A 0 - \ u A 6 E F \ u A 7 1 7 - \ u A 7 1 F \ u A 7 2 2 - \ u A 7 8 8 \ u A 7 8 B - \ u A 7 A D \ u A 7 B 0 - \ u A 7 B 7 \ u A 7 F 7 - \ u A 8 0 1 \ u A 8 0 3 - \ u A 8 0 5 \ u A 8 0 7 - \ u A 8 0 A \ u A 8 0 C - \ u A 8 2 2 \ u A 8 4 0 - \ u A 8 7 3 \ u A 8 8 2 - \ u A 8 B 3 \ u A 8 F 2 - \ u A 8 F 7 \ u A 8 F B \ u A 8 F D \ u A 9 0 A - \ u A 9 2 5 \ u A 9 3 0 - \ u A 9 4 6 \ u A 9 6 0 - \ u A 9 7 C \ u A 9 8 4 - \ u A 9 B 2 \ u A 9 C F \ u A 9 E 0 - \ u A 9 E 4 \ u A 9 E 6 - \ u A 9 E F \ u A 9 F A - \ u A 9 F E \ u A A 0 0 - \ u A A 2 8 \ u A A 4 0 - \ u A A 4 2 \ u A A 4 4 - \ u A A 4 B \ u A A 6 0 - \ u A A 7 6 \ u A A 7 A \ u A A 7 E - \ u A A A F \ u A A B 1 \ u A A B 5 \ u A A B 6 \ u A A B 9 - \ u A A B D \ u A A C 0 \ u A A C 2 \ u A A D B - \ u A A D D \ u A A E 0 - \ u A A E A \ u A A F 2 - \ u A A F 4 \ u A B 0 1 - \ u A B 0 6 \ u A B 0 9 - \ u A B 0 E \ u A B 1 1 - \ u A B 1 6 \ u A B 2 0 - \ u A B 2 6 \ u A B 2 8 - \ u A B 2 E \ u A B 3 0 - \ u A B 5 A \ u A B 5 C - \ u A B 6 5 \ u A B 7 0 - \ u A B E 2 \ u A C 0 0 - \ u D 7 A 3 \ u D 7 B 0 - \ u D 7 C 6 \ u D 7 C B - \ u D 7 F B \ u F 9 0 0 - \ u F A 6 D \ u F A 7 0 - \ u F A D 9 \ u F B 0 0 - \ u F B 0 6 \ u F B 1 3 - \ u F B 1 7 \ u F B 1 D \ u F B 1 F - \ u F B 2 8 \ u F B 2 A - \ u F B 3 6 \ u F B 3 8 - \ u F B 3 C \ u F B 3 E \ u F B 4 0 \ u F B 4 1 \ u F B 4 3 \ u F B 4 4 \ u F B 4 6 - \ u F B B 1 \ u F B D 3 - \ u F
ID _Continue : / ( ? : [ $ 0 - 9 A - Z _ a - z \ x A A \ x B 5 \ x B 7 \ x B A \ x C 0 - \ x D 6 \ x D 8 - \ x F 6 \ x F 8 - \ u 0 2 C 1 \ u 0 2 C 6 - \ u 0 2 D 1 \ u 0 2 E 0 - \ u 0 2 E 4 \ u 0 2 E C \ u 0 2 E E \ u 0 3 0 0 - \ u 0 3 7 4 \ u 0 3 7 6 \ u 0 3 7 7 \ u 0 3 7 A - \ u 0 3 7 D \ u 0 3 7 F \ u 0 3 8 6 - \ u 0 3 8 A \ u 0 3 8 C \ u 0 3 8 E - \ u 0 3 A 1 \ u 0 3 A 3 - \ u 0 3 F 5 \ u 0 3 F 7 - \ u 0 4 8 1 \ u 0 4 8 3 - \ u 0 4 8 7 \ u 0 4 8 A - \ u 0 5 2 F \ u 0 5 3 1 - \ u 0 5 5 6 \ u 0 5 5 9 \ u 0 5 6 1 - \ u 0 5 8 7 \ u 0 5 9 1 - \ u 0 5 B D \ u 0 5 B F \ u 0 5 C 1 \ u 0 5 C 2 \ u 0 5 C 4 \ u 0 5 C 5 \ u 0 5 C 7 \ u 0 5 D 0 - \ u 0 5 E A \ u 0 5 F 0 - \ u 0 5 F 2 \ u 0 6 1 0 - \ u 0 6 1 A \ u 0 6 2 0 - \ u 0 6 6 9 \ u 0 6 6 E - \ u 0 6 D 3 \ u 0 6 D 5 - \ u 0 6 D C \ u 0 6 D F - \ u 0 6 E 8 \ u 0 6 E A - \ u 0 6 F C \ u 0 6 F F \ u 0 7 1 0 - \ u 0 7 4 A \ u 0 7 4 D - \ u 0 7 B 1 \ u 0 7 C 0 - \ u 0 7 F 5 \ u 0 7 F A \ u 0 8 0 0 - \ u 0 8 2 D \ u 0 8 4 0 - \ u 0 8 5 B \ u 0 8 A 0 - \ u 0 8 B 4 \ u 0 8 E 3 - \ u 0 9 6 3 \ u 0 9 6 6 - \ u 0 9 6 F \ u 0 9 7 1 - \ u 0 9 8 3 \ u 0 9 8 5 - \ u 0 9 8 C \ u 0 9 8 F \ u 0 9 9 0 \ u 0 9 9 3 - \ u 0 9 A 8 \ u 0 9 A A - \ u 0 9 B 0 \ u 0 9 B 2 \ u 0 9 B 6 - \ u 0 9 B 9 \ u 0 9 B C - \ u 0 9 C 4 \ u 0 9 C 7 \ u 0 9 C 8 \ u 0 9 C B - \ u 0 9 C E \ u 0 9 D 7 \ u 0 9 D C \ u 0 9 D D \ u 0 9 D F - \ u 0 9 E 3 \ u 0 9 E 6 - \ u 0 9 F 1 \ u 0 A 0 1 - \ u 0 A 0 3 \ u 0 A 0 5 - \ u 0 A 0 A \ u 0 A 0 F \ u 0 A 1 0 \ u 0 A 1 3 - \ u 0 A 2 8 \ u 0 A 2 A - \ u 0 A 3 0 \ u 0 A 3 2 \ u 0 A 3 3 \ u 0 A 3 5 \ u 0 A 3 6 \ u 0 A 3 8 \ u 0 A 3 9 \ u 0 A 3 C \ u 0 A 3 E - \ u 0 A 4 2 \ u 0 A 4 7 \ u 0 A 4 8 \ u 0 A 4 B - \ u 0 A 4 D \ u 0 A 5 1 \ u 0 A 5 9 - \ u 0 A 5 C \ u 0 A 5 E \ u 0 A 6 6 - \ u 0 A 7 5 \ u 0 A 8 1 - \ u 0 A 8 3 \ u 0 A 8 5 - \ u 0 A 8 D \ u 0 A 8 F - \ u 0 A 9 1 \ u 0 A 9 3 - \ u 0 A A 8 \ u 0 A A A - \ u 0 A B 0 \ u 0 A B 2 \ u 0 A B 3 \ u 0 A B 5 - \ u 0 A B 9 \ u 0 A B C - \ u 0 A C 5 \ u 0 A C 7 - \ u 0 A C 9 \ u 0 A C B - \ u 0 A C D \ u 0 A D 0 \ u 0 A E 0 - \ u 0 A E 3 \ u 0 A E 6 - \ u 0 A E F \ u 0 A F 9 \ u 0 B 0 1 - \ u 0 B 0 3 \ u 0 B 0 5 - \ u 0 B 0 C \ u 0 B 0 F \ u 0 B 1 0 \ u 0 B 1 3 - \ u 0 B 2 8 \ u 0 B 2 A - \ u 0 B 3 0 \ u 0 B 3 2 \ u 0 B 3 3 \ u 0 B 3 5 - \ u 0 B 3 9 \ u 0 B 3 C - \ u 0 B 4 4 \ u 0 B 4 7 \ u 0 B 4 8 \ u 0 B 4 B - \ u 0 B 4 D \ u 0 B 5 6 \ u 0 B 5 7 \ u 0 B 5 C \ u 0 B 5 D \ u 0 B 5 F - \ u 0 B 6 3 \ u 0 B 6 6 - \ u 0 B 6 F \ u 0 B 7 1 \ u 0 B 8 2 \ u 0 B 8 3 \ u 0 B 8 5 - \ u 0 B 8 A \ u 0 B 8 E - \ u 0 B 9 0 \ u 0 B 9 2 - \ u 0 B 9 5 \ u 0 B 9 9 \ u 0 B 9 A \ u 0 B 9 C \ u 0 B 9 E \ u 0 B 9 F \ u 0 B A 3 \ u 0 B A 4 \ u 0 B A 8 - \ u 0 B A A \ u 0 B A E - \ u 0 B B 9 \ u 0 B B E - \ u 0 B C 2 \ u 0 B C 6 - \ u 0 B C 8 \ u 0 B C A - \ u 0 B C D \ u 0 B D 0 \ u 0 B D 7 \ u 0 B E 6 - \ u 0 B E F \ u 0 C 0 0 - \ u 0 C 0 3 \ u 0 C 0 5 - \ u 0 C 0 C \ u 0 C 0 E - \ u 0 C 1 0 \ u 0 C 1 2 - \ u 0 C 2 8 \ u 0 C 2 A - \ u 0 C 3 9 \ u 0 C 3 D - \ u 0 C 4 4 \ u 0 C 4 6 - \ u 0 C 4 8 \ u 0 C 4 A - \ u 0 C 4 D \ u 0 C 5 5 \ u 0 C 5 6 \ u 0 C 5 8 - \ u 0 C 5 A \ u 0 C 6 0 - \ u 0 C 6 3 \ u 0 C 6 6 - \ u 0 C 6 F \ u 0 C 8 1 - \ u 0 C 8 3 \ u 0 C 8 5 - \ u 0 C 8 C \ u 0 C 8 E - \ u 0 C 9 0 \ u 0 C 9 2 - \ u 0 C A 8 \ u 0 C A A - \ u 0 C B 3 \ u 0 C B 5 - \ u 0 C B 9 \ u 0 C B C - \ u 0 C C 4 \ u 0 C C 6 - \ u 0 C C 8 \ u 0 C C A - \ u 0 C C D \ u 0 C D 5 \ u 0 C D 6 \ u 0 C D E \ u 0 C E 0 - \ u 0 C E 3 \ u 0 C E 6 - \ u 0 C E F \ u 0 C F 1 \ u 0 C F 2 \ u 0 D 0 1 - \ u 0 D 0 3 \ u 0 D 0 5 - \ u 0 D 0 C \ u 0 D 0 E - \ u 0 D 1 0 \ u 0 D 1 2 - \ u 0 D 3 A \ u 0 D 3 D - \ u 0 D 4 4 \ u 0 D 4 6 - \ u 0 D 4 8 \ u 0 D 4 A - \ u 0 D 4 E \ u 0 D 5 7 \ u 0 D 5 F - \ u 0 D 6 3 \ u 0 D 6 6 - \ u 0 D 6 F \ u 0 D 7 A - \ u 0 D 7 F \ u 0 D 8 2 \ u 0 D 8 3 \ u 0 D 8 5 - \ u 0 D 9 6 \ u 0 D 9 A - \ u 0 D B 1 \ u 0 D B 3 - \ u 0 D B B \ u 0 D B D \ u 0 D C 0 - \ u 0 D C 6 \ u 0 D C A \ u 0 D C F - \ u 0 D D 4 \ u 0 D D 6 \ u 0 D D 8 - \ u 0 D D F \ u 0 D E 6 - \ u 0 D E F \ u 0 D F 2 \ u 0 D F 3 \ u 0 E 0 1 - \ u 0 E 3 A \ u 0 E 4 0 - \ u 0 E 4 E \ u 0 E 5 0 - \ u 0 E 5 9 \ u 0 E 8 1 \ u 0 E 8 2 \ u 0 E 8 4 \ u 0 E 8 7 \ u 0 E 8 8 \ u 0 E 8 A \ u 0 E 8 D \ u 0 E 9 4 - \ u 0 E 9 7 \ u 0 E 9 9 - \ u 0 E 9 F \ u 0 E A 1 - \ u 0 E A 3 \ u 0 E A 5 \ u 0 E A 7 \ u 0 E A A \ u 0 E A B \ u 0 E A D - \ u 0 E B 9 \ u 0 E B B - \ u 0 E B D \ u 0 E C 0 - \ u 0 E C 4 \ u 0 E C 6 \ u 0 E C 8 - \ u 0 E C D \ u 0 E D 0 - \ u 0 E D 9 \ u 0 E D C - \ u 0 E D F \ u 0 F 0 0 \ u 0 F 1 8 \ u 0 F 1 9 \ u 0 F 2 0 - \ u 0 F 2 9 \ u 0 F 3 5 \ u 0 F 3 7 \ u 0 F 3 9 \ u 0 F 3 E - \ u 0 F 4 7 \ u 0 F 4 9 - \ u 0 F 6 C \ u 0 F 7 1 - \ u 0 F 8 4 \ u 0 F 8 6 - \ u 0 F 9 7 \ u 0 F 9 9 - \ u 0 F B C \ u 0 F C 6 \ u 1 0 0 0 - \ u 1 0 4 9 \ u 1 0 5 0 - \ u 1 0 9 D \ u 1 0 A 0 - \ u 1 0 C 5 \ u 1 0 C 7 \ u 1 0 C D \ u 1 0 D 0 - \ u 1 0 F A \ u 1 0 F C - \ u 1 2 4 8 \ u 1 2 4 A - \ u 1 2 4 D \ u 1 2 5 0 - \ u 1 2 5 6 \ u 1 2 5 8 \ u 1 2 5 A - \ u 1 2 5 D \ u 1 2 6 0 - \ u 1 2 8 8 \ u 1 2 8 A - \ u 1 2 8 D \ u 1 2 9 0 - \ u 1 2 B 0 \ u 1 2 B 2 - \ u 1 2 B 5 \ u 1 2 B 8 - \ u 1 2 B E \ u 1 2 C 0 \ u 1 2 C 2 - \ u 1 2 C 5 \ u 1 2 C 8 - \ u 1 2 D 6 \ u 1 2 D 8 - \ u 1 3 1 0 \ u 1 3 1 2 - \ u 1 3 1 5 \ u 1 3 1 8 - \ u 1 3 5 A \ u 1 3 5 D - \ u 1 3 5 F \ u 1 3 6 9 - \ u 1 3 7 1 \ u 1 3 8 0 - \ u 1 3 8 F \ u 1 3 A 0 - \ u 1 3 F 5 \ u 1 3 F 8 - \ u 1 3 F D \ u 1 4 0 1 - \ u 1 6 6 C \ u 1 6 6 F - \ u 1 6 7 F \ u 1 6 8 1 - \ u 1 6 9 A \ u 1 6 A 0 - \ u 1 6 E A \ u 1 6 E E - \ u 1 6 F 8 \ u 1 7 0 0 - \ u 1 7 0 C \ u 1 7 0 E - \ u 1 7 1 4 \ u 1 7 2 0 - \ u 1 7 3 4 \ u 1 7 4 0 - \ u 1 7 5 3 \ u 1 7 6 0 - \ u 1 7 6 C \ u 1 7 6 E - \ u 1 7 7 0 \ u 1 7 7 2 \ u 1 7 7 3 \ u 1 7 8 0 - \ u 1 7 D 3 \ u 1 7 D 7 \ u 1 7 D C \ u 1 7 D D \ u 1 7 E 0 - \ u 1 7 E 9 \ u 1 8 0 B - \ u 1 8 0 D \ u 1 8 1 0 - \ u 1 8 1 9 \ u 1 8 2 0 - \ u 1 8 7 7 \ u 1 8 8 0 - \ u 1 8 A A \ u 1 8 B 0 - \ u 1 8 F 5 \ u 1 9 0 0 - \ u 1 9 1 E \ u 1 9 2 0 - \ u 1 9 2 B \ u 1 9 3 0 - \ u 1 9 3 B \ u 1 9 4 6 - \ u 1 9 6 D \ u 1 9 7 0 - \ u 1 9 7 4 \ u 1 9 8 0 - \ u 1 9 A B \ u 1 9 B 0 - \ u 1 9 C 9 \ u 1 9 D 0 - \ u 1 9 D A \ u 1 A 0 0 - \ u 1 A 1 B \ u 1 A 2 0 - \ u 1 A 5 E \ u 1 A 6 0 - \ u 1 A 7 C \ u 1 A 7 F - \ u 1 A 8 9 \ u 1 A 9 0 - \ u 1 A 9 9 \ u 1 A A 7 \ u 1 A B 0 - \ u 1 A B D \ u 1 B 0 0 - \ u 1 B 4 B \ u 1 B 5 0 - \ u 1 B 5 9 \ u 1 B 6 B - \ u 1 B 7 3 \ u 1 B 8 0 - \ u 1 B F 3 \ u 1 C 0 0 - \ u 1 C 3 7 \ u 1 C 4 0 - \ u 1 C 4 9 \ u 1 C 4 D - \ u 1 C 7 D \ u 1 C D 0 - \ u 1 C D 2 \ u 1 C D 4 - \ u 1 C F 6 \ u 1 C F 8 \ u 1 C F 9 \ u 1 D 0 0 - \ u 1 D F 5 \ u 1 D F C - \ u 1 F 1 5 \ u 1 F 1 8 - \ u 1 F 1 D \ u 1 F 2 0 - \ u 1 F 4 5 \ u 1 F 4 8 - \ u 1 F 4 D \ u 1 F 5 0 - \ u 1 F 5 7 \ u 1 F 5 9 \ u 1 F 5 B \ u 1 F 5 D \ u 1 F 5 F - \ u 1 F 7 D \ u 1 F 8 0 - \ u 1 F B 4 \ u 1 F B 6 - \ u 1 F B C \ u 1 F B E \ u 1 F C 2 - \ u 1 F C 4 \ u 1 F C 6 - \ u 1 F C C \ u 1 F D 0 - \ u 1 F D 3 \ u 1 F D 6 - \ u 1 F D B \ u 1 F E 0 - \ u 1 F E C \ u 1 F F 2 - \ u 1 F F 4 \ u 1 F F 6 - \ u 1 F F C \ u 2 0 0 C \ u 2 0 0 D \ u 2 0 3 F \ u 2 0 4 0 \ u 2 0 5 4 \ u 2 0 7 1 \ u 2 0 7 F \ u 2 0 9 0 - \ u 2 0 9 C \ u 2 0 D 0 - \ u 2 0 D C \ u 2 0 E 1 \ u 2 0 E 5 - \ u 2 0 F 0 \ u 2 1 0 2 \ u 2 1 0 7 \ u 2 1 0 A - \ u 2 1 1 3 \ u 2 1 1 5 \ u 2 1 1 8 - \ u 2 1 1 D \ u 2 1 2 4 \ u 2 1 2 6 \ u 2 1 2 8 \ u 2 1 2 A - \ u 2 1 3 9 \ u 2 1 3 C - \ u 2 1 3 F \ u 2 1 4 5 - \ u 2 1 4 9 \ u 2 1 4 E \ u 2 1 6 0 - \ u 2 1 8 8 \ u 2 C 0 0 - \ u 2 C 2 E \ u 2 C 3 0 - \ u 2 C 5 E \ u 2 C 6 0 - \ u 2 C E 4 \ u 2 C E B - \ u 2 C F 3 \ u 2 D 0 0 - \ u 2 D 2 5 \ u 2 D 2 7 \ u 2 D 2 D \ u 2 D 3 0 - \ u 2 D 6 7 \ u 2 D 6 F \ u 2 D 7 F - \ u 2 D 9 6 \ u 2 D A 0 - \ u 2 D A 6 \ u 2 D A 8 - \ u 2 D A E \ u 2 D B 0 - \ u 2 D B 6 \ u 2 D B 8 - \ u 2 D B E \ u 2 D C 0 - \ u 2 D C 6 \ u 2 D C 8 - \ u 2 D C E \ u 2 D D 0 - \ u 2 D D 6 \ u 2 D D 8 - \ u 2 D D E \ u 2 D E 0 - \ u 2 D F F \ u 3 0 0 5 - \ u 3 0 0 7 \ u 3 0 2 1 - \ u 3 0 2 F \ u 3 0 3 1 - \ u 3 0 3 5 \ u 3 0 3 8 - \ u 3 0 3 C \ u 3 0 4 1 - \ u 3 0 9 6 \ u 3 0 9 9 - \ u 3 0 9 F \ u 3 0 A 1 - \ u 3 0 F A \ u 3 0 F C - \ u 3 0 F F \ u 3 1 0 5 - \ u 3 1 2 D \ u 3 1 3 1 - \ u 3 1 8 E \ u 3 1 A 0 - \ u 3 1 B A \ u 3 1 F 0 - \ u 3 1 F F
} ;
function get _full _char ( str , pos ) {
if ( is _surrogate _pair _head ( str . charCodeAt ( pos ) ) ) {
if ( is _surrogate _pair _tail ( str . charCodeAt ( pos + 1 ) ) ) {
return str . charAt ( pos ) + str . charAt ( pos + 1 ) ;
}
} else if ( is _surrogate _pair _tail ( str . charCodeAt ( pos ) ) ) {
if ( is _surrogate _pair _head ( str . charCodeAt ( pos - 1 ) ) ) {
return str . charAt ( pos - 1 ) + str . charAt ( pos ) ;
}
}
return str . charAt ( pos ) ;
}
function get _full _char _code ( str , pos ) {
// https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
if ( is _surrogate _pair _head ( str . charCodeAt ( pos ) ) ) {
return 0x10000 + ( str . charCodeAt ( pos ) - 0xd800 << 10 ) + str . charCodeAt ( pos + 1 ) - 0xdc00 ;
}
return str . charCodeAt ( pos ) ;
}
function get _full _char _length ( str ) {
var surrogates = 0 ;
for ( var i = 0 ; i < str . length ; i ++ ) {
if ( is _surrogate _pair _head ( str . charCodeAt ( i ) ) && is _surrogate _pair _tail ( str . charCodeAt ( i + 1 ) ) ) {
surrogates ++ ;
i ++ ;
}
}
return str . length - surrogates ;
}
function from _char _code ( code ) {
// Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
if ( code > 0xFFFF ) {
code -= 0x10000 ;
return ( String . fromCharCode ( ( code >> 10 ) + 0xD800 ) +
String . fromCharCode ( ( code % 0x400 ) + 0xDC00 ) ) ;
}
return String . fromCharCode ( code ) ;
}
function is _surrogate _pair _head ( code ) {
return code >= 0xd800 && code <= 0xdbff ;
}
function is _surrogate _pair _tail ( code ) {
return code >= 0xdc00 && code <= 0xdfff ;
}
function is _digit ( code ) {
return code >= 48 && code <= 57 ;
}
function is _identifier _start ( ch ) {
return UNICODE . ID _Start . test ( ch ) ;
}
function is _identifier _char ( ch ) {
return UNICODE . ID _Continue . test ( ch ) ;
}
const BASIC _IDENT = /^[a-z_$][a-z0-9_$]*$/i ;
function is _basic _identifier _string ( str ) {
return BASIC _IDENT . test ( str ) ;
}
function is _identifier _string ( str , allow _surrogates ) {
if ( BASIC _IDENT . test ( str ) ) {
return true ;
}
if ( ! allow _surrogates && /[\ud800-\udfff]/ . test ( str ) ) {
return false ;
}
var match = UNICODE . ID _Start . exec ( str ) ;
if ( ! match || match . index !== 0 ) {
return false ;
}
str = str . slice ( match [ 0 ] . length ) ;
if ( ! str ) {
return true ;
}
match = UNICODE . ID _Continue . exec ( str ) ;
return ! ! match && match [ 0 ] . length === str . length ;
}
function parse _js _number ( num , allow _e = true ) {
if ( ! allow _e && num . includes ( "e" ) ) {
return NaN ;
}
if ( RE _HEX _NUMBER . test ( num ) ) {
return parseInt ( num . substr ( 2 ) , 16 ) ;
} else if ( RE _OCT _NUMBER . test ( num ) ) {
return parseInt ( num . substr ( 1 ) , 8 ) ;
} else if ( RE _ES6 _OCT _NUMBER . test ( num ) ) {
return parseInt ( num . substr ( 2 ) , 8 ) ;
} else if ( RE _BIN _NUMBER . test ( num ) ) {
return parseInt ( num . substr ( 2 ) , 2 ) ;
} else if ( RE _DEC _NUMBER . test ( num ) ) {
return parseFloat ( num ) ;
} else {
var val = parseFloat ( num ) ;
if ( val == num ) return val ;
}
}
class JS _Parse _Error extends Error {
constructor ( message , filename , line , col , pos ) {
super ( ) ;
this . name = "SyntaxError" ;
this . message = message ;
this . filename = filename ;
this . line = line ;
this . col = col ;
this . pos = pos ;
}
}
function js _error ( message , filename , line , col , pos ) {
throw new JS _Parse _Error ( message , filename , line , col , pos ) ;
}
function is _token ( token , type , val ) {
return token . type == type && ( val == null || token . value == val ) ;
}
var EX _EOF = { } ;
function tokenizer ( $TEXT , filename , html5 _comments , shebang ) {
var S = {
text : $TEXT ,
filename : filename ,
pos : 0 ,
tokpos : 0 ,
line : 1 ,
tokline : 0 ,
col : 0 ,
tokcol : 0 ,
newline _before : false ,
regex _allowed : false ,
brace _counter : 0 ,
template _braces : [ ] ,
comments _before : [ ] ,
directives : { } ,
directive _stack : [ ]
} ;
function peek ( ) { return get _full _char ( S . text , S . pos ) ; }
// Used because parsing ?. involves a lookahead for a digit
function is _option _chain _op ( ) {
const must _be _dot = S . text . charCodeAt ( S . pos + 1 ) === 46 ;
if ( ! must _be _dot ) return false ;
const cannot _be _digit = S . text . charCodeAt ( S . pos + 2 ) ;
return cannot _be _digit < 48 || cannot _be _digit > 57 ;
}
function next ( signal _eof , in _string ) {
var ch = get _full _char ( S . text , S . pos ++ ) ;
if ( signal _eof && ! ch )
throw EX _EOF ;
if ( NEWLINE _CHARS . has ( ch ) ) {
S . newline _before = S . newline _before || ! in _string ;
++ S . line ;
S . col = 0 ;
if ( ch == "\r" && peek ( ) == "\n" ) {
// treat a \r\n sequence as a single \n
++ S . pos ;
ch = "\n" ;
}
} else {
if ( ch . length > 1 ) {
++ S . pos ;
++ S . col ;
}
++ S . col ;
}
return ch ;
}
function forward ( i ) {
while ( i -- ) next ( ) ;
}
function looking _at ( str ) {
return S . text . substr ( S . pos , str . length ) == str ;
}
function find _eol ( ) {
var text = S . text ;
for ( var i = S . pos , n = S . text . length ; i < n ; ++ i ) {
var ch = text [ i ] ;
if ( NEWLINE _CHARS . has ( ch ) )
return i ;
}
return - 1 ;
}
function find ( what , signal _eof ) {
var pos = S . text . indexOf ( what , S . pos ) ;
if ( signal _eof && pos == - 1 ) throw EX _EOF ;
return pos ;
}
function start _token ( ) {
S . tokline = S . line ;
S . tokcol = S . col ;
S . tokpos = S . pos ;
}
var prev _was _dot = false ;
var previous _token = null ;
function token ( type , value , is _comment ) {
S . regex _allowed = ( ( type == "operator" && ! UNARY _POSTFIX . has ( value ) ) ||
( type == "keyword" && KEYWORDS _BEFORE _EXPRESSION . has ( value ) ) ||
( type == "punc" && PUNC _BEFORE _EXPRESSION . has ( value ) ) ) ||
( type == "arrow" ) ;
if ( type == "punc" && ( value == "." || value == "?." ) ) {
prev _was _dot = true ;
} else if ( ! is _comment ) {
prev _was _dot = false ;
}
const line = S . tokline ;
const col = S . tokcol ;
const pos = S . tokpos ;
const nlb = S . newline _before ;
const file = filename ;
let comments _before = [ ] ;
let comments _after = [ ] ;
if ( ! is _comment ) {
comments _before = S . comments _before ;
comments _after = S . comments _before = [ ] ;
}
S . newline _before = false ;
const tok = new AST _Token ( type , value , line , col , pos , nlb , comments _before , comments _after , file ) ;
if ( ! is _comment ) previous _token = tok ;
return tok ;
}
function skip _whitespace ( ) {
while ( WHITESPACE _CHARS . has ( peek ( ) ) )
next ( ) ;
}
function read _while ( pred ) {
var ret = "" , ch , i = 0 ;
while ( ( ch = peek ( ) ) && pred ( ch , i ++ ) )
ret += next ( ) ;
return ret ;
}
function parse _error ( err ) {
js _error ( err , filename , S . tokline , S . tokcol , S . tokpos ) ;
}
function read _num ( prefix ) {
var has _e = false , after _e = false , has _x = false , has _dot = prefix == "." , is _big _int = false , numeric _separator = false ;
var num = read _while ( function ( ch , i ) {
if ( is _big _int ) return false ;
var code = ch . charCodeAt ( 0 ) ;
switch ( code ) {
case 95 : // _
return ( numeric _separator = true ) ;
case 98 : case 66 : // bB
return ( has _x = true ) ; // Can occur in hex sequence, don't return false yet
case 111 : case 79 : // oO
case 120 : case 88 : // xX
return has _x ? false : ( has _x = true ) ;
case 101 : case 69 : // eE
return has _x ? true : has _e ? false : ( has _e = after _e = true ) ;
case 45 : // -
return after _e || ( i == 0 && ! prefix ) ;
case 43 : // +
return after _e ;
case ( after _e = false , 46 ) : // .
return ( ! has _dot && ! has _x && ! has _e ) ? ( has _dot = true ) : false ;
}
if ( ch === "n" ) {
is _big _int = true ;
return true ;
}
return RE _NUM _LITERAL . test ( ch ) ;
} ) ;
if ( prefix ) num = prefix + num ;
LATEST _RAW = num ;
if ( RE _OCT _NUMBER . test ( num ) && next _token . has _directive ( "use strict" ) ) {
parse _error ( "Legacy octal literals are not allowed in strict mode" ) ;
}
if ( numeric _separator ) {
if ( num . endsWith ( "_" ) ) {
parse _error ( "Numeric separators are not allowed at the end of numeric literals" ) ;
} else if ( num . includes ( "__" ) ) {
parse _error ( "Only one underscore is allowed as numeric separator" ) ;
}
num = num . replace ( /_/g , "" ) ;
}
if ( num . endsWith ( "n" ) ) {
const without _n = num . slice ( 0 , - 1 ) ;
const allow _e = RE _HEX _NUMBER . test ( without _n ) ;
const valid = parse _js _number ( without _n , allow _e ) ;
if ( ! has _dot && RE _BIG _INT . test ( num ) && ! isNaN ( valid ) )
return token ( "big_int" , without _n ) ;
parse _error ( "Invalid or unexpected token" ) ;
}
var valid = parse _js _number ( num ) ;
if ( ! isNaN ( valid ) ) {
return token ( "num" , valid ) ;
} else {
parse _error ( "Invalid syntax: " + num ) ;
}
}
function is _octal ( ch ) {
return ch >= "0" && ch <= "7" ;
}
function read _escaped _char ( in _string , strict _hex , template _string ) {
var ch = next ( true , in _string ) ;
switch ( ch . charCodeAt ( 0 ) ) {
case 110 : return "\n" ;
case 114 : return "\r" ;
case 116 : return "\t" ;
case 98 : return "\b" ;
case 118 : return "\u000b" ; // \v
case 102 : return "\f" ;
case 120 : return String . fromCharCode ( hex _bytes ( 2 , strict _hex ) ) ; // \x
case 117 : // \u
if ( peek ( ) == "{" ) {
next ( true ) ;
if ( peek ( ) === "}" )
parse _error ( "Expecting hex-character between {}" ) ;
while ( peek ( ) == "0" ) next ( true ) ; // No significance
var result , length = find ( "}" , true ) - S . pos ;
// Avoid 32 bit integer overflow (1 << 32 === 1)
// We know first character isn't 0 and thus out of range anyway
if ( length > 6 || ( result = hex _bytes ( length , strict _hex ) ) > 0x10FFFF ) {
parse _error ( "Unicode reference out of bounds" ) ;
}
next ( true ) ;
return from _char _code ( result ) ;
}
return String . fromCharCode ( hex _bytes ( 4 , strict _hex ) ) ;
case 10 : return "" ; // newline
case 13 : // \r
if ( peek ( ) == "\n" ) { // DOS newline
next ( true , in _string ) ;
return "" ;
}
}
if ( is _octal ( ch ) ) {
if ( template _string && strict _hex ) {
const represents _null _character = ch === "0" && ! is _octal ( peek ( ) ) ;
if ( ! represents _null _character ) {
parse _error ( "Octal escape sequences are not allowed in template strings" ) ;
}
}
return read _octal _escape _sequence ( ch , strict _hex ) ;
}
return ch ;
}
function read _octal _escape _sequence ( ch , strict _octal ) {
// Read
var p = peek ( ) ;
if ( p >= "0" && p <= "7" ) {
ch += next ( true ) ;
if ( ch [ 0 ] <= "3" && ( p = peek ( ) ) >= "0" && p <= "7" )
ch += next ( true ) ;
}
// Parse
if ( ch === "0" ) return "\0" ;
if ( ch . length > 0 && next _token . has _directive ( "use strict" ) && strict _octal )
parse _error ( "Legacy octal escape sequences are not allowed in strict mode" ) ;
return String . fromCharCode ( parseInt ( ch , 8 ) ) ;
}
function hex _bytes ( n , strict _hex ) {
var num = 0 ;
for ( ; n > 0 ; -- n ) {
if ( ! strict _hex && isNaN ( parseInt ( peek ( ) , 16 ) ) ) {
return parseInt ( num , 16 ) || "" ;
}
var digit = next ( true ) ;
if ( isNaN ( parseInt ( digit , 16 ) ) )
parse _error ( "Invalid hex-character pattern in string" ) ;
num += digit ;
}
return parseInt ( num , 16 ) ;
}
var read _string = with _eof _error ( "Unterminated string constant" , function ( ) {
const start _pos = S . pos ;
var quote = next ( ) , ret = [ ] ;
for ( ; ; ) {
var ch = next ( true , true ) ;
if ( ch == "\\" ) ch = read _escaped _char ( true , true ) ;
else if ( ch == "\r" || ch == "\n" ) parse _error ( "Unterminated string constant" ) ;
else if ( ch == quote ) break ;
ret . push ( ch ) ;
}
var tok = token ( "string" , ret . join ( "" ) ) ;
LATEST _RAW = S . text . slice ( start _pos , S . pos ) ;
tok . quote = quote ;
return tok ;
} ) ;
var read _template _characters = with _eof _error ( "Unterminated template" , function ( begin ) {
if ( begin ) {
S . template _braces . push ( S . brace _counter ) ;
}
var content = "" , raw = "" , ch , tok ;
next ( true , true ) ;
while ( ( ch = next ( true , true ) ) != "`" ) {
if ( ch == "\r" ) {
if ( peek ( ) == "\n" ) ++ S . pos ;
ch = "\n" ;
} else if ( ch == "$" && peek ( ) == "{" ) {
next ( true , true ) ;
S . brace _counter ++ ;
tok = token ( begin ? "template_head" : "template_substitution" , content ) ;
LATEST _RAW = raw ;
LATEST _TEMPLATE _END = false ;
return tok ;
}
raw += ch ;
if ( ch == "\\" ) {
var tmp = S . pos ;
var prev _is _tag = previous _token && ( previous _token . type === "name" || previous _token . type === "punc" && ( previous _token . value === ")" || previous _token . value === "]" ) ) ;
ch = read _escaped _char ( true , ! prev _is _tag , true ) ;
raw += S . text . substr ( tmp , S . pos - tmp ) ;
}
content += ch ;
}
S . template _braces . pop ( ) ;
tok = token ( begin ? "template_head" : "template_substitution" , content ) ;
LATEST _RAW = raw ;
LATEST _TEMPLATE _END = true ;
return tok ;
} ) ;
function skip _line _comment ( type ) {
var regex _allowed = S . regex _allowed ;
var i = find _eol ( ) , ret ;
if ( i == - 1 ) {
ret = S . text . substr ( S . pos ) ;
S . pos = S . text . length ;
} else {
ret = S . text . substring ( S . pos , i ) ;
S . pos = i ;
}
S . col = S . tokcol + ( S . pos - S . tokpos ) ;
S . comments _before . push ( token ( type , ret , true ) ) ;
S . regex _allowed = regex _allowed ;
return next _token ;
}
var skip _multiline _comment = with _eof _error ( "Unterminated multiline comment" , function ( ) {
var regex _allowed = S . regex _allowed ;
var i = find ( "*/" , true ) ;
var text = S . text . substring ( S . pos , i ) . replace ( /\r\n|\r|\u2028|\u2029/g , "\n" ) ;
// update stream position
forward ( get _full _char _length ( text ) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2 ) ;
S . comments _before . push ( token ( "comment2" , text , true ) ) ;
S . newline _before = S . newline _before || text . includes ( "\n" ) ;
S . regex _allowed = regex _allowed ;
return next _token ;
} ) ;
var read _name = with _eof _error ( "Unterminated identifier name" , function ( ) {
var name = [ ] , ch , escaped = false ;
var read _escaped _identifier _char = function ( ) {
escaped = true ;
next ( ) ;
if ( peek ( ) !== "u" ) {
parse _error ( "Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}" ) ;
}
return read _escaped _char ( false , true ) ;
} ;
// Read first character (ID_Start)
if ( ( ch = peek ( ) ) === "\\" ) {
ch = read _escaped _identifier _char ( ) ;
if ( ! is _identifier _start ( ch ) ) {
parse _error ( "First identifier char is an invalid identifier char" ) ;
}
} else if ( is _identifier _start ( ch ) ) {
next ( ) ;
} else {
return "" ;
}
name . push ( ch ) ;
// Read ID_Continue
while ( ( ch = peek ( ) ) != null ) {
if ( ( ch = peek ( ) ) === "\\" ) {
ch = read _escaped _identifier _char ( ) ;
if ( ! is _identifier _char ( ch ) ) {
parse _error ( "Invalid escaped identifier char" ) ;
}
} else {
if ( ! is _identifier _char ( ch ) ) {
break ;
}
next ( ) ;
}
name . push ( ch ) ;
}
const name _str = name . join ( "" ) ;
if ( RESERVED _WORDS . has ( name _str ) && escaped ) {
parse _error ( "Escaped characters are not allowed in keywords" ) ;
}
return name _str ;
} ) ;
var read _regexp = with _eof _error ( "Unterminated regular expression" , function ( source ) {
var prev _backslash = false , ch , in _class = false ;
while ( ( ch = next ( true ) ) ) if ( NEWLINE _CHARS . has ( ch ) ) {
parse _error ( "Unexpected line terminator" ) ;
} else if ( prev _backslash ) {
source += "\\" + ch ;
prev _backslash = false ;
} else if ( ch == "[" ) {
in _class = true ;
source += ch ;
} else if ( ch == "]" && in _class ) {
in _class = false ;
source += ch ;
} else if ( ch == "/" && ! in _class ) {
break ;
} else if ( ch == "\\" ) {
prev _backslash = true ;
} else {
source += ch ;
}
const flags = read _name ( ) ;
return token ( "regexp" , "/" + source + "/" + flags ) ;
} ) ;
function read _operator ( prefix ) {
function grow ( op ) {
if ( ! peek ( ) ) return op ;
var bigger = op + peek ( ) ;
if ( OPERATORS . has ( bigger ) ) {
next ( ) ;
return grow ( bigger ) ;
} else {
return op ;
}
}
return token ( "operator" , grow ( prefix || next ( ) ) ) ;
}
function handle _slash ( ) {
next ( ) ;
switch ( peek ( ) ) {
case "/" :
next ( ) ;
return skip _line _comment ( "comment1" ) ;
case "*" :
next ( ) ;
return skip _multiline _comment ( ) ;
}
return S . regex _allowed ? read _regexp ( "" ) : read _operator ( "/" ) ;
}
function handle _eq _sign ( ) {
next ( ) ;
if ( peek ( ) === ">" ) {
next ( ) ;
return token ( "arrow" , "=>" ) ;
} else {
return read _operator ( "=" ) ;
}
}
function handle _dot ( ) {
next ( ) ;
if ( is _digit ( peek ( ) . charCodeAt ( 0 ) ) ) {
return read _num ( "." ) ;
}
if ( peek ( ) === "." ) {
next ( ) ; // Consume second dot
next ( ) ; // Consume third dot
return token ( "expand" , "..." ) ;
}
return token ( "punc" , "." ) ;
}
function read _word ( ) {
var word = read _name ( ) ;
if ( prev _was _dot ) return token ( "name" , word ) ;
return KEYWORDS _ATOM . has ( word ) ? token ( "atom" , word )
: ! KEYWORDS . has ( word ) ? token ( "name" , word )
: OPERATORS . has ( word ) ? token ( "operator" , word )
: token ( "keyword" , word ) ;
}
function read _private _word ( ) {
next ( ) ;
return token ( "privatename" , read _name ( ) ) ;
}
function with _eof _error ( eof _error , cont ) {
return function ( x ) {
try {
return cont ( x ) ;
} catch ( ex ) {
if ( ex === EX _EOF ) parse _error ( eof _error ) ;
else throw ex ;
}
} ;
}
function next _token ( force _regexp ) {
if ( force _regexp != null )
return read _regexp ( force _regexp ) ;
if ( shebang && S . pos == 0 && looking _at ( "#!" ) ) {
start _token ( ) ;
forward ( 2 ) ;
skip _line _comment ( "comment5" ) ;
}
for ( ; ; ) {
skip _whitespace ( ) ;
start _token ( ) ;
if ( html5 _comments ) {
if ( looking _at ( "<!--" ) ) {
forward ( 4 ) ;
skip _line _comment ( "comment3" ) ;
continue ;
}
if ( looking _at ( "-->" ) && S . newline _before ) {
forward ( 3 ) ;
skip _line _comment ( "comment4" ) ;
continue ;
}
}
var ch = peek ( ) ;
if ( ! ch ) return token ( "eof" ) ;
var code = ch . charCodeAt ( 0 ) ;
switch ( code ) {
case 34 : case 39 : return read _string ( ) ;
case 46 : return handle _dot ( ) ;
case 47 : {
var tok = handle _slash ( ) ;
if ( tok === next _token ) continue ;
return tok ;
}
case 61 : return handle _eq _sign ( ) ;
case 63 : {
if ( ! is _option _chain _op ( ) ) break ; // Handled below
next ( ) ; // ?
next ( ) ; // .
return token ( "punc" , "?." ) ;
}
case 96 : return read _template _characters ( true ) ;
case 123 :
S . brace _counter ++ ;
break ;
case 125 :
S . brace _counter -- ;
if ( S . template _braces . length > 0
&& S . template _braces [ S . template _braces . length - 1 ] === S . brace _counter )
return read _template _characters ( false ) ;
break ;
}
if ( is _digit ( code ) ) return read _num ( ) ;
if ( PUNC _CHARS . has ( ch ) ) return token ( "punc" , next ( ) ) ;
if ( OPERATOR _CHARS . has ( ch ) ) return read _operator ( ) ;
if ( code == 92 || is _identifier _start ( ch ) ) return read _word ( ) ;
if ( code == 35 ) return read _private _word ( ) ;
break ;
}
parse _error ( "Unexpected character '" + ch + "'" ) ;
}
next _token . next = next ;
next _token . peek = peek ;
next _token . context = function ( nc ) {
if ( nc ) S = nc ;
return S ;
} ;
next _token . add _directive = function ( directive ) {
S . directive _stack [ S . directive _stack . length - 1 ] . push ( directive ) ;
if ( S . directives [ directive ] === undefined ) {
S . directives [ directive ] = 1 ;
} else {
S . directives [ directive ] ++ ;
}
} ;
next _token . push _directives _stack = function ( ) {
S . directive _stack . push ( [ ] ) ;
} ;
next _token . pop _directives _stack = function ( ) {
var directives = S . directive _stack [ S . directive _stack . length - 1 ] ;
for ( var i = 0 ; i < directives . length ; i ++ ) {
S . directives [ directives [ i ] ] -- ;
}
S . directive _stack . pop ( ) ;
} ;
next _token . has _directive = function ( directive ) {
return S . directives [ directive ] > 0 ;
} ;
return next _token ;
}
/* -----[ Parser (constants) ]----- */
var UNARY _PREFIX = makePredicate ( [
"typeof" ,
"void" ,
"delete" ,
"--" ,
"++" ,
"!" ,
"~" ,
"-" ,
"+"
] ) ;
var UNARY _POSTFIX = makePredicate ( [ "--" , "++" ] ) ;
var ASSIGNMENT = makePredicate ( [ "=" , "+=" , "-=" , "??=" , "&&=" , "||=" , "/=" , "*=" , "**=" , "%=" , ">>=" , "<<=" , ">>>=" , "|=" , "^=" , "&=" ] ) ;
var LOGICAL _ASSIGNMENT = makePredicate ( [ "??=" , "&&=" , "||=" ] ) ;
var PRECEDENCE = ( function ( a , ret ) {
for ( var i = 0 ; i < a . length ; ++ i ) {
var b = a [ i ] ;
for ( var j = 0 ; j < b . length ; ++ j ) {
ret [ b [ j ] ] = i + 1 ;
}
}
return ret ;
} ) (
[
[ "||" ] ,
[ "??" ] ,
[ "&&" ] ,
[ "|" ] ,
[ "^" ] ,
[ "&" ] ,
[ "==" , "===" , "!=" , "!==" ] ,
[ "<" , ">" , "<=" , ">=" , "in" , "instanceof" ] ,
[ ">>" , "<<" , ">>>" ] ,
[ "+" , "-" ] ,
[ "*" , "/" , "%" ] ,
[ "**" ]
] ,
{ }
) ;
var ATOMIC _START _TOKEN = makePredicate ( [ "atom" , "num" , "big_int" , "string" , "regexp" , "name" ] ) ;
/* -----[ Parser ]----- */
function parse ( $TEXT , options ) {
// maps start tokens to count of comments found outside of their parens
// Example: /* I count */ ( /* I don't */ foo() )
// Useful because comments_before property of call with parens outside
// contains both comments inside and outside these parens. Used to find the
// right #__PURE__ comments for an expression
const outer _comments _before _counts = new WeakMap ( ) ;
options = defaults ( options , {
bare _returns : false ,
ecma : null , // Legacy
expression : false ,
filename : null ,
html5 _comments : true ,
module : false ,
shebang : true ,
strict : false ,
toplevel : null ,
} , true ) ;
var S = {
input : ( typeof $TEXT == "string"
? tokenizer ( $TEXT , options . filename ,
options . html5 _comments , options . shebang )
: $TEXT ) ,
token : null ,
prev : null ,
peeked : null ,
in _function : 0 ,
in _async : - 1 ,
in _generator : - 1 ,
in _directives : true ,
in _loop : 0 ,
labels : [ ]
} ;
S . token = next ( ) ;
function is ( type , value ) {
return is _token ( S . token , type , value ) ;
}
function peek ( ) { return S . peeked || ( S . peeked = S . input ( ) ) ; }
function next ( ) {
S . prev = S . token ;
if ( ! S . peeked ) peek ( ) ;
S . token = S . peeked ;
S . peeked = null ;
S . in _directives = S . in _directives && (
S . token . type == "string" || is ( "punc" , ";" )
) ;
return S . token ;
}
function prev ( ) {
return S . prev ;
}
function croak ( msg , line , col , pos ) {
var ctx = S . input . context ( ) ;
js _error ( msg ,
ctx . filename ,
line != null ? line : ctx . tokline ,
col != null ? col : ctx . tokcol ,
pos != null ? pos : ctx . tokpos ) ;
}
function token _error ( token , msg ) {
croak ( msg , token . line , token . col ) ;
}
function unexpected ( token ) {
if ( token == null )
token = S . token ;
token _error ( token , "Unexpected token: " + token . type + " (" + token . value + ")" ) ;
}
function expect _token ( type , val ) {
if ( is ( type , val ) ) {
return next ( ) ;
}
token _error ( S . token , "Unexpected token " + S . token . type + " «" + S . token . value + "»" + ", expected " + type + " «" + val + "»" ) ;
}
function expect ( punc ) { return expect _token ( "punc" , punc ) ; }
function has _newline _before ( token ) {
return token . nlb || ! token . comments _before . every ( ( comment ) => ! comment . nlb ) ;
}
function can _insert _semicolon ( ) {
return ! options . strict
&& ( is ( "eof" ) || is ( "punc" , "}" ) || has _newline _before ( S . token ) ) ;
}
function is _in _generator ( ) {
return S . in _generator === S . in _function ;
}
function is _in _async ( ) {
return S . in _async === S . in _function ;
}
function can _await ( ) {
return (
S . in _async === S . in _function
|| S . in _function === 0 && S . input . has _directive ( "use strict" )
) ;
}
function semicolon ( optional ) {
if ( is ( "punc" , ";" ) ) next ( ) ;
else if ( ! optional && ! can _insert _semicolon ( ) ) unexpected ( ) ;
}
function parenthesised ( ) {
expect ( "(" ) ;
var exp = expression ( true ) ;
expect ( ")" ) ;
return exp ;
}
function embed _tokens ( parser ) {
return function _embed _tokens _wrapper ( ... args ) {
const start = S . token ;
const expr = parser ( ... args ) ;
expr . start = start ;
expr . end = prev ( ) ;
return expr ;
} ;
}
function handle _regexp ( ) {
if ( is ( "operator" , "/" ) || is ( "operator" , "/=" ) ) {
S . peeked = null ;
S . token = S . input ( S . token . value . substr ( 1 ) ) ; // force regexp
}
}
var statement = embed _tokens ( function statement ( is _export _default , is _for _body , is _if _body ) {
handle _regexp ( ) ;
switch ( S . token . type ) {
case "string" :
if ( S . in _directives ) {
var token = peek ( ) ;
if ( ! LATEST _RAW . includes ( "\\" )
&& ( is _token ( token , "punc" , ";" )
|| is _token ( token , "punc" , "}" )
|| has _newline _before ( token )
|| is _token ( token , "eof" ) ) ) {
S . input . add _directive ( S . token . value ) ;
} else {
S . in _directives = false ;
}
}
var dir = S . in _directives , stat = simple _statement ( ) ;
return dir && stat . body instanceof AST _String ? new AST _Directive ( stat . body ) : stat ;
case "template_head" :
case "num" :
case "big_int" :
case "regexp" :
case "operator" :
case "atom" :
return simple _statement ( ) ;
case "name" :
if ( S . token . value == "async" && is _token ( peek ( ) , "keyword" , "function" ) ) {
next ( ) ;
next ( ) ;
if ( is _for _body ) {
croak ( "functions are not allowed as the body of a loop" ) ;
}
return function _ ( AST _Defun , false , true , is _export _default ) ;
}
if ( S . token . value == "import" && ! is _token ( peek ( ) , "punc" , "(" ) && ! is _token ( peek ( ) , "punc" , "." ) ) {
next ( ) ;
var node = import _ ( ) ;
semicolon ( ) ;
return node ;
}
return is _token ( peek ( ) , "punc" , ":" )
? labeled _statement ( )
: simple _statement ( ) ;
case "punc" :
switch ( S . token . value ) {
case "{" :
return new AST _BlockStatement ( {
start : S . token ,
body : block _ ( ) ,
end : prev ( )
} ) ;
case "[" :
case "(" :
return simple _statement ( ) ;
case ";" :
S . in _directives = false ;
next ( ) ;
return new AST _EmptyStatement ( ) ;
default :
unexpected ( ) ;
}
case "keyword" :
switch ( S . token . value ) {
case "break" :
next ( ) ;
return break _cont ( AST _Break ) ;
case "continue" :
next ( ) ;
return break _cont ( AST _Continue ) ;
case "debugger" :
next ( ) ;
semicolon ( ) ;
return new AST _Debugger ( ) ;
case "do" :
next ( ) ;
var body = in _loop ( statement ) ;
expect _token ( "keyword" , "while" ) ;
var condition = parenthesised ( ) ;
semicolon ( true ) ;
return new AST _Do ( {
body : body ,
condition : condition
} ) ;
case "while" :
next ( ) ;
return new AST _While ( {
condition : parenthesised ( ) ,
body : in _loop ( function ( ) { return statement ( false , true ) ; } )
} ) ;
case "for" :
next ( ) ;
return for _ ( ) ;
case "class" :
next ( ) ;
if ( is _for _body ) {
croak ( "classes are not allowed as the body of a loop" ) ;
}
if ( is _if _body ) {
croak ( "classes are not allowed as the body of an if" ) ;
}
return class _ ( AST _DefClass , is _export _default ) ;
case "function" :
next ( ) ;
if ( is _for _body ) {
croak ( "functions are not allowed as the body of a loop" ) ;
}
return function _ ( AST _Defun , false , false , is _export _default ) ;
case "if" :
next ( ) ;
return if _ ( ) ;
case "return" :
if ( S . in _function == 0 && ! options . bare _returns )
croak ( "'return' outside of function" ) ;
next ( ) ;
var value = null ;
if ( is ( "punc" , ";" ) ) {
next ( ) ;
} else if ( ! can _insert _semicolon ( ) ) {
value = expression ( true ) ;
semicolon ( ) ;
}
return new AST _Return ( {
value : value
} ) ;
case "switch" :
next ( ) ;
return new AST _Switch ( {
expression : parenthesised ( ) ,
body : in _loop ( switch _body _ )
} ) ;
case "throw" :
next ( ) ;
if ( has _newline _before ( S . token ) )
croak ( "Illegal newline after 'throw'" ) ;
var value = expression ( true ) ;
semicolon ( ) ;
return new AST _Throw ( {
value : value
} ) ;
case "try" :
next ( ) ;
return try _ ( ) ;
case "var" :
next ( ) ;
var node = var _ ( ) ;
semicolon ( ) ;
return node ;
case "let" :
next ( ) ;
var node = let _ ( ) ;
semicolon ( ) ;
return node ;
case "const" :
next ( ) ;
var node = const _ ( ) ;
semicolon ( ) ;
return node ;
case "with" :
if ( S . input . has _directive ( "use strict" ) ) {
croak ( "Strict mode may not include a with statement" ) ;
}
next ( ) ;
return new AST _With ( {
expression : parenthesised ( ) ,
body : statement ( )
} ) ;
case "export" :
if ( ! is _token ( peek ( ) , "punc" , "(" ) ) {
next ( ) ;
var node = export _ ( ) ;
if ( is ( "punc" , ";" ) ) semicolon ( ) ;
return node ;
}
}
}
unexpected ( ) ;
} ) ;
function labeled _statement ( ) {
var label = as _symbol ( AST _Label ) ;
if ( label . name === "await" && is _in _async ( ) ) {
token _error ( S . prev , "await cannot be used as label inside async function" ) ;
}
if ( S . labels . some ( ( l ) => l . name === label . name ) ) {
// ECMA-262, 12.12: An ECMAScript program is considered
// syntactically incorrect if it contains a
// LabelledStatement that is enclosed by a
// LabelledStatement with the same Identifier as label.
croak ( "Label " + label . name + " defined twice" ) ;
}
expect ( ":" ) ;
S . labels . push ( label ) ;
var stat = statement ( ) ;
S . labels . pop ( ) ;
if ( ! ( stat instanceof AST _IterationStatement ) ) {
// check for `continue` that refers to this label.
// those should be reported as syntax errors.
// https://github.com/mishoo/UglifyJS2/issues/287
label . references . forEach ( function ( ref ) {
if ( ref instanceof AST _Continue ) {
ref = ref . label . start ;
croak ( "Continue label `" + label . name + "` refers to non-IterationStatement." ,
ref . line , ref . col , ref . pos ) ;
}
} ) ;
}
return new AST _LabeledStatement ( { body : stat , label : label } ) ;
}
function simple _statement ( tmp ) {
return new AST _SimpleStatement ( { body : ( tmp = expression ( true ) , semicolon ( ) , tmp ) } ) ;
}
function break _cont ( type ) {
var label = null , ldef ;
if ( ! can _insert _semicolon ( ) ) {
label = as _symbol ( AST _LabelRef , true ) ;
}
if ( label != null ) {
ldef = S . labels . find ( ( l ) => l . name === label . name ) ;
if ( ! ldef )
croak ( "Undefined label " + label . name ) ;
label . thedef = ldef ;
} else if ( S . in _loop == 0 )
croak ( type . TYPE + " not inside a loop or switch" ) ;
semicolon ( ) ;
var stat = new type ( { label : label } ) ;
if ( ldef ) ldef . references . push ( stat ) ;
return stat ;
}
function for _ ( ) {
var for _await _error = "`for await` invalid in this context" ;
var await _tok = S . token ;
if ( await _tok . type == "name" && await _tok . value == "await" ) {
if ( ! can _await ( ) ) {
token _error ( await _tok , for _await _error ) ;
}
next ( ) ;
} else {
await _tok = false ;
}
expect ( "(" ) ;
var init = null ;
if ( ! is ( "punc" , ";" ) ) {
init =
is ( "keyword" , "var" ) ? ( next ( ) , var _ ( true ) ) :
is ( "keyword" , "let" ) ? ( next ( ) , let _ ( true ) ) :
is ( "keyword" , "const" ) ? ( next ( ) , const _ ( true ) ) :
expression ( true , true ) ;
var is _in = is ( "operator" , "in" ) ;
var is _of = is ( "name" , "of" ) ;
if ( await _tok && ! is _of ) {
token _error ( await _tok , for _await _error ) ;
}
if ( is _in || is _of ) {
if ( init instanceof AST _Definitions ) {
if ( init . definitions . length > 1 )
token _error ( init . start , "Only one variable declaration allowed in for..in loop" ) ;
} else if ( ! ( is _assignable ( init ) || ( init = to _destructuring ( init ) ) instanceof AST _Destructuring ) ) {
token _error ( init . start , "Invalid left-hand side in for..in loop" ) ;
}
next ( ) ;
if ( is _in ) {
return for _in ( init ) ;
} else {
return for _of ( init , ! ! await _tok ) ;
}
}
} else if ( await _tok ) {
token _error ( await _tok , for _await _error ) ;
}
return regular _for ( init ) ;
}
function regular _for ( init ) {
expect ( ";" ) ;
var test = is ( "punc" , ";" ) ? null : expression ( true ) ;
expect ( ";" ) ;
var step = is ( "punc" , ")" ) ? null : expression ( true ) ;
expect ( ")" ) ;
return new AST _For ( {
init : init ,
condition : test ,
step : step ,
body : in _loop ( function ( ) { return statement ( false , true ) ; } )
} ) ;
}
function for _of ( init , is _await ) {
var lhs = init instanceof AST _Definitions ? init . definitions [ 0 ] . name : null ;
var obj = expression ( true ) ;
expect ( ")" ) ;
return new AST _ForOf ( {
await : is _await ,
init : init ,
name : lhs ,
object : obj ,
body : in _loop ( function ( ) { return statement ( false , true ) ; } )
} ) ;
}
function for _in ( init ) {
var obj = expression ( true ) ;
expect ( ")" ) ;
return new AST _ForIn ( {
init : init ,
object : obj ,
body : in _loop ( function ( ) { return statement ( false , true ) ; } )
} ) ;
}
var arrow _function = function ( start , argnames , is _async ) {
if ( has _newline _before ( S . token ) ) {
croak ( "Unexpected newline before arrow (=>)" ) ;
}
expect _token ( "arrow" , "=>" ) ;
var body = _function _body ( is ( "punc" , "{" ) , false , is _async ) ;
var end =
body instanceof Array && body . length ? body [ body . length - 1 ] . end :
body instanceof Array ? start :
body . end ;
return new AST _Arrow ( {
start : start ,
end : end ,
async : is _async ,
argnames : argnames ,
body : body
} ) ;
} ;
var function _ = function ( ctor , is _generator _property , is _async , is _export _default ) {
var in _statement = ctor === AST _Defun ;
var is _generator = is ( "operator" , "*" ) ;
if ( is _generator ) {
next ( ) ;
}
var name = is ( "name" ) ? as _symbol ( in _statement ? AST _SymbolDefun : AST _SymbolLambda ) : null ;
if ( in _statement && ! name ) {
if ( is _export _default ) {
ctor = AST _Function ;
} else {
unexpected ( ) ;
}
}
if ( name && ctor !== AST _Accessor && ! ( name instanceof AST _SymbolDeclaration ) )
unexpected ( prev ( ) ) ;
var args = [ ] ;
var body = _function _body ( true , is _generator || is _generator _property , is _async , name , args ) ;
return new ctor ( {
start : args . start ,
end : body . end ,
is _generator : is _generator ,
async : is _async ,
name : name ,
argnames : args ,
body : body
} ) ;
} ;
function track _used _binding _identifiers ( is _parameter , strict ) {
var parameters = new Set ( ) ;
var duplicate = false ;
var default _assignment = false ;
var spread = false ;
var strict _mode = ! ! strict ;
var tracker = {
add _parameter : function ( token ) {
if ( parameters . has ( token . value ) ) {
if ( duplicate === false ) {
duplicate = token ;
}
tracker . check _strict ( ) ;
} else {
parameters . add ( token . value ) ;
if ( is _parameter ) {
switch ( token . value ) {
case "arguments" :
case "eval" :
case "yield" :
if ( strict _mode ) {
token _error ( token , "Unexpected " + token . value + " identifier as parameter inside strict mode" ) ;
}
break ;
default :
if ( RESERVED _WORDS . has ( token . value ) ) {
unexpected ( ) ;
}
}
}
}
} ,
mark _default _assignment : function ( token ) {
if ( default _assignment === false ) {
default _assignment = token ;
}
} ,
mark _spread : function ( token ) {
if ( spread === false ) {
spread = token ;
}
} ,
mark _strict _mode : function ( ) {
strict _mode = true ;
} ,
is _strict : function ( ) {
return default _assignment !== false || spread !== false || strict _mode ;
} ,
check _strict : function ( ) {
if ( tracker . is _strict ( ) && duplicate !== false ) {
token _error ( duplicate , "Parameter " + duplicate . value + " was used already" ) ;
}
}
} ;
return tracker ;
}
function parameters ( params ) {
var used _parameters = track _used _binding _identifiers ( true , S . input . has _directive ( "use strict" ) ) ;
expect ( "(" ) ;
while ( ! is ( "punc" , ")" ) ) {
var param = parameter ( used _parameters ) ;
params . push ( param ) ;
if ( ! is ( "punc" , ")" ) ) {
expect ( "," ) ;
}
if ( param instanceof AST _Expansion ) {
break ;
}
}
next ( ) ;
}
function parameter ( used _parameters , symbol _type ) {
var param ;
var expand = false ;
if ( used _parameters === undefined ) {
used _parameters = track _used _binding _identifiers ( true , S . input . has _directive ( "use strict" ) ) ;
}
if ( is ( "expand" , "..." ) ) {
expand = S . token ;
used _parameters . mark _spread ( S . token ) ;
next ( ) ;
}
param = binding _element ( used _parameters , symbol _type ) ;
if ( is ( "operator" , "=" ) && expand === false ) {
used _parameters . mark _default _assignment ( S . token ) ;
next ( ) ;
param = new AST _DefaultAssign ( {
start : param . start ,
left : param ,
operator : "=" ,
right : expression ( false ) ,
end : S . token
} ) ;
}
if ( expand !== false ) {
if ( ! is ( "punc" , ")" ) ) {
unexpected ( ) ;
}
param = new AST _Expansion ( {
start : expand ,
expression : param ,
end : expand
} ) ;
}
used _parameters . check _strict ( ) ;
return param ;
}
function binding _element ( used _parameters , symbol _type ) {
var elements = [ ] ;
var first = true ;
var is _expand = false ;
var expand _token ;
var first _token = S . token ;
if ( used _parameters === undefined ) {
used _parameters = track _used _binding _identifiers ( false , S . input . has _directive ( "use strict" ) ) ;
}
symbol _type = symbol _type === undefined ? AST _SymbolFunarg : symbol _type ;
if ( is ( "punc" , "[" ) ) {
next ( ) ;
while ( ! is ( "punc" , "]" ) ) {
if ( first ) {
first = false ;
} else {
expect ( "," ) ;
}
if ( is ( "expand" , "..." ) ) {
is _expand = true ;
expand _token = S . token ;
used _parameters . mark _spread ( S . token ) ;
next ( ) ;
}
if ( is ( "punc" ) ) {
switch ( S . token . value ) {
case "," :
elements . push ( new AST _Hole ( {
start : S . token ,
end : S . token
} ) ) ;
continue ;
case "]" : // Trailing comma after last element
break ;
case "[" :
case "{" :
elements . push ( binding _element ( used _parameters , symbol _type ) ) ;
break ;
default :
unexpected ( ) ;
}
} else if ( is ( "name" ) ) {
used _parameters . add _parameter ( S . token ) ;
elements . push ( as _symbol ( symbol _type ) ) ;
} else {
croak ( "Invalid function parameter" ) ;
}
if ( is ( "operator" , "=" ) && is _expand === false ) {
used _parameters . mark _default _assignment ( S . token ) ;
next ( ) ;
elements [ elements . length - 1 ] = new AST _DefaultAssign ( {
start : elements [ elements . length - 1 ] . start ,
left : elements [ elements . length - 1 ] ,
operator : "=" ,
right : expression ( false ) ,
end : S . token
} ) ;
}
if ( is _expand ) {
if ( ! is ( "punc" , "]" ) ) {
croak ( "Rest element must be last element" ) ;
}
elements [ elements . length - 1 ] = new AST _Expansion ( {
start : expand _token ,
expression : elements [ elements . length - 1 ] ,
end : expand _token
} ) ;
}
}
expect ( "]" ) ;
used _parameters . check _strict ( ) ;
return new AST _Destructuring ( {
start : first _token ,
names : elements ,
is _array : true ,
end : prev ( )
} ) ;
} else if ( is ( "punc" , "{" ) ) {
next ( ) ;
while ( ! is ( "punc" , "}" ) ) {
if ( first ) {
first = false ;
} else {
expect ( "," ) ;
}
if ( is ( "expand" , "..." ) ) {
is _expand = true ;
expand _token = S . token ;
used _parameters . mark _spread ( S . token ) ;
next ( ) ;
}
if ( is ( "name" ) && ( is _token ( peek ( ) , "punc" ) || is _token ( peek ( ) , "operator" ) ) && [ "," , "}" , "=" ] . includes ( peek ( ) . value ) ) {
used _parameters . add _parameter ( S . token ) ;
var start = prev ( ) ;
var value = as _symbol ( symbol _type ) ;
if ( is _expand ) {
elements . push ( new AST _Expansion ( {
start : expand _token ,
expression : value ,
end : value . end ,
} ) ) ;
} else {
elements . push ( new AST _ObjectKeyVal ( {
start : start ,
key : value . name ,
value : value ,
end : value . end ,
} ) ) ;
}
} else if ( is ( "punc" , "}" ) ) {
continue ; // Allow trailing hole
} else {
var property _token = S . token ;
var property = as _property _name ( ) ;
if ( property === null ) {
unexpected ( prev ( ) ) ;
} else if ( prev ( ) . type === "name" && ! is ( "punc" , ":" ) ) {
elements . push ( new AST _ObjectKeyVal ( {
start : prev ( ) ,
key : property ,
value : new symbol _type ( {
start : prev ( ) ,
name : property ,
end : prev ( )
} ) ,
end : prev ( )
} ) ) ;
} else {
expect ( ":" ) ;
elements . push ( new AST _ObjectKeyVal ( {
start : property _token ,
quote : property _token . quote ,
key : property ,
value : binding _element ( used _parameters , symbol _type ) ,
end : prev ( )
} ) ) ;
}
}
if ( is _expand ) {
if ( ! is ( "punc" , "}" ) ) {
croak ( "Rest element must be last element" ) ;
}
} else if ( is ( "operator" , "=" ) ) {
used _parameters . mark _default _assignment ( S . token ) ;
next ( ) ;
elements [ elements . length - 1 ] . value = new AST _DefaultAssign ( {
start : elements [ elements . length - 1 ] . value . start ,
left : elements [ elements . length - 1 ] . value ,
operator : "=" ,
right : expression ( false ) ,
end : S . token
} ) ;
}
}
expect ( "}" ) ;
used _parameters . check _strict ( ) ;
return new AST _Destructuring ( {
start : first _token ,
names : elements ,
is _array : false ,
end : prev ( )
} ) ;
} else if ( is ( "name" ) ) {
used _parameters . add _parameter ( S . token ) ;
return as _symbol ( symbol _type ) ;
} else {
croak ( "Invalid function parameter" ) ;
}
}
function params _or _seq _ ( allow _arrows , maybe _sequence ) {
var spread _token ;
var invalid _sequence ;
var trailing _comma ;
var a = [ ] ;
expect ( "(" ) ;
while ( ! is ( "punc" , ")" ) ) {
if ( spread _token ) unexpected ( spread _token ) ;
if ( is ( "expand" , "..." ) ) {
spread _token = S . token ;
if ( maybe _sequence ) invalid _sequence = S . token ;
next ( ) ;
a . push ( new AST _Expansion ( {
start : prev ( ) ,
expression : expression ( ) ,
end : S . token ,
} ) ) ;
} else {
a . push ( expression ( ) ) ;
}
if ( ! is ( "punc" , ")" ) ) {
expect ( "," ) ;
if ( is ( "punc" , ")" ) ) {
trailing _comma = prev ( ) ;
if ( maybe _sequence ) invalid _sequence = trailing _comma ;
}
}
}
expect ( ")" ) ;
if ( allow _arrows && is ( "arrow" , "=>" ) ) {
if ( spread _token && trailing _comma ) unexpected ( trailing _comma ) ;
} else if ( invalid _sequence ) {
unexpected ( invalid _sequence ) ;
}
return a ;
}
function _function _body ( block , generator , is _async , name , args ) {
var loop = S . in _loop ;
var labels = S . labels ;
var current _generator = S . in _generator ;
var current _async = S . in _async ;
++ S . in _function ;
if ( generator )
S . in _generator = S . in _function ;
if ( is _async )
S . in _async = S . in _function ;
if ( args ) parameters ( args ) ;
if ( block )
S . in _directives = true ;
S . in _loop = 0 ;
S . labels = [ ] ;
if ( block ) {
S . input . push _directives _stack ( ) ;
var a = block _ ( ) ;
if ( name ) _verify _symbol ( name ) ;
if ( args ) args . forEach ( _verify _symbol ) ;
S . input . pop _directives _stack ( ) ;
} else {
var a = [ new AST _Return ( {
start : S . token ,
value : expression ( false ) ,
end : S . token
} ) ] ;
}
-- S . in _function ;
S . in _loop = loop ;
S . labels = labels ;
S . in _generator = current _generator ;
S . in _async = current _async ;
return a ;
}
function _await _expression ( ) {
// Previous token must be "await" and not be interpreted as an identifier
if ( ! can _await ( ) ) {
croak ( "Unexpected await expression outside async function" ,
S . prev . line , S . prev . col , S . prev . pos ) ;
}
// the await expression is parsed as a unary expression in Babel
return new AST _Await ( {
start : prev ( ) ,
end : S . token ,
expression : maybe _unary ( true ) ,
} ) ;
}
function _yield _expression ( ) {
// Previous token must be keyword yield and not be interpret as an identifier
if ( ! is _in _generator ( ) ) {
croak ( "Unexpected yield expression outside generator function" ,
S . prev . line , S . prev . col , S . prev . pos ) ;
}
var start = S . token ;
var star = false ;
var has _expression = true ;
// Attempt to get expression or star (and then the mandatory expression)
// behind yield on the same line.
//
// If nothing follows on the same line of the yieldExpression,
// it should default to the value `undefined` for yield to return.
// In that case, the `undefined` stored as `null` in ast.
//
// Note 1: It isn't allowed for yield* to close without an expression
// Note 2: If there is a nlb between yield and star, it is interpret as
// yield <explicit undefined> <inserted automatic semicolon> *
if ( can _insert _semicolon ( ) ||
( is ( "punc" ) && PUNC _AFTER _EXPRESSION . has ( S . token . value ) ) ) {
has _expression = false ;
} else if ( is ( "operator" , "*" ) ) {
star = true ;
next ( ) ;
}
return new AST _Yield ( {
start : start ,
is _star : star ,
expression : has _expression ? expression ( ) : null ,
end : prev ( )
} ) ;
}
function if _ ( ) {
var cond = parenthesised ( ) , body = statement ( false , false , true ) , belse = null ;
if ( is ( "keyword" , "else" ) ) {
next ( ) ;
belse = statement ( false , false , true ) ;
}
return new AST _If ( {
condition : cond ,
body : body ,
alternative : belse
} ) ;
}
function block _ ( ) {
expect ( "{" ) ;
var a = [ ] ;
while ( ! is ( "punc" , "}" ) ) {
if ( is ( "eof" ) ) unexpected ( ) ;
a . push ( statement ( ) ) ;
}
next ( ) ;
return a ;
}
function switch _body _ ( ) {
expect ( "{" ) ;
var a = [ ] , cur = null , branch = null , tmp ;
while ( ! is ( "punc" , "}" ) ) {
if ( is ( "eof" ) ) unexpected ( ) ;
if ( is ( "keyword" , "case" ) ) {
if ( branch ) branch . end = prev ( ) ;
cur = [ ] ;
branch = new AST _Case ( {
start : ( tmp = S . token , next ( ) , tmp ) ,
expression : expression ( true ) ,
body : cur
} ) ;
a . push ( branch ) ;
expect ( ":" ) ;
} else if ( is ( "keyword" , "default" ) ) {
if ( branch ) branch . end = prev ( ) ;
cur = [ ] ;
branch = new AST _Default ( {
start : ( tmp = S . token , next ( ) , expect ( ":" ) , tmp ) ,
body : cur
} ) ;
a . push ( branch ) ;
} else {
if ( ! cur ) unexpected ( ) ;
cur . push ( statement ( ) ) ;
}
}
if ( branch ) branch . end = prev ( ) ;
next ( ) ;
return a ;
}
function try _ ( ) {
var body = block _ ( ) , bcatch = null , bfinally = null ;
if ( is ( "keyword" , "catch" ) ) {
var start = S . token ;
next ( ) ;
if ( is ( "punc" , "{" ) ) {
var name = null ;
} else {
expect ( "(" ) ;
var name = parameter ( undefined , AST _SymbolCatch ) ;
expect ( ")" ) ;
}
bcatch = new AST _Catch ( {
start : start ,
argname : name ,
body : block _ ( ) ,
end : prev ( )
} ) ;
}
if ( is ( "keyword" , "finally" ) ) {
var start = S . token ;
next ( ) ;
bfinally = new AST _Finally ( {
start : start ,
body : block _ ( ) ,
end : prev ( )
} ) ;
}
if ( ! bcatch && ! bfinally )
croak ( "Missing catch/finally blocks" ) ;
return new AST _Try ( {
body : body ,
bcatch : bcatch ,
bfinally : bfinally
} ) ;
}
function vardefs ( no _in , kind ) {
var a = [ ] ;
var def ;
for ( ; ; ) {
var sym _type =
kind === "var" ? AST _SymbolVar :
kind === "const" ? AST _SymbolConst :
kind === "let" ? AST _SymbolLet : null ;
if ( is ( "punc" , "{" ) || is ( "punc" , "[" ) ) {
def = new AST _VarDef ( {
start : S . token ,
name : binding _element ( undefined , sym _type ) ,
value : is ( "operator" , "=" ) ? ( expect _token ( "operator" , "=" ) , expression ( false , no _in ) ) : null ,
end : prev ( )
} ) ;
} else {
def = new AST _VarDef ( {
start : S . token ,
name : as _symbol ( sym _type ) ,
value : is ( "operator" , "=" )
? ( next ( ) , expression ( false , no _in ) )
: ! no _in && kind === "const"
? croak ( "Missing initializer in const declaration" ) : null ,
end : prev ( )
} ) ;
if ( def . name . name == "import" ) croak ( "Unexpected token: import" ) ;
}
a . push ( def ) ;
if ( ! is ( "punc" , "," ) )
break ;
next ( ) ;
}
return a ;
}
var var _ = function ( no _in ) {
return new AST _Var ( {
start : prev ( ) ,
definitions : vardefs ( no _in , "var" ) ,
end : prev ( )
} ) ;
} ;
var let _ = function ( no _in ) {
return new AST _Let ( {
start : prev ( ) ,
definitions : vardefs ( no _in , "let" ) ,
end : prev ( )
} ) ;
} ;
var const _ = function ( no _in ) {
return new AST _Const ( {
start : prev ( ) ,
definitions : vardefs ( no _in , "const" ) ,
end : prev ( )
} ) ;
} ;
var new _ = function ( allow _calls ) {
var start = S . token ;
expect _token ( "operator" , "new" ) ;
if ( is ( "punc" , "." ) ) {
next ( ) ;
expect _token ( "name" , "target" ) ;
return subscripts ( new AST _NewTarget ( {
start : start ,
end : prev ( )
} ) , allow _calls ) ;
}
var newexp = expr _atom ( false ) , args ;
if ( is ( "punc" , "(" ) ) {
next ( ) ;
args = expr _list ( ")" , true ) ;
} else {
args = [ ] ;
}
var call = new AST _New ( {
start : start ,
expression : newexp ,
args : args ,
end : prev ( )
} ) ;
annotate ( call ) ;
return subscripts ( call , allow _calls ) ;
} ;
function as _atom _node ( ) {
var tok = S . token , ret ;
switch ( tok . type ) {
case "name" :
ret = _make _symbol ( AST _SymbolRef ) ;
break ;
case "num" :
ret = new AST _Number ( {
start : tok ,
end : tok ,
value : tok . value ,
raw : LATEST _RAW
} ) ;
break ;
case "big_int" :
ret = new AST _BigInt ( { start : tok , end : tok , value : tok . value } ) ;
break ;
case "string" :
ret = new AST _String ( {
start : tok ,
end : tok ,
value : tok . value ,
quote : tok . quote
} ) ;
break ;
case "regexp" :
const [ _ , source , flags ] = tok . value . match ( /^\/(.*)\/(\w*)$/ ) ;
ret = new AST _RegExp ( { start : tok , end : tok , value : { source , flags } } ) ;
break ;
case "atom" :
switch ( tok . value ) {
case "false" :
ret = new AST _False ( { start : tok , end : tok } ) ;
break ;
case "true" :
ret = new AST _True ( { start : tok , end : tok } ) ;
break ;
case "null" :
ret = new AST _Null ( { start : tok , end : tok } ) ;
break ;
}
break ;
}
next ( ) ;
return ret ;
}
function to _fun _args ( ex , default _seen _above ) {
var insert _default = function ( ex , default _value ) {
if ( default _value ) {
return new AST _DefaultAssign ( {
start : ex . start ,
left : ex ,
operator : "=" ,
right : default _value ,
end : default _value . end
} ) ;
}
return ex ;
} ;
if ( ex instanceof AST _Object ) {
return insert _default ( new AST _Destructuring ( {
start : ex . start ,
end : ex . end ,
is _array : false ,
names : ex . properties . map ( prop => to _fun _args ( prop ) )
} ) , default _seen _above ) ;
} else if ( ex instanceof AST _ObjectKeyVal ) {
ex . value = to _fun _args ( ex . value ) ;
return insert _default ( ex , default _seen _above ) ;
} else if ( ex instanceof AST _Hole ) {
return ex ;
} else if ( ex instanceof AST _Destructuring ) {
ex . names = ex . names . map ( name => to _fun _args ( name ) ) ;
return insert _default ( ex , default _seen _above ) ;
} else if ( ex instanceof AST _SymbolRef ) {
return insert _default ( new AST _SymbolFunarg ( {
name : ex . name ,
start : ex . start ,
end : ex . end
} ) , default _seen _above ) ;
} else if ( ex instanceof AST _Expansion ) {
ex . expression = to _fun _args ( ex . expression ) ;
return insert _default ( ex , default _seen _above ) ;
} else if ( ex instanceof AST _Array ) {
return insert _default ( new AST _Destructuring ( {
start : ex . start ,
end : ex . end ,
is _array : true ,
names : ex . elements . map ( elm => to _fun _args ( elm ) )
} ) , default _seen _above ) ;
} else if ( ex instanceof AST _Assign ) {
return insert _default ( to _fun _args ( ex . left , ex . right ) , default _seen _above ) ;
} else if ( ex instanceof AST _DefaultAssign ) {
ex . left = to _fun _args ( ex . left ) ;
return ex ;
} else {
croak ( "Invalid function parameter" , ex . start . line , ex . start . col ) ;
}
}
var expr _atom = function ( allow _calls , allow _arrows ) {
if ( is ( "operator" , "new" ) ) {
return new _ ( allow _calls ) ;
}
if ( is ( "operator" , "import" ) ) {
return import _meta ( ) ;
}
var start = S . token ;
var peeked ;
var async = is ( "name" , "async" )
&& ( peeked = peek ( ) ) . value != "["
&& peeked . type != "arrow"
&& as _atom _node ( ) ;
if ( is ( "punc" ) ) {
switch ( S . token . value ) {
case "(" :
if ( async && ! allow _calls ) break ;
var exprs = params _or _seq _ ( allow _arrows , ! async ) ;
if ( allow _arrows && is ( "arrow" , "=>" ) ) {
return arrow _function ( start , exprs . map ( e => to _fun _args ( e ) ) , ! ! async ) ;
}
var ex = async ? new AST _Call ( {
expression : async ,
args : exprs
} ) : exprs . length == 1 ? exprs [ 0 ] : new AST _Sequence ( {
expressions : exprs
} ) ;
if ( ex . start ) {
const outer _comments _before = start . comments _before . length ;
outer _comments _before _counts . set ( start , outer _comments _before ) ;
ex . start . comments _before . unshift ( ... start . comments _before ) ;
start . comments _before = ex . start . comments _before ;
if ( outer _comments _before == 0 && start . comments _before . length > 0 ) {
var comment = start . comments _before [ 0 ] ;
if ( ! comment . nlb ) {
comment . nlb = start . nlb ;
start . nlb = false ;
}
}
start . comments _after = ex . start . comments _after ;
}
ex . start = start ;
var end = prev ( ) ;
if ( ex . end ) {
end . comments _before = ex . end . comments _before ;
ex . end . comments _after . push ( ... end . comments _after ) ;
end . comments _after = ex . end . comments _after ;
}
ex . end = end ;
if ( ex instanceof AST _Call ) annotate ( ex ) ;
return subscripts ( ex , allow _calls ) ;
case "[" :
return subscripts ( array _ ( ) , allow _calls ) ;
case "{" :
return subscripts ( object _or _destructuring _ ( ) , allow _calls ) ;
}
if ( ! async ) unexpected ( ) ;
}
if ( allow _arrows && is ( "name" ) && is _token ( peek ( ) , "arrow" ) ) {
var param = new AST _SymbolFunarg ( {
name : S . token . value ,
start : start ,
end : start ,
} ) ;
next ( ) ;
return arrow _function ( start , [ param ] , ! ! async ) ;
}
if ( is ( "keyword" , "function" ) ) {
next ( ) ;
var func = function _ ( AST _Function , false , ! ! async ) ;
func . start = start ;
func . end = prev ( ) ;
return subscripts ( func , allow _calls ) ;
}
if ( async ) return subscripts ( async , allow _calls ) ;
if ( is ( "keyword" , "class" ) ) {
next ( ) ;
var cls = class _ ( AST _ClassExpression ) ;
cls . start = start ;
cls . end = prev ( ) ;
return subscripts ( cls , allow _calls ) ;
}
if ( is ( "template_head" ) ) {
return subscripts ( template _string ( ) , allow _calls ) ;
}
if ( ATOMIC _START _TOKEN . has ( S . token . type ) ) {
return subscripts ( as _atom _node ( ) , allow _calls ) ;
}
unexpected ( ) ;
} ;
function template _string ( ) {
var segments = [ ] , start = S . token ;
segments . push ( new AST _TemplateSegment ( {
start : S . token ,
raw : LATEST _RAW ,
value : S . token . value ,
end : S . token
} ) ) ;
while ( ! LATEST _TEMPLATE _END ) {
next ( ) ;
handle _regexp ( ) ;
segments . push ( expression ( true ) ) ;
segments . push ( new AST _TemplateSegment ( {
start : S . token ,
raw : LATEST _RAW ,
value : S . token . value ,
end : S . token
} ) ) ;
}
next ( ) ;
return new AST _TemplateString ( {
start : start ,
segments : segments ,
end : S . token
} ) ;
}
function expr _list ( closing , allow _trailing _comma , allow _empty ) {
var first = true , a = [ ] ;
while ( ! is ( "punc" , closing ) ) {
if ( first ) first = false ; else expect ( "," ) ;
if ( allow _trailing _comma && is ( "punc" , closing ) ) break ;
if ( is ( "punc" , "," ) && allow _empty ) {
a . push ( new AST _Hole ( { start : S . token , end : S . token } ) ) ;
} else if ( is ( "expand" , "..." ) ) {
next ( ) ;
a . push ( new AST _Expansion ( { start : prev ( ) , expression : expression ( ) , end : S . token } ) ) ;
} else {
a . push ( expression ( false ) ) ;
}
}
next ( ) ;
return a ;
}
var array _ = embed _tokens ( function ( ) {
expect ( "[" ) ;
return new AST _Array ( {
elements : expr _list ( "]" , ! options . strict , true )
} ) ;
} ) ;
var create _accessor = embed _tokens ( ( is _generator , is _async ) => {
return function _ ( AST _Accessor , is _generator , is _async ) ;
} ) ;
var object _or _destructuring _ = embed _tokens ( function object _or _destructuring _ ( ) {
var start = S . token , first = true , a = [ ] ;
expect ( "{" ) ;
while ( ! is ( "punc" , "}" ) ) {
if ( first ) first = false ; else expect ( "," ) ;
if ( ! options . strict && is ( "punc" , "}" ) )
// allow trailing comma
break ;
start = S . token ;
if ( start . type == "expand" ) {
next ( ) ;
a . push ( new AST _Expansion ( {
start : start ,
expression : expression ( false ) ,
end : prev ( ) ,
} ) ) ;
continue ;
}
var name = as _property _name ( ) ;
var value ;
// Check property and fetch value
if ( ! is ( "punc" , ":" ) ) {
var concise = concise _method _or _getset ( name , start ) ;
if ( concise ) {
a . push ( concise ) ;
continue ;
}
value = new AST _SymbolRef ( {
start : prev ( ) ,
name : name ,
end : prev ( )
} ) ;
} else if ( name === null ) {
unexpected ( prev ( ) ) ;
} else {
next ( ) ; // `:` - see first condition
value = expression ( false ) ;
}
// Check for default value and alter value accordingly if necessary
if ( is ( "operator" , "=" ) ) {
next ( ) ;
value = new AST _Assign ( {
start : start ,
left : value ,
operator : "=" ,
right : expression ( false ) ,
logical : false ,
end : prev ( )
} ) ;
}
// Create property
a . push ( new AST _ObjectKeyVal ( {
start : start ,
quote : start . quote ,
key : name instanceof AST _Node ? name : "" + name ,
value : value ,
end : prev ( )
} ) ) ;
}
next ( ) ;
return new AST _Object ( { properties : a } ) ;
} ) ;
function class _ ( KindOfClass , is _export _default ) {
var start , method , class _name , extends _ , a = [ ] ;
S . input . push _directives _stack ( ) ; // Push directive stack, but not scope stack
S . input . add _directive ( "use strict" ) ;
if ( S . token . type == "name" && S . token . value != "extends" ) {
class _name = as _symbol ( KindOfClass === AST _DefClass ? AST _SymbolDefClass : AST _SymbolClass ) ;
}
if ( KindOfClass === AST _DefClass && ! class _name ) {
if ( is _export _default ) {
KindOfClass = AST _ClassExpression ;
} else {
unexpected ( ) ;
}
}
if ( S . token . value == "extends" ) {
next ( ) ;
extends _ = expression ( true ) ;
}
expect ( "{" ) ;
while ( is ( "punc" , ";" ) ) { next ( ) ; } // Leading semicolons are okay in class bodies.
while ( ! is ( "punc" , "}" ) ) {
start = S . token ;
method = concise _method _or _getset ( as _property _name ( ) , start , true ) ;
if ( ! method ) { unexpected ( ) ; }
a . push ( method ) ;
while ( is ( "punc" , ";" ) ) { next ( ) ; }
}
S . input . pop _directives _stack ( ) ;
next ( ) ;
return new KindOfClass ( {
start : start ,
name : class _name ,
extends : extends _ ,
properties : a ,
end : prev ( ) ,
} ) ;
}
function concise _method _or _getset ( name , start , is _class ) {
const get _symbol _ast = ( name , SymbolClass = AST _SymbolMethod ) => {
if ( typeof name === "string" || typeof name === "number" ) {
return new SymbolClass ( {
start ,
name : "" + name ,
end : prev ( )
} ) ;
} else if ( name === null ) {
unexpected ( ) ;
}
return name ;
} ;
const is _not _method _start = ( ) =>
! is ( "punc" , "(" ) && ! is ( "punc" , "," ) && ! is ( "punc" , "}" ) && ! is ( "operator" , "=" ) ;
var is _async = false ;
var is _static = false ;
var is _generator = false ;
var is _private = false ;
var accessor _type = null ;
if ( is _class && name === "static" && is _not _method _start ( ) ) {
is _static = true ;
name = as _property _name ( ) ;
}
if ( name === "async" && is _not _method _start ( ) ) {
is _async = true ;
name = as _property _name ( ) ;
}
if ( prev ( ) . type === "operator" && prev ( ) . value === "*" ) {
is _generator = true ;
name = as _property _name ( ) ;
}
if ( ( name === "get" || name === "set" ) && is _not _method _start ( ) ) {
accessor _type = name ;
name = as _property _name ( ) ;
}
if ( prev ( ) . type === "privatename" ) {
is _private = true ;
}
const property _token = prev ( ) ;
if ( accessor _type != null ) {
if ( ! is _private ) {
const AccessorClass = accessor _type === "get"
? AST _ObjectGetter
: AST _ObjectSetter ;
name = get _symbol _ast ( name ) ;
return new AccessorClass ( {
start ,
static : is _static ,
key : name ,
quote : name instanceof AST _SymbolMethod ? property _token . quote : undefined ,
value : create _accessor ( ) ,
end : prev ( )
} ) ;
} else {
const AccessorClass = accessor _type === "get"
? AST _PrivateGetter
: AST _PrivateSetter ;
return new AccessorClass ( {
start ,
static : is _static ,
key : get _symbol _ast ( name ) ,
value : create _accessor ( ) ,
end : prev ( ) ,
} ) ;
}
}
if ( is ( "punc" , "(" ) ) {
name = get _symbol _ast ( name ) ;
const AST _MethodVariant = is _private
? AST _PrivateMethod
: AST _ConciseMethod ;
var node = new AST _MethodVariant ( {
start : start ,
static : is _static ,
is _generator : is _generator ,
async : is _async ,
key : name ,
quote : name instanceof AST _SymbolMethod ?
property _token . quote : undefined ,
value : create _accessor ( is _generator , is _async ) ,
end : prev ( )
} ) ;
return node ;
}
if ( is _class ) {
const key = get _symbol _ast ( name , AST _SymbolClassProperty ) ;
const quote = key instanceof AST _SymbolClassProperty
? property _token . quote
: undefined ;
const AST _ClassPropertyVariant = is _private
? AST _ClassPrivateProperty
: AST _ClassProperty ;
if ( is ( "operator" , "=" ) ) {
next ( ) ;
return new AST _ClassPropertyVariant ( {
start ,
static : is _static ,
quote ,
key ,
value : expression ( false ) ,
end : prev ( )
} ) ;
} else if (
is ( "name" )
|| is ( "privatename" )
|| is ( "operator" , "*" )
|| is ( "punc" , ";" )
|| is ( "punc" , "}" )
) {
return new AST _ClassPropertyVariant ( {
start ,
static : is _static ,
quote ,
key ,
end : prev ( )
} ) ;
}
}
}
function import _ ( ) {
var start = prev ( ) ;
var imported _name ;
var imported _names ;
if ( is ( "name" ) ) {
imported _name = as _symbol ( AST _SymbolImport ) ;
}
if ( is ( "punc" , "," ) ) {
next ( ) ;
}
imported _names = map _names ( true ) ;
if ( imported _names || imported _name ) {
expect _token ( "name" , "from" ) ;
}
var mod _str = S . token ;
if ( mod _str . type !== "string" ) {
unexpected ( ) ;
}
next ( ) ;
return new AST _Import ( {
start : start ,
imported _name : imported _name ,
imported _names : imported _names ,
module _name : new AST _String ( {
start : mod _str ,
value : mod _str . value ,
quote : mod _str . quote ,
end : mod _str ,
} ) ,
end : S . token ,
} ) ;
}
function import _meta ( ) {
var start = S . token ;
expect _token ( "operator" , "import" ) ;
expect _token ( "punc" , "." ) ;
expect _token ( "name" , "meta" ) ;
return subscripts ( new AST _ImportMeta ( {
start : start ,
end : prev ( )
} ) , false ) ;
}
function map _name ( is _import ) {
function make _symbol ( type ) {
return new type ( {
name : as _property _name ( ) ,
start : prev ( ) ,
end : prev ( )
} ) ;
}
var foreign _type = is _import ? AST _SymbolImportForeign : AST _SymbolExportForeign ;
var type = is _import ? AST _SymbolImport : AST _SymbolExport ;
var start = S . token ;
var foreign _name ;
var name ;
if ( is _import ) {
foreign _name = make _symbol ( foreign _type ) ;
} else {
name = make _symbol ( type ) ;
}
if ( is ( "name" , "as" ) ) {
next ( ) ; // The "as" word
if ( is _import ) {
name = make _symbol ( type ) ;
} else {
foreign _name = make _symbol ( foreign _type ) ;
}
} else if ( is _import ) {
name = new type ( foreign _name ) ;
} else {
foreign _name = new foreign _type ( name ) ;
}
return new AST _NameMapping ( {
start : start ,
foreign _name : foreign _name ,
name : name ,
end : prev ( ) ,
} ) ;
}
function map _nameAsterisk ( is _import , name ) {
var foreign _type = is _import ? AST _SymbolImportForeign : AST _SymbolExportForeign ;
var type = is _import ? AST _SymbolImport : AST _SymbolExport ;
var start = S . token ;
var foreign _name ;
var end = prev ( ) ;
name = name || new type ( {
name : "*" ,
start : start ,
end : end ,
} ) ;
foreign _name = new foreign _type ( {
name : "*" ,
start : start ,
end : end ,
} ) ;
return new AST _NameMapping ( {
start : start ,
foreign _name : foreign _name ,
name : name ,
end : end ,
} ) ;
}
function map _names ( is _import ) {
var names ;
if ( is ( "punc" , "{" ) ) {
next ( ) ;
names = [ ] ;
while ( ! is ( "punc" , "}" ) ) {
names . push ( map _name ( is _import ) ) ;
if ( is ( "punc" , "," ) ) {
next ( ) ;
}
}
next ( ) ;
} else if ( is ( "operator" , "*" ) ) {
var name ;
next ( ) ;
if ( is _import && is ( "name" , "as" ) ) {
next ( ) ; // The "as" word
name = as _symbol ( is _import ? AST _SymbolImport : AST _SymbolExportForeign ) ;
}
names = [ map _nameAsterisk ( is _import , name ) ] ;
}
return names ;
}
function export _ ( ) {
var start = S . token ;
var is _default ;
var exported _names ;
if ( is ( "keyword" , "default" ) ) {
is _default = true ;
next ( ) ;
} else if ( exported _names = map _names ( false ) ) {
if ( is ( "name" , "from" ) ) {
next ( ) ;
var mod _str = S . token ;
if ( mod _str . type !== "string" ) {
unexpected ( ) ;
}
next ( ) ;
return new AST _Export ( {
start : start ,
is _default : is _default ,
exported _names : exported _names ,
module _name : new AST _String ( {
start : mod _str ,
value : mod _str . value ,
quote : mod _str . quote ,
end : mod _str ,
} ) ,
end : prev ( ) ,
} ) ;
} else {
return new AST _Export ( {
start : start ,
is _default : is _default ,
exported _names : exported _names ,
end : prev ( ) ,
} ) ;
}
}
var node ;
var exported _value ;
var exported _definition ;
if ( is ( "punc" , "{" )
|| is _default
&& ( is ( "keyword" , "class" ) || is ( "keyword" , "function" ) )
&& is _token ( peek ( ) , "punc" ) ) {
exported _value = expression ( false ) ;
semicolon ( ) ;
} else if ( ( node = statement ( is _default ) ) instanceof AST _Definitions && is _default ) {
unexpected ( node . start ) ;
} else if (
node instanceof AST _Definitions
|| node instanceof AST _Defun
|| node instanceof AST _DefClass
) {
exported _definition = node ;
} else if (
node instanceof AST _ClassExpression
|| node instanceof AST _Function
) {
exported _value = node ;
} else if ( node instanceof AST _SimpleStatement ) {
exported _value = node . body ;
} else {
unexpected ( node . start ) ;
}
return new AST _Export ( {
start : start ,
is _default : is _default ,
exported _value : exported _value ,
exported _definition : exported _definition ,
end : prev ( ) ,
} ) ;
}
function as _property _name ( ) {
var tmp = S . token ;
switch ( tmp . type ) {
case "punc" :
if ( tmp . value === "[" ) {
next ( ) ;
var ex = expression ( false ) ;
expect ( "]" ) ;
return ex ;
} else unexpected ( tmp ) ;
case "operator" :
if ( tmp . value === "*" ) {
next ( ) ;
return null ;
}
if ( ! [ "delete" , "in" , "instanceof" , "new" , "typeof" , "void" ] . includes ( tmp . value ) ) {
unexpected ( tmp ) ;
}
/* falls through */
case "name" :
case "privatename" :
case "string" :
case "num" :
case "big_int" :
case "keyword" :
case "atom" :
next ( ) ;
return tmp . value ;
default :
unexpected ( tmp ) ;
}
}
function as _name ( ) {
var tmp = S . token ;
if ( tmp . type != "name" && tmp . type != "privatename" ) unexpected ( ) ;
next ( ) ;
return tmp . value ;
}
function _make _symbol ( type ) {
var name = S . token . value ;
return new ( name == "this" ? AST _This :
name == "super" ? AST _Super :
type ) ( {
name : String ( name ) ,
start : S . token ,
end : S . token
} ) ;
}
function _verify _symbol ( sym ) {
var name = sym . name ;
if ( is _in _generator ( ) && name == "yield" ) {
token _error ( sym . start , "Yield cannot be used as identifier inside generators" ) ;
}
if ( S . input . has _directive ( "use strict" ) ) {
if ( name == "yield" ) {
token _error ( sym . start , "Unexpected yield identifier inside strict mode" ) ;
}
if ( sym instanceof AST _SymbolDeclaration && ( name == "arguments" || name == "eval" ) ) {
token _error ( sym . start , "Unexpected " + name + " in strict mode" ) ;
}
}
}
function as _symbol ( type , noerror ) {
if ( ! is ( "name" ) ) {
if ( ! noerror ) croak ( "Name expected" ) ;
return null ;
}
var sym = _make _symbol ( type ) ;
_verify _symbol ( sym ) ;
next ( ) ;
return sym ;
}
// Annotate AST_Call, AST_Lambda or AST_New with the special comments
function annotate ( node ) {
var start = node . start ;
var comments = start . comments _before ;
const comments _outside _parens = outer _comments _before _counts . get ( start ) ;
var i = comments _outside _parens != null ? comments _outside _parens : comments . length ;
while ( -- i >= 0 ) {
var comment = comments [ i ] ;
if ( /[@#]__/ . test ( comment . value ) ) {
if ( /[@#]__PURE__/ . test ( comment . value ) ) {
set _annotation ( node , _PURE ) ;
break ;
}
if ( /[@#]__INLINE__/ . test ( comment . value ) ) {
set _annotation ( node , _INLINE ) ;
break ;
}
if ( /[@#]__NOINLINE__/ . test ( comment . value ) ) {
set _annotation ( node , _NOINLINE ) ;
break ;
}
}
}
}
var subscripts = function ( expr , allow _calls , is _chain ) {
var start = expr . start ;
if ( is ( "punc" , "." ) ) {
next ( ) ;
const AST _DotVariant = is ( "privatename" ) ? AST _DotHash : AST _Dot ;
return subscripts ( new AST _DotVariant ( {
start : start ,
expression : expr ,
optional : false ,
property : as _name ( ) ,
end : prev ( )
} ) , allow _calls , is _chain ) ;
}
if ( is ( "punc" , "[" ) ) {
next ( ) ;
var prop = expression ( true ) ;
expect ( "]" ) ;
return subscripts ( new AST _Sub ( {
start : start ,
expression : expr ,
optional : false ,
property : prop ,
end : prev ( )
} ) , allow _calls , is _chain ) ;
}
if ( allow _calls && is ( "punc" , "(" ) ) {
next ( ) ;
var call = new AST _Call ( {
start : start ,
expression : expr ,
optional : false ,
args : call _args ( ) ,
end : prev ( )
} ) ;
annotate ( call ) ;
return subscripts ( call , true , is _chain ) ;
}
if ( is ( "punc" , "?." ) ) {
next ( ) ;
let chain _contents ;
if ( allow _calls && is ( "punc" , "(" ) ) {
next ( ) ;
const call = new AST _Call ( {
start ,
optional : true ,
expression : expr ,
args : call _args ( ) ,
end : prev ( )
} ) ;
annotate ( call ) ;
chain _contents = subscripts ( call , true , true ) ;
} else if ( is ( "name" ) || is ( "privatename" ) ) {
const AST _DotVariant = is ( "privatename" ) ? AST _DotHash : AST _Dot ;
chain _contents = subscripts ( new AST _DotVariant ( {
start ,
expression : expr ,
optional : true ,
property : as _name ( ) ,
end : prev ( )
} ) , allow _calls , true ) ;
} else if ( is ( "punc" , "[" ) ) {
next ( ) ;
const property = expression ( true ) ;
expect ( "]" ) ;
chain _contents = subscripts ( new AST _Sub ( {
start ,
expression : expr ,
optional : true ,
property ,
end : prev ( )
} ) , allow _calls , true ) ;
}
if ( ! chain _contents ) unexpected ( ) ;
if ( chain _contents instanceof AST _Chain ) return chain _contents ;
return new AST _Chain ( {
start ,
expression : chain _contents ,
end : prev ( )
} ) ;
}
if ( is ( "template_head" ) ) {
if ( is _chain ) {
// a?.b`c` is a syntax error
unexpected ( ) ;
}
return subscripts ( new AST _PrefixedTemplateString ( {
start : start ,
prefix : expr ,
template _string : template _string ( ) ,
end : prev ( )
} ) , allow _calls ) ;
}
return expr ;
} ;
function call _args ( ) {
var args = [ ] ;
while ( ! is ( "punc" , ")" ) ) {
if ( is ( "expand" , "..." ) ) {
next ( ) ;
args . push ( new AST _Expansion ( {
start : prev ( ) ,
expression : expression ( false ) ,
end : prev ( )
} ) ) ;
} else {
args . push ( expression ( false ) ) ;
}
if ( ! is ( "punc" , ")" ) ) {
expect ( "," ) ;
}
}
next ( ) ;
return args ;
}
var maybe _unary = function ( allow _calls , allow _arrows ) {
var start = S . token ;
if ( start . type == "name" && start . value == "await" && can _await ( ) ) {
next ( ) ;
return _await _expression ( ) ;
}
if ( is ( "operator" ) && UNARY _PREFIX . has ( start . value ) ) {
next ( ) ;
handle _regexp ( ) ;
var ex = make _unary ( AST _UnaryPrefix , start , maybe _unary ( allow _calls ) ) ;
ex . start = start ;
ex . end = prev ( ) ;
return ex ;
}
var val = expr _atom ( allow _calls , allow _arrows ) ;
while ( is ( "operator" ) && UNARY _POSTFIX . has ( S . token . value ) && ! has _newline _before ( S . token ) ) {
if ( val instanceof AST _Arrow ) unexpected ( ) ;
val = make _unary ( AST _UnaryPostfix , S . token , val ) ;
val . start = start ;
val . end = S . token ;
next ( ) ;
}
return val ;
} ;
function make _unary ( ctor , token , expr ) {
var op = token . value ;
switch ( op ) {
case "++" :
case "--" :
if ( ! is _assignable ( expr ) )
croak ( "Invalid use of " + op + " operator" , token . line , token . col , token . pos ) ;
break ;
case "delete" :
if ( expr instanceof AST _SymbolRef && S . input . has _directive ( "use strict" ) )
croak ( "Calling delete on expression not allowed in strict mode" , expr . start . line , expr . start . col , expr . start . pos ) ;
break ;
}
return new ctor ( { operator : op , expression : expr } ) ;
}
var expr _op = function ( left , min _prec , no _in ) {
var op = is ( "operator" ) ? S . token . value : null ;
if ( op == "in" && no _in ) op = null ;
if ( op == "**" && left instanceof AST _UnaryPrefix
/* unary token in front not allowed - parenthesis required */
&& ! is _token ( left . start , "punc" , "(" )
&& left . operator !== "--" && left . operator !== "++" )
unexpected ( left . start ) ;
var prec = op != null ? PRECEDENCE [ op ] : null ;
if ( prec != null && ( prec > min _prec || ( op === "**" && min _prec === prec ) ) ) {
next ( ) ;
var right = expr _op ( maybe _unary ( true ) , prec , no _in ) ;
return expr _op ( new AST _Binary ( {
start : left . start ,
left : left ,
operator : op ,
right : right ,
end : right . end
} ) , min _prec , no _in ) ;
}
return left ;
} ;
function expr _ops ( no _in ) {
return expr _op ( maybe _unary ( true , true ) , 0 , no _in ) ;
}
var maybe _conditional = function ( no _in ) {
var start = S . token ;
var expr = expr _ops ( no _in ) ;
if ( is ( "operator" , "?" ) ) {
next ( ) ;
var yes = expression ( false ) ;
expect ( ":" ) ;
return new AST _Conditional ( {
start : start ,
condition : expr ,
consequent : yes ,
alternative : expression ( false , no _in ) ,
end : prev ( )
} ) ;
}
return expr ;
} ;
function is _assignable ( expr ) {
return expr instanceof AST _PropAccess || expr instanceof AST _SymbolRef ;
}
function to _destructuring ( node ) {
if ( node instanceof AST _Object ) {
node = new AST _Destructuring ( {
start : node . start ,
names : node . properties . map ( to _destructuring ) ,
is _array : false ,
end : node . end
} ) ;
} else if ( node instanceof AST _Array ) {
var names = [ ] ;
for ( var i = 0 ; i < node . elements . length ; i ++ ) {
// Only allow expansion as last element
if ( node . elements [ i ] instanceof AST _Expansion ) {
if ( i + 1 !== node . elements . length ) {
token _error ( node . elements [ i ] . start , "Spread must the be last element in destructuring array" ) ;
}
node . elements [ i ] . expression = to _destructuring ( node . elements [ i ] . expression ) ;
}
names . push ( to _destructuring ( node . elements [ i ] ) ) ;
}
node = new AST _Destructuring ( {
start : node . start ,
names : names ,
is _array : true ,
end : node . end
} ) ;
} else if ( node instanceof AST _ObjectProperty ) {
node . value = to _destructuring ( node . value ) ;
} else if ( node instanceof AST _Assign ) {
node = new AST _DefaultAssign ( {
start : node . start ,
left : node . left ,
operator : "=" ,
right : node . right ,
end : node . end
} ) ;
}
return node ;
}
// In ES6, AssignmentExpression can also be an ArrowFunction
var maybe _assign = function ( no _in ) {
handle _regexp ( ) ;
var start = S . token ;
if ( start . type == "name" && start . value == "yield" ) {
if ( is _in _generator ( ) ) {
next ( ) ;
return _yield _expression ( ) ;
} else if ( S . input . has _directive ( "use strict" ) ) {
token _error ( S . token , "Unexpected yield identifier inside strict mode" ) ;
}
}
var left = maybe _conditional ( no _in ) ;
var val = S . token . value ;
if ( is ( "operator" ) && ASSIGNMENT . has ( val ) ) {
if ( is _assignable ( left ) || ( left = to _destructuring ( left ) ) instanceof AST _Destructuring ) {
next ( ) ;
return new AST _Assign ( {
start : start ,
left : left ,
operator : val ,
right : maybe _assign ( no _in ) ,
logical : LOGICAL _ASSIGNMENT . has ( val ) ,
end : prev ( )
} ) ;
}
croak ( "Invalid assignment" ) ;
}
return left ;
} ;
var expression = function ( commas , no _in ) {
var start = S . token ;
var exprs = [ ] ;
while ( true ) {
exprs . push ( maybe _assign ( no _in ) ) ;
if ( ! commas || ! is ( "punc" , "," ) ) break ;
next ( ) ;
commas = true ;
}
return exprs . length == 1 ? exprs [ 0 ] : new AST _Sequence ( {
start : start ,
expressions : exprs ,
end : peek ( )
} ) ;
} ;
function in _loop ( cont ) {
++ S . in _loop ;
var ret = cont ( ) ;
-- S . in _loop ;
return ret ;
}
if ( options . expression ) {
return expression ( true ) ;
}
return ( function parse _toplevel ( ) {
var start = S . token ;
var body = [ ] ;
S . input . push _directives _stack ( ) ;
if ( options . module ) S . input . add _directive ( "use strict" ) ;
while ( ! is ( "eof" ) ) {
body . push ( statement ( ) ) ;
}
S . input . pop _directives _stack ( ) ;
var end = prev ( ) ;
var toplevel = options . toplevel ;
if ( toplevel ) {
toplevel . body = toplevel . body . concat ( body ) ;
toplevel . end = end ;
} else {
toplevel = new AST _Toplevel ( { start : start , body : body , end : end } ) ;
}
return toplevel ;
} ) ( ) ;
}
export {
get _full _char _code ,
get _full _char ,
is _identifier _char ,
is _basic _identifier _string ,
is _identifier _string ,
is _surrogate _pair _head ,
is _surrogate _pair _tail ,
js _error ,
JS _Parse _Error ,
parse ,
PRECEDENCE ,
ALL _RESERVED _WORDS ,
tokenizer ,
} ;