2 Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
17 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 (function (root, factory) {
28 // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
29 // Rhino, and plain browser loading.
31 /* istanbul ignore next */
32 if (typeof define === 'function' && define.amd) {
33 define(['exports'], factory);
34 } else if (typeof exports !== 'undefined') {
37 factory((root.esprima = {}));
39 }(this, function (exports) {
69 firstCoverInitializedNameError;
85 TokenName[Token.BooleanLiteral] = 'Boolean';
86 TokenName[Token.EOF] = '<end>';
87 TokenName[Token.Identifier] = 'Identifier';
88 TokenName[Token.Keyword] = 'Keyword';
89 TokenName[Token.NullLiteral] = 'Null';
90 TokenName[Token.NumericLiteral] = 'Numeric';
91 TokenName[Token.Punctuator] = 'Punctuator';
92 TokenName[Token.StringLiteral] = 'String';
93 TokenName[Token.RegularExpression] = 'RegularExpression';
94 TokenName[Token.Template] = 'Template';
96 // A function following one of those tokens is an expression.
97 FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
98 'return', 'case', 'delete', 'throw', 'void',
99 // assignment operators
100 '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
101 '&=', '|=', '^=', ',',
102 // binary/unary operators
103 '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
104 '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
105 '<=', '<', '>', '!=', '!=='];
108 AssignmentExpression: 'AssignmentExpression',
109 AssignmentPattern: 'AssignmentPattern',
110 ArrayExpression: 'ArrayExpression',
111 ArrayPattern: 'ArrayPattern',
112 ArrowFunctionExpression: 'ArrowFunctionExpression',
113 BlockStatement: 'BlockStatement',
114 BinaryExpression: 'BinaryExpression',
115 BreakStatement: 'BreakStatement',
116 CallExpression: 'CallExpression',
117 CatchClause: 'CatchClause',
118 ClassBody: 'ClassBody',
119 ClassDeclaration: 'ClassDeclaration',
120 ClassExpression: 'ClassExpression',
121 ConditionalExpression: 'ConditionalExpression',
122 ContinueStatement: 'ContinueStatement',
123 DoWhileStatement: 'DoWhileStatement',
124 DebuggerStatement: 'DebuggerStatement',
125 EmptyStatement: 'EmptyStatement',
126 ExportAllDeclaration: 'ExportAllDeclaration',
127 ExportDefaultDeclaration: 'ExportDefaultDeclaration',
128 ExportNamedDeclaration: 'ExportNamedDeclaration',
129 ExportSpecifier: 'ExportSpecifier',
130 ExpressionStatement: 'ExpressionStatement',
131 ForStatement: 'ForStatement',
132 ForOfStatement: 'ForOfStatement',
133 ForInStatement: 'ForInStatement',
134 FunctionDeclaration: 'FunctionDeclaration',
135 FunctionExpression: 'FunctionExpression',
136 Identifier: 'Identifier',
137 IfStatement: 'IfStatement',
138 ImportDeclaration: 'ImportDeclaration',
139 ImportDefaultSpecifier: 'ImportDefaultSpecifier',
140 ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
141 ImportSpecifier: 'ImportSpecifier',
143 LabeledStatement: 'LabeledStatement',
144 LogicalExpression: 'LogicalExpression',
145 MemberExpression: 'MemberExpression',
146 MetaProperty: 'MetaProperty',
147 MethodDefinition: 'MethodDefinition',
148 NewExpression: 'NewExpression',
149 ObjectExpression: 'ObjectExpression',
150 ObjectPattern: 'ObjectPattern',
152 Property: 'Property',
153 RestElement: 'RestElement',
154 ReturnStatement: 'ReturnStatement',
155 SequenceExpression: 'SequenceExpression',
156 SpreadElement: 'SpreadElement',
158 SwitchCase: 'SwitchCase',
159 SwitchStatement: 'SwitchStatement',
160 TaggedTemplateExpression: 'TaggedTemplateExpression',
161 TemplateElement: 'TemplateElement',
162 TemplateLiteral: 'TemplateLiteral',
163 ThisExpression: 'ThisExpression',
164 ThrowStatement: 'ThrowStatement',
165 TryStatement: 'TryStatement',
166 UnaryExpression: 'UnaryExpression',
167 UpdateExpression: 'UpdateExpression',
168 VariableDeclaration: 'VariableDeclaration',
169 VariableDeclarator: 'VariableDeclarator',
170 WhileStatement: 'WhileStatement',
171 WithStatement: 'WithStatement',
172 YieldExpression: 'YieldExpression'
176 ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder'
179 // Error messages should be identical to V8.
181 UnexpectedToken: 'Unexpected token %0',
182 UnexpectedNumber: 'Unexpected number',
183 UnexpectedString: 'Unexpected string',
184 UnexpectedIdentifier: 'Unexpected identifier',
185 UnexpectedReserved: 'Unexpected reserved word',
186 UnexpectedTemplate: 'Unexpected quasi %0',
187 UnexpectedEOS: 'Unexpected end of input',
188 NewlineAfterThrow: 'Illegal newline after throw',
189 InvalidRegExp: 'Invalid regular expression',
190 UnterminatedRegExp: 'Invalid regular expression: missing /',
191 InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
192 InvalidLHSInForIn: 'Invalid left-hand side in for-in',
193 InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
194 MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
195 NoCatchOrFinally: 'Missing catch or finally after try',
196 UnknownLabel: 'Undefined label \'%0\'',
197 Redeclaration: '%0 \'%1\' has already been declared',
198 IllegalContinue: 'Illegal continue statement',
199 IllegalBreak: 'Illegal break statement',
200 IllegalReturn: 'Illegal return statement',
201 StrictModeWith: 'Strict mode code may not include a with statement',
202 StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
203 StrictVarName: 'Variable name may not be eval or arguments in strict mode',
204 StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
205 StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
206 StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
207 StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
208 StrictDelete: 'Delete of an unqualified identifier in strict mode.',
209 StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
210 StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
211 StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
212 StrictReservedWord: 'Use of future reserved word in strict mode',
213 TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
214 ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
215 DefaultRestParameter: 'Unexpected token =',
216 ObjectPatternAsRestParameter: 'Unexpected token {',
217 DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
218 ConstructorSpecialMethod: 'Class constructor may not be an accessor',
219 DuplicateConstructor: 'A class may only have one constructor',
220 StaticPrototype: 'Classes may not have static property named prototype',
221 MissingFromClause: 'Unexpected token',
222 NoAsAfterImportNamespace: 'Unexpected token',
223 InvalidModuleSpecifier: 'Unexpected token',
224 IllegalImportDeclaration: 'Unexpected token',
225 IllegalExportDeclaration: 'Unexpected token',
226 DuplicateBinding: 'Duplicate binding %0'
229 // See also tools/generate-unicode-regex.js.
231 // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:
232 NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,
234 // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:
235 NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
238 // Ensure the condition is true, otherwise throw an error.
239 // This is only to have a better contract semantic, i.e. another safety net
240 // to catch a logic error. The condition shall be fulfilled in normal case.
241 // Do NOT use this to enforce a certain condition on any user input.
243 function assert(condition, message) {
244 /* istanbul ignore if */
246 throw new Error('ASSERT: ' + message);
250 function isDecimalDigit(ch) {
251 return (ch >= 0x30 && ch <= 0x39); // 0..9
254 function isHexDigit(ch) {
255 return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
258 function isOctalDigit(ch) {
259 return '01234567'.indexOf(ch) >= 0;
262 function octalToDecimal(ch) {
263 // \0 is not octal escape sequence
264 var octal = (ch !== '0'), code = '01234567'.indexOf(ch);
266 if (index < length && isOctalDigit(source[index])) {
268 code = code * 8 + '01234567'.indexOf(source[index++]);
270 // 3 digits are only allowed when string starts
272 if ('0123'.indexOf(ch) >= 0 &&
274 isOctalDigit(source[index])) {
275 code = code * 8 + '01234567'.indexOf(source[index++]);
285 // ECMA-262 11.2 White Space
287 function isWhiteSpace(ch) {
288 return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
289 (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
292 // ECMA-262 11.3 Line Terminators
294 function isLineTerminator(ch) {
295 return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
298 // ECMA-262 11.6 Identifier Names and Identifiers
300 function fromCodePoint(cp) {
301 return (cp < 0x10000) ? String.fromCharCode(cp) :
302 String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
303 String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
306 function isIdentifierStart(ch) {
307 return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
308 (ch >= 0x41 && ch <= 0x5A) || // A..Z
309 (ch >= 0x61 && ch <= 0x7A) || // a..z
310 (ch === 0x5C) || // \ (backslash)
311 ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)));
314 function isIdentifierPart(ch) {
315 return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
316 (ch >= 0x41 && ch <= 0x5A) || // A..Z
317 (ch >= 0x61 && ch <= 0x7A) || // a..z
318 (ch >= 0x30 && ch <= 0x39) || // 0..9
319 (ch === 0x5C) || // \ (backslash)
320 ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)));
323 // ECMA-262 11.6.2.2 Future Reserved Words
325 function isFutureReservedWord(id) {
337 function isStrictModeReservedWord(id) {
354 function isRestrictedWord(id) {
355 return id === 'eval' || id === 'arguments';
358 // ECMA-262 11.6.2.1 Keywords
360 function isKeyword(id) {
362 // 'const' is specialized as Keyword in V8.
363 // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next.
364 // Some others are from future reserved words.
368 return (id === 'if') || (id === 'in') || (id === 'do');
370 return (id === 'var') || (id === 'for') || (id === 'new') ||
371 (id === 'try') || (id === 'let');
373 return (id === 'this') || (id === 'else') || (id === 'case') ||
374 (id === 'void') || (id === 'with') || (id === 'enum');
376 return (id === 'while') || (id === 'break') || (id === 'catch') ||
377 (id === 'throw') || (id === 'const') || (id === 'yield') ||
378 (id === 'class') || (id === 'super');
380 return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
381 (id === 'switch') || (id === 'export') || (id === 'import');
383 return (id === 'default') || (id === 'finally') || (id === 'extends');
385 return (id === 'function') || (id === 'continue') || (id === 'debugger');
387 return (id === 'instanceof');
393 // ECMA-262 11.4 Comments
395 function addComment(type, value, start, end, loc) {
398 assert(typeof start === 'number', 'Comment must have valid position');
400 state.lastCommentStart = start;
407 comment.range = [start, end];
412 extra.comments.push(comment);
413 if (extra.attachComment) {
414 extra.leadingComments.push(comment);
415 extra.trailingComments.push(comment);
419 function skipSingleLineComment(offset) {
420 var start, loc, ch, comment;
422 start = index - offset;
426 column: index - lineStart - offset
430 while (index < length) {
431 ch = source.charCodeAt(index);
433 if (isLineTerminator(ch)) {
434 hasLineTerminator = true;
435 if (extra.comments) {
436 comment = source.slice(start + offset, index - 1);
439 column: index - lineStart - 1
441 addComment('Line', comment, start, index - 1, loc);
443 if (ch === 13 && source.charCodeAt(index) === 10) {
452 if (extra.comments) {
453 comment = source.slice(start + offset, index);
456 column: index - lineStart
458 addComment('Line', comment, start, index, loc);
462 function skipMultiLineComment() {
463 var start, loc, ch, comment;
465 if (extra.comments) {
470 column: index - lineStart - 2
475 while (index < length) {
476 ch = source.charCodeAt(index);
477 if (isLineTerminator(ch)) {
478 if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
481 hasLineTerminator = true;
485 } else if (ch === 0x2A) {
486 // Block comment ends with '*/'.
487 if (source.charCodeAt(index + 1) === 0x2F) {
490 if (extra.comments) {
491 comment = source.slice(start + 2, index - 2);
494 column: index - lineStart
496 addComment('Block', comment, start, index, loc);
506 // Ran off the end of the file - the whole thing is a comment
507 if (extra.comments) {
510 column: index - lineStart
512 comment = source.slice(start + 2, index);
513 addComment('Block', comment, start, index, loc);
515 tolerateUnexpectedToken();
518 function skipComment() {
520 hasLineTerminator = false;
522 start = (index === 0);
523 while (index < length) {
524 ch = source.charCodeAt(index);
526 if (isWhiteSpace(ch)) {
528 } else if (isLineTerminator(ch)) {
529 hasLineTerminator = true;
531 if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
537 } else if (ch === 0x2F) { // U+002F is '/'
538 ch = source.charCodeAt(index + 1);
542 skipSingleLineComment(2);
544 } else if (ch === 0x2A) { // U+002A is '*'
547 skipMultiLineComment();
551 } else if (start && ch === 0x2D) { // U+002D is '-'
553 if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
554 // '-->' is a single-line comment
556 skipSingleLineComment(3);
560 } else if (ch === 0x3C) { // U+003C is '<'
561 if (source.slice(index + 1, index + 4) === '!--') {
566 skipSingleLineComment(4);
576 function scanHexEscape(prefix) {
577 var i, len, ch, code = 0;
579 len = (prefix === 'u') ? 4 : 2;
580 for (i = 0; i < len; ++i) {
581 if (index < length && isHexDigit(source[index])) {
582 ch = source[index++];
583 code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
588 return String.fromCharCode(code);
591 function scanUnicodeCodePointEscape() {
597 // At least, one hex digit is required.
599 throwUnexpectedToken();
602 while (index < length) {
603 ch = source[index++];
604 if (!isHexDigit(ch)) {
607 code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
610 if (code > 0x10FFFF || ch !== '}') {
611 throwUnexpectedToken();
614 return fromCodePoint(code);
617 function codePointAt(i) {
618 var cp, first, second;
620 cp = source.charCodeAt(i);
621 if (cp >= 0xD800 && cp <= 0xDBFF) {
622 second = source.charCodeAt(i + 1);
623 if (second >= 0xDC00 && second <= 0xDFFF) {
625 cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
632 function getComplexIdentifier() {
635 cp = codePointAt(index);
636 id = fromCodePoint(cp);
639 // '\u' (U+005C, U+0075) denotes an escaped character.
641 if (source.charCodeAt(index) !== 0x75) {
642 throwUnexpectedToken();
645 if (source[index] === '{') {
647 ch = scanUnicodeCodePointEscape();
649 ch = scanHexEscape('u');
650 cp = ch.charCodeAt(0);
651 if (!ch || ch === '\\' || !isIdentifierStart(cp)) {
652 throwUnexpectedToken();
658 while (index < length) {
659 cp = codePointAt(index);
660 if (!isIdentifierPart(cp)) {
663 ch = fromCodePoint(cp);
667 // '\u' (U+005C, U+0075) denotes an escaped character.
669 id = id.substr(0, id.length - 1);
670 if (source.charCodeAt(index) !== 0x75) {
671 throwUnexpectedToken();
674 if (source[index] === '{') {
676 ch = scanUnicodeCodePointEscape();
678 ch = scanHexEscape('u');
679 cp = ch.charCodeAt(0);
680 if (!ch || ch === '\\' || !isIdentifierPart(cp)) {
681 throwUnexpectedToken();
691 function getIdentifier() {
695 while (index < length) {
696 ch = source.charCodeAt(index);
698 // Blackslash (U+005C) marks Unicode escape sequence.
700 return getComplexIdentifier();
701 } else if (ch >= 0xD800 && ch < 0xDFFF) {
702 // Need to handle surrogate pairs.
704 return getComplexIdentifier();
706 if (isIdentifierPart(ch)) {
713 return source.slice(start, index);
716 function scanIdentifier() {
721 // Backslash (U+005C) starts an escaped character.
722 id = (source.charCodeAt(index) === 0x5C) ? getComplexIdentifier() : getIdentifier();
724 // There is no keyword or literal with only one character.
725 // Thus, it must be an identifier.
726 if (id.length === 1) {
727 type = Token.Identifier;
728 } else if (isKeyword(id)) {
729 type = Token.Keyword;
730 } else if (id === 'null') {
731 type = Token.NullLiteral;
732 } else if (id === 'true' || id === 'false') {
733 type = Token.BooleanLiteral;
735 type = Token.Identifier;
741 lineNumber: lineNumber,
742 lineStart: lineStart,
749 // ECMA-262 11.7 Punctuators
751 function scanPunctuator() {
755 type: Token.Punctuator,
757 lineNumber: lineNumber,
758 lineStart: lineStart,
763 // Check for most common single-character punctuators.
768 if (extra.tokenize) {
769 extra.openParenToken = extra.tokens.length;
775 if (extra.tokenize) {
776 extra.openCurlyToken = extra.tokens.length;
778 state.curlyStack.push('{');
784 if (source[index] === '.' && source[index + 1] === '.') {
785 // Spread operator: ...
793 state.curlyStack.pop();
807 // 4-character punctuator.
808 str = source.substr(index, 4);
809 if (str === '>>>=') {
813 // 3-character punctuators.
814 str = str.substr(0, 3);
815 if (str === '===' || str === '!==' || str === '>>>' ||
816 str === '<<=' || str === '>>=') {
820 // 2-character punctuators.
821 str = str.substr(0, 2);
822 if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
823 str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
824 str === '++' || str === '--' || str === '<<' || str === '>>' ||
825 str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
826 str === '<=' || str === '>=' || str === '=>') {
830 // 1-character punctuators.
832 if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
840 if (index === token.start) {
841 throwUnexpectedToken();
849 // ECMA-262 11.8.3 Numeric Literals
851 function scanHexLiteral(start) {
854 while (index < length) {
855 if (!isHexDigit(source[index])) {
858 number += source[index++];
861 if (number.length === 0) {
862 throwUnexpectedToken();
865 if (isIdentifierStart(source.charCodeAt(index))) {
866 throwUnexpectedToken();
870 type: Token.NumericLiteral,
871 value: parseInt('0x' + number, 16),
872 lineNumber: lineNumber,
873 lineStart: lineStart,
879 function scanBinaryLiteral(start) {
884 while (index < length) {
886 if (ch !== '0' && ch !== '1') {
889 number += source[index++];
892 if (number.length === 0) {
894 throwUnexpectedToken();
897 if (index < length) {
898 ch = source.charCodeAt(index);
899 /* istanbul ignore else */
900 if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
901 throwUnexpectedToken();
906 type: Token.NumericLiteral,
907 value: parseInt(number, 2),
908 lineNumber: lineNumber,
909 lineStart: lineStart,
915 function scanOctalLiteral(prefix, start) {
918 if (isOctalDigit(prefix)) {
920 number = '0' + source[index++];
927 while (index < length) {
928 if (!isOctalDigit(source[index])) {
931 number += source[index++];
934 if (!octal && number.length === 0) {
936 throwUnexpectedToken();
939 if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
940 throwUnexpectedToken();
944 type: Token.NumericLiteral,
945 value: parseInt(number, 8),
947 lineNumber: lineNumber,
948 lineStart: lineStart,
954 function isImplicitOctalLiteral() {
957 // Implicit octal, unless there is a non-octal digit.
958 // (Annex B.1.1 on Numeric Literals)
959 for (i = index + 1; i < length; ++i) {
961 if (ch === '8' || ch === '9') {
964 if (!isOctalDigit(ch)) {
972 function scanNumericLiteral() {
973 var number, start, ch;
976 assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
977 'Numeric literal must start with a decimal digit or a decimal point');
982 number = source[index++];
985 // Hex number starts with '0x'.
986 // Octal number starts with '0'.
987 // Octal number in ES6 starts with '0o'.
988 // Binary number in ES6 starts with '0b'.
989 if (number === '0') {
990 if (ch === 'x' || ch === 'X') {
992 return scanHexLiteral(start);
994 if (ch === 'b' || ch === 'B') {
996 return scanBinaryLiteral(start);
998 if (ch === 'o' || ch === 'O') {
999 return scanOctalLiteral(ch, start);
1002 if (isOctalDigit(ch)) {
1003 if (isImplicitOctalLiteral()) {
1004 return scanOctalLiteral(ch, start);
1009 while (isDecimalDigit(source.charCodeAt(index))) {
1010 number += source[index++];
1016 number += source[index++];
1017 while (isDecimalDigit(source.charCodeAt(index))) {
1018 number += source[index++];
1023 if (ch === 'e' || ch === 'E') {
1024 number += source[index++];
1027 if (ch === '+' || ch === '-') {
1028 number += source[index++];
1030 if (isDecimalDigit(source.charCodeAt(index))) {
1031 while (isDecimalDigit(source.charCodeAt(index))) {
1032 number += source[index++];
1035 throwUnexpectedToken();
1039 if (isIdentifierStart(source.charCodeAt(index))) {
1040 throwUnexpectedToken();
1044 type: Token.NumericLiteral,
1045 value: parseFloat(number),
1046 lineNumber: lineNumber,
1047 lineStart: lineStart,
1053 // ECMA-262 11.8.4 String Literals
1055 function scanStringLiteral() {
1056 var str = '', quote, start, ch, unescaped, octToDec, octal = false;
1058 quote = source[index];
1059 assert((quote === '\'' || quote === '"'),
1060 'String literal must starts with a quote');
1065 while (index < length) {
1066 ch = source[index++];
1071 } else if (ch === '\\') {
1072 ch = source[index++];
1073 if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
1077 if (source[index] === '{') {
1079 str += scanUnicodeCodePointEscape();
1081 unescaped = scanHexEscape(ch);
1083 throw throwUnexpectedToken();
1109 tolerateUnexpectedToken();
1113 if (isOctalDigit(ch)) {
1114 octToDec = octalToDecimal(ch);
1116 octal = octToDec.octal || octal;
1117 str += String.fromCharCode(octToDec.code);
1125 if (ch === '\r' && source[index] === '\n') {
1130 } else if (isLineTerminator(ch.charCodeAt(0))) {
1138 throwUnexpectedToken();
1142 type: Token.StringLiteral,
1145 lineNumber: startLineNumber,
1146 lineStart: startLineStart,
1152 // ECMA-262 11.8.6 Template Literal Lexical Components
1154 function scanTemplate() {
1155 var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped;
1160 head = (source[index] === '`');
1165 while (index < length) {
1166 ch = source[index++];
1172 } else if (ch === '$') {
1173 if (source[index] === '{') {
1174 state.curlyStack.push('${');
1180 } else if (ch === '\\') {
1181 ch = source[index++];
1182 if (!isLineTerminator(ch.charCodeAt(0))) {
1195 if (source[index] === '{') {
1197 cooked += scanUnicodeCodePointEscape();
1200 unescaped = scanHexEscape(ch);
1202 cooked += unescaped;
1221 if (isDecimalDigit(source.charCodeAt(index))) {
1222 // Illegal: \01 \02 and so on
1223 throwError(Messages.TemplateOctalLiteral);
1226 } else if (isOctalDigit(ch)) {
1228 throwError(Messages.TemplateOctalLiteral);
1236 if (ch === '\r' && source[index] === '\n') {
1241 } else if (isLineTerminator(ch.charCodeAt(0))) {
1243 if (ch === '\r' && source[index] === '\n') {
1254 throwUnexpectedToken();
1258 state.curlyStack.pop();
1262 type: Token.Template,
1265 raw: source.slice(start + 1, index - rawOffset)
1269 lineNumber: lineNumber,
1270 lineStart: lineStart,
1276 // ECMA-262 11.8.5 Regular Expression Literals
1278 function testRegExp(pattern, flags) {
1279 // The BMP character to use as a replacement for astral symbols when
1280 // translating an ES6 "u"-flagged pattern to an ES5-compatible
1282 // Note: replacing with '\uFFFF' enables false positives in unlikely
1283 // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
1284 // pattern that would not be detected by this substitution.
1285 var astralSubstitute = '\uFFFF',
1288 if (flags.indexOf('u') >= 0) {
1290 // Replace every Unicode escape sequence with the equivalent
1291 // BMP character or a constant ASCII code point in the case of
1292 // astral symbols. (See the above note on `astralSubstitute`
1293 // for more information.)
1294 .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
1295 var codePoint = parseInt($1 || $2, 16);
1296 if (codePoint > 0x10FFFF) {
1297 throwUnexpectedToken(null, Messages.InvalidRegExp);
1299 if (codePoint <= 0xFFFF) {
1300 return String.fromCharCode(codePoint);
1302 return astralSubstitute;
1304 // Replace each paired surrogate with a single ASCII symbol to
1305 // avoid throwing on regular expressions that are only valid in
1306 // combination with the "u" flag.
1308 /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
1313 // First, detect invalid regular expressions.
1317 throwUnexpectedToken(null, Messages.InvalidRegExp);
1320 // Return a regular expression object for this pattern-flag pair, or
1321 // `null` in case the current environment doesn't support the flags it
1324 return new RegExp(pattern, flags);
1325 } catch (exception) {
1330 function scanRegExpBody() {
1331 var ch, str, classMarker, terminated, body;
1334 assert(ch === '/', 'Regular expression literal must start with a slash');
1335 str = source[index++];
1337 classMarker = false;
1339 while (index < length) {
1340 ch = source[index++];
1343 ch = source[index++];
1345 if (isLineTerminator(ch.charCodeAt(0))) {
1346 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
1349 } else if (isLineTerminator(ch.charCodeAt(0))) {
1350 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
1351 } else if (classMarker) {
1353 classMarker = false;
1359 } else if (ch === '[') {
1366 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
1369 // Exclude leading and trailing slash.
1370 body = str.substr(1, str.length - 2);
1377 function scanRegExpFlags() {
1378 var ch, str, flags, restore;
1382 while (index < length) {
1384 if (!isIdentifierPart(ch.charCodeAt(0))) {
1389 if (ch === '\\' && index < length) {
1394 ch = scanHexEscape('u');
1397 for (str += '\\u'; restore < index; ++restore) {
1398 str += source[restore];
1405 tolerateUnexpectedToken();
1408 tolerateUnexpectedToken();
1422 function scanRegExp() {
1424 var start, body, flags, value;
1430 body = scanRegExpBody();
1431 flags = scanRegExpFlags();
1432 value = testRegExp(body.value, flags.value);
1434 if (extra.tokenize) {
1436 type: Token.RegularExpression,
1439 pattern: body.value,
1442 lineNumber: lineNumber,
1443 lineStart: lineStart,
1450 literal: body.literal + flags.literal,
1453 pattern: body.value,
1461 function collectRegex() {
1462 var pos, loc, regex, token;
1470 column: index - lineStart
1474 regex = scanRegExp();
1478 column: index - lineStart
1481 /* istanbul ignore next */
1482 if (!extra.tokenize) {
1483 // Pop the previous token, which is likely '/' or '/='
1484 if (extra.tokens.length > 0) {
1485 token = extra.tokens[extra.tokens.length - 1];
1486 if (token.range[0] === pos && token.type === 'Punctuator') {
1487 if (token.value === '/' || token.value === '/=') {
1494 type: 'RegularExpression',
1495 value: regex.literal,
1497 range: [pos, index],
1505 function isIdentifierName(token) {
1506 return token.type === Token.Identifier ||
1507 token.type === Token.Keyword ||
1508 token.type === Token.BooleanLiteral ||
1509 token.type === Token.NullLiteral;
1512 function advanceSlash() {
1515 // Using the following algorithm:
1516 // https://github.com/mozilla/sweet.js/wiki/design
1517 prevToken = extra.tokens[extra.tokens.length - 1];
1519 // Nothing before that: it cannot be a division.
1520 return collectRegex();
1522 if (prevToken.type === 'Punctuator') {
1523 if (prevToken.value === ']') {
1524 return scanPunctuator();
1526 if (prevToken.value === ')') {
1527 checkToken = extra.tokens[extra.openParenToken - 1];
1529 checkToken.type === 'Keyword' &&
1530 (checkToken.value === 'if' ||
1531 checkToken.value === 'while' ||
1532 checkToken.value === 'for' ||
1533 checkToken.value === 'with')) {
1534 return collectRegex();
1536 return scanPunctuator();
1538 if (prevToken.value === '}') {
1539 // Dividing a function by anything makes little sense,
1540 // but we have to check for that.
1541 if (extra.tokens[extra.openCurlyToken - 3] &&
1542 extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
1543 // Anonymous function.
1544 checkToken = extra.tokens[extra.openCurlyToken - 4];
1546 return scanPunctuator();
1548 } else if (extra.tokens[extra.openCurlyToken - 4] &&
1549 extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
1551 checkToken = extra.tokens[extra.openCurlyToken - 5];
1553 return collectRegex();
1556 return scanPunctuator();
1558 // checkToken determines whether the function is
1559 // a declaration or an expression.
1560 if (FnExprTokens.indexOf(checkToken.value) >= 0) {
1561 // It is an expression.
1562 return scanPunctuator();
1564 // It is a declaration.
1565 return collectRegex();
1567 return collectRegex();
1569 if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
1570 return collectRegex();
1572 return scanPunctuator();
1575 function advance() {
1578 if (index >= length) {
1581 lineNumber: lineNumber,
1582 lineStart: lineStart,
1588 cp = source.charCodeAt(index);
1590 if (isIdentifierStart(cp)) {
1591 token = scanIdentifier();
1592 if (strict && isStrictModeReservedWord(token.value)) {
1593 token.type = Token.Keyword;
1598 // Very common: ( and ) and ;
1599 if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
1600 return scanPunctuator();
1603 // String literal starts with single quote (U+0027) or double quote (U+0022).
1604 if (cp === 0x27 || cp === 0x22) {
1605 return scanStringLiteral();
1608 // Dot (.) U+002E can also start a floating-point number, hence the need
1609 // to check the next character.
1611 if (isDecimalDigit(source.charCodeAt(index + 1))) {
1612 return scanNumericLiteral();
1614 return scanPunctuator();
1617 if (isDecimalDigit(cp)) {
1618 return scanNumericLiteral();
1621 // Slash (/) U+002F can also start a regex.
1622 if (extra.tokenize && cp === 0x2F) {
1623 return advanceSlash();
1626 // Template literals start with ` (U+0060) for template head
1627 // or } (U+007D) for template middle or template tail.
1628 if (cp === 0x60 || (cp === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) {
1629 return scanTemplate();
1632 // Possible identifier start in a surrogate pair.
1633 if (cp >= 0xD800 && cp < 0xDFFF) {
1634 cp = codePointAt(index);
1635 if (isIdentifierStart(cp)) {
1636 return scanIdentifier();
1640 return scanPunctuator();
1643 function collectToken() {
1644 var loc, token, value, entry;
1649 column: index - lineStart
1656 column: index - lineStart
1659 if (token.type !== Token.EOF) {
1660 value = source.slice(token.start, token.end);
1662 type: TokenName[token.type],
1664 range: [token.start, token.end],
1669 pattern: token.regex.pattern,
1670 flags: token.regex.flags
1673 extra.tokens.push(entry);
1684 lastLineNumber = lineNumber;
1685 lastLineStart = lineStart;
1692 startLineNumber = lineNumber;
1693 startLineStart = lineStart;
1695 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1706 lastLineNumber = lineNumber;
1707 lastLineStart = lineStart;
1710 startLineNumber = lineNumber;
1711 startLineStart = lineStart;
1713 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1717 function Position() {
1718 this.line = startLineNumber;
1719 this.column = startIndex - startLineStart;
1722 function SourceLocation() {
1723 this.start = new Position();
1727 function WrappingSourceLocation(startToken) {
1729 line: startToken.lineNumber,
1730 column: startToken.start - startToken.lineStart
1737 this.range = [startIndex, 0];
1740 this.loc = new SourceLocation();
1744 function WrappingNode(startToken) {
1746 this.range = [startToken.start, 0];
1749 this.loc = new WrappingSourceLocation(startToken);
1753 WrappingNode.prototype = Node.prototype = {
1755 processComment: function () {
1759 bottomRight = extra.bottomRightStack,
1762 last = bottomRight[bottomRight.length - 1];
1764 if (this.type === Syntax.Program) {
1765 if (this.body.length > 0) {
1770 if (extra.trailingComments.length > 0) {
1771 trailingComments = [];
1772 for (i = extra.trailingComments.length - 1; i >= 0; --i) {
1773 comment = extra.trailingComments[i];
1774 if (comment.range[0] >= this.range[1]) {
1775 trailingComments.unshift(comment);
1776 extra.trailingComments.splice(i, 1);
1779 extra.trailingComments = [];
1781 if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) {
1782 trailingComments = last.trailingComments;
1783 delete last.trailingComments;
1787 // Eating the stack.
1788 while (last && last.range[0] >= this.range[0]) {
1789 lastChild = bottomRight.pop();
1790 last = bottomRight[bottomRight.length - 1];
1794 if (lastChild.leadingComments) {
1795 leadingComments = [];
1796 for (i = lastChild.leadingComments.length - 1; i >= 0; --i) {
1797 comment = lastChild.leadingComments[i];
1798 if (comment.range[1] <= this.range[0]) {
1799 leadingComments.unshift(comment);
1800 lastChild.leadingComments.splice(i, 1);
1804 if (!lastChild.leadingComments.length) {
1805 lastChild.leadingComments = undefined;
1808 } else if (extra.leadingComments.length > 0) {
1809 leadingComments = [];
1810 for (i = extra.leadingComments.length - 1; i >= 0; --i) {
1811 comment = extra.leadingComments[i];
1812 if (comment.range[1] <= this.range[0]) {
1813 leadingComments.unshift(comment);
1814 extra.leadingComments.splice(i, 1);
1820 if (leadingComments && leadingComments.length > 0) {
1821 this.leadingComments = leadingComments;
1823 if (trailingComments && trailingComments.length > 0) {
1824 this.trailingComments = trailingComments;
1827 bottomRight.push(this);
1830 finish: function () {
1832 this.range[1] = lastIndex;
1836 line: lastLineNumber,
1837 column: lastIndex - lastLineStart
1840 this.loc.source = extra.source;
1844 if (extra.attachComment) {
1845 this.processComment();
1849 finishArrayExpression: function (elements) {
1850 this.type = Syntax.ArrayExpression;
1851 this.elements = elements;
1856 finishArrayPattern: function (elements) {
1857 this.type = Syntax.ArrayPattern;
1858 this.elements = elements;
1863 finishArrowFunctionExpression: function (params, defaults, body, expression) {
1864 this.type = Syntax.ArrowFunctionExpression;
1866 this.params = params;
1867 this.defaults = defaults;
1869 this.generator = false;
1870 this.expression = expression;
1875 finishAssignmentExpression: function (operator, left, right) {
1876 this.type = Syntax.AssignmentExpression;
1877 this.operator = operator;
1884 finishAssignmentPattern: function (left, right) {
1885 this.type = Syntax.AssignmentPattern;
1892 finishBinaryExpression: function (operator, left, right) {
1893 this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression;
1894 this.operator = operator;
1901 finishBlockStatement: function (body) {
1902 this.type = Syntax.BlockStatement;
1908 finishBreakStatement: function (label) {
1909 this.type = Syntax.BreakStatement;
1915 finishCallExpression: function (callee, args) {
1916 this.type = Syntax.CallExpression;
1917 this.callee = callee;
1918 this.arguments = args;
1923 finishCatchClause: function (param, body) {
1924 this.type = Syntax.CatchClause;
1931 finishClassBody: function (body) {
1932 this.type = Syntax.ClassBody;
1938 finishClassDeclaration: function (id, superClass, body) {
1939 this.type = Syntax.ClassDeclaration;
1941 this.superClass = superClass;
1947 finishClassExpression: function (id, superClass, body) {
1948 this.type = Syntax.ClassExpression;
1950 this.superClass = superClass;
1956 finishConditionalExpression: function (test, consequent, alternate) {
1957 this.type = Syntax.ConditionalExpression;
1959 this.consequent = consequent;
1960 this.alternate = alternate;
1965 finishContinueStatement: function (label) {
1966 this.type = Syntax.ContinueStatement;
1972 finishDebuggerStatement: function () {
1973 this.type = Syntax.DebuggerStatement;
1978 finishDoWhileStatement: function (body, test) {
1979 this.type = Syntax.DoWhileStatement;
1986 finishEmptyStatement: function () {
1987 this.type = Syntax.EmptyStatement;
1992 finishExpressionStatement: function (expression) {
1993 this.type = Syntax.ExpressionStatement;
1994 this.expression = expression;
1999 finishForStatement: function (init, test, update, body) {
2000 this.type = Syntax.ForStatement;
2003 this.update = update;
2009 finishForOfStatement: function (left, right, body) {
2010 this.type = Syntax.ForOfStatement;
2018 finishForInStatement: function (left, right, body) {
2019 this.type = Syntax.ForInStatement;
2028 finishFunctionDeclaration: function (id, params, defaults, body, generator) {
2029 this.type = Syntax.FunctionDeclaration;
2031 this.params = params;
2032 this.defaults = defaults;
2034 this.generator = generator;
2035 this.expression = false;
2040 finishFunctionExpression: function (id, params, defaults, body, generator) {
2041 this.type = Syntax.FunctionExpression;
2043 this.params = params;
2044 this.defaults = defaults;
2046 this.generator = generator;
2047 this.expression = false;
2052 finishIdentifier: function (name) {
2053 this.type = Syntax.Identifier;
2059 finishIfStatement: function (test, consequent, alternate) {
2060 this.type = Syntax.IfStatement;
2062 this.consequent = consequent;
2063 this.alternate = alternate;
2068 finishLabeledStatement: function (label, body) {
2069 this.type = Syntax.LabeledStatement;
2076 finishLiteral: function (token) {
2077 this.type = Syntax.Literal;
2078 this.value = token.value;
2079 this.raw = source.slice(token.start, token.end);
2081 this.regex = token.regex;
2087 finishMemberExpression: function (accessor, object, property) {
2088 this.type = Syntax.MemberExpression;
2089 this.computed = accessor === '[';
2090 this.object = object;
2091 this.property = property;
2096 finishMetaProperty: function (meta, property) {
2097 this.type = Syntax.MetaProperty;
2099 this.property = property;
2104 finishNewExpression: function (callee, args) {
2105 this.type = Syntax.NewExpression;
2106 this.callee = callee;
2107 this.arguments = args;
2112 finishObjectExpression: function (properties) {
2113 this.type = Syntax.ObjectExpression;
2114 this.properties = properties;
2119 finishObjectPattern: function (properties) {
2120 this.type = Syntax.ObjectPattern;
2121 this.properties = properties;
2126 finishPostfixExpression: function (operator, argument) {
2127 this.type = Syntax.UpdateExpression;
2128 this.operator = operator;
2129 this.argument = argument;
2130 this.prefix = false;
2135 finishProgram: function (body) {
2136 this.type = Syntax.Program;
2138 if (sourceType === 'module') {
2139 // very restrictive for now
2140 this.sourceType = sourceType;
2146 finishProperty: function (kind, key, computed, value, method, shorthand) {
2147 this.type = Syntax.Property;
2149 this.computed = computed;
2152 this.method = method;
2153 this.shorthand = shorthand;
2158 finishRestElement: function (argument) {
2159 this.type = Syntax.RestElement;
2160 this.argument = argument;
2165 finishReturnStatement: function (argument) {
2166 this.type = Syntax.ReturnStatement;
2167 this.argument = argument;
2172 finishSequenceExpression: function (expressions) {
2173 this.type = Syntax.SequenceExpression;
2174 this.expressions = expressions;
2179 finishSpreadElement: function (argument) {
2180 this.type = Syntax.SpreadElement;
2181 this.argument = argument;
2186 finishSwitchCase: function (test, consequent) {
2187 this.type = Syntax.SwitchCase;
2189 this.consequent = consequent;
2194 finishSuper: function () {
2195 this.type = Syntax.Super;
2200 finishSwitchStatement: function (discriminant, cases) {
2201 this.type = Syntax.SwitchStatement;
2202 this.discriminant = discriminant;
2208 finishTaggedTemplateExpression: function (tag, quasi) {
2209 this.type = Syntax.TaggedTemplateExpression;
2216 finishTemplateElement: function (value, tail) {
2217 this.type = Syntax.TemplateElement;
2224 finishTemplateLiteral: function (quasis, expressions) {
2225 this.type = Syntax.TemplateLiteral;
2226 this.quasis = quasis;
2227 this.expressions = expressions;
2232 finishThisExpression: function () {
2233 this.type = Syntax.ThisExpression;
2238 finishThrowStatement: function (argument) {
2239 this.type = Syntax.ThrowStatement;
2240 this.argument = argument;
2245 finishTryStatement: function (block, handler, finalizer) {
2246 this.type = Syntax.TryStatement;
2248 this.guardedHandlers = [];
2249 this.handlers = handler ? [ handler ] : [];
2250 this.handler = handler;
2251 this.finalizer = finalizer;
2256 finishUnaryExpression: function (operator, argument) {
2257 this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression;
2258 this.operator = operator;
2259 this.argument = argument;
2265 finishVariableDeclaration: function (declarations) {
2266 this.type = Syntax.VariableDeclaration;
2267 this.declarations = declarations;
2273 finishLexicalDeclaration: function (declarations, kind) {
2274 this.type = Syntax.VariableDeclaration;
2275 this.declarations = declarations;
2281 finishVariableDeclarator: function (id, init) {
2282 this.type = Syntax.VariableDeclarator;
2289 finishWhileStatement: function (test, body) {
2290 this.type = Syntax.WhileStatement;
2297 finishWithStatement: function (object, body) {
2298 this.type = Syntax.WithStatement;
2299 this.object = object;
2305 finishExportSpecifier: function (local, exported) {
2306 this.type = Syntax.ExportSpecifier;
2307 this.exported = exported || local;
2313 finishImportDefaultSpecifier: function (local) {
2314 this.type = Syntax.ImportDefaultSpecifier;
2320 finishImportNamespaceSpecifier: function (local) {
2321 this.type = Syntax.ImportNamespaceSpecifier;
2327 finishExportNamedDeclaration: function (declaration, specifiers, src) {
2328 this.type = Syntax.ExportNamedDeclaration;
2329 this.declaration = declaration;
2330 this.specifiers = specifiers;
2336 finishExportDefaultDeclaration: function (declaration) {
2337 this.type = Syntax.ExportDefaultDeclaration;
2338 this.declaration = declaration;
2343 finishExportAllDeclaration: function (src) {
2344 this.type = Syntax.ExportAllDeclaration;
2350 finishImportSpecifier: function (local, imported) {
2351 this.type = Syntax.ImportSpecifier;
2352 this.local = local || imported;
2353 this.imported = imported;
2358 finishImportDeclaration: function (specifiers, src) {
2359 this.type = Syntax.ImportDeclaration;
2360 this.specifiers = specifiers;
2366 finishYieldExpression: function (argument, delegate) {
2367 this.type = Syntax.YieldExpression;
2368 this.argument = argument;
2369 this.delegate = delegate;
2376 function recordError(error) {
2379 for (e = 0; e < extra.errors.length; e++) {
2380 existing = extra.errors[e];
2381 // Prevent duplicated error.
2382 /* istanbul ignore next */
2383 if (existing.index === error.index && existing.message === error.message) {
2388 extra.errors.push(error);
2391 function createError(line, pos, description) {
2392 var error = new Error('Line ' + line + ': ' + description);
2394 error.lineNumber = line;
2395 error.column = pos - (scanning ? lineStart : lastLineStart) + 1;
2396 error.description = description;
2400 // Throw an exception
2402 function throwError(messageFormat) {
2405 args = Array.prototype.slice.call(arguments, 1);
2406 msg = messageFormat.replace(/%(\d)/g,
2407 function (whole, idx) {
2408 assert(idx < args.length, 'Message reference must be in range');
2413 throw createError(lastLineNumber, lastIndex, msg);
2416 function tolerateError(messageFormat) {
2417 var args, msg, error;
2419 args = Array.prototype.slice.call(arguments, 1);
2420 /* istanbul ignore next */
2421 msg = messageFormat.replace(/%(\d)/g,
2422 function (whole, idx) {
2423 assert(idx < args.length, 'Message reference must be in range');
2428 error = createError(lineNumber, lastIndex, msg);
2436 // Throw an exception because of the token.
2438 function unexpectedTokenError(token, message) {
2439 var value, msg = message || Messages.UnexpectedToken;
2443 msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS :
2444 (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier :
2445 (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber :
2446 (token.type === Token.StringLiteral) ? Messages.UnexpectedString :
2447 (token.type === Token.Template) ? Messages.UnexpectedTemplate :
2448 Messages.UnexpectedToken;
2450 if (token.type === Token.Keyword) {
2451 if (isFutureReservedWord(token.value)) {
2452 msg = Messages.UnexpectedReserved;
2453 } else if (strict && isStrictModeReservedWord(token.value)) {
2454 msg = Messages.StrictReservedWord;
2459 value = (token.type === Token.Template) ? token.value.raw : token.value;
2464 msg = msg.replace('%0', value);
2466 return (token && typeof token.lineNumber === 'number') ?
2467 createError(token.lineNumber, token.start, msg) :
2468 createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg);
2471 function throwUnexpectedToken(token, message) {
2472 throw unexpectedTokenError(token, message);
2475 function tolerateUnexpectedToken(token, message) {
2476 var error = unexpectedTokenError(token, message);
2484 // Expect the next token to match the specified punctuator.
2485 // If not, an exception will be thrown.
2487 function expect(value) {
2489 if (token.type !== Token.Punctuator || token.value !== value) {
2490 throwUnexpectedToken(token);
2495 * @name expectCommaSeparator
2496 * @description Quietly expect a comma when in tolerant mode, otherwise delegates
2497 * to <code>expect(value)</code>
2500 function expectCommaSeparator() {
2505 if (token.type === Token.Punctuator && token.value === ',') {
2507 } else if (token.type === Token.Punctuator && token.value === ';') {
2509 tolerateUnexpectedToken(token);
2511 tolerateUnexpectedToken(token, Messages.UnexpectedToken);
2518 // Expect the next token to match the specified keyword.
2519 // If not, an exception will be thrown.
2521 function expectKeyword(keyword) {
2523 if (token.type !== Token.Keyword || token.value !== keyword) {
2524 throwUnexpectedToken(token);
2528 // Return true if the next token matches the specified punctuator.
2530 function match(value) {
2531 return lookahead.type === Token.Punctuator && lookahead.value === value;
2534 // Return true if the next token matches the specified keyword
2536 function matchKeyword(keyword) {
2537 return lookahead.type === Token.Keyword && lookahead.value === keyword;
2540 // Return true if the next token matches the specified contextual keyword
2541 // (where an identifier is sometimes a keyword depending on the context)
2543 function matchContextualKeyword(keyword) {
2544 return lookahead.type === Token.Identifier && lookahead.value === keyword;
2547 // Return true if the next token is an assignment operator
2549 function matchAssign() {
2552 if (lookahead.type !== Token.Punctuator) {
2555 op = lookahead.value;
2556 return op === '=' ||
2570 function consumeSemicolon() {
2571 // Catch the very common case first: immediately a semicolon (U+003B).
2572 if (source.charCodeAt(startIndex) === 0x3B || match(';')) {
2577 if (hasLineTerminator) {
2581 // FIXME(ikarienator): this is seemingly an issue in the previous location info convention.
2582 lastIndex = startIndex;
2583 lastLineNumber = startLineNumber;
2584 lastLineStart = startLineStart;
2586 if (lookahead.type !== Token.EOF && !match('}')) {
2587 throwUnexpectedToken(lookahead);
2591 // Cover grammar support.
2593 // When an assignment expression position starts with an left parenthesis, the determination of the type
2594 // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
2595 // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
2597 // There are three productions that can be parsed in a parentheses pair that needs to be determined
2598 // after the outermost pair is closed. They are:
2600 // 1. AssignmentExpression
2601 // 2. BindingElements
2602 // 3. AssignmentTargets
2604 // In order to avoid exponential backtracking, we use two flags to denote if the production can be
2605 // binding element or assignment target.
2607 // The three productions have the relationship:
2609 // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
2611 // with a single exception that CoverInitializedName when used directly in an Expression, generates
2612 // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
2613 // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
2615 // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
2616 // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
2617 // the CoverInitializedName check is conducted.
2619 // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
2620 // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
2621 // pattern. The CoverInitializedName check is deferred.
2622 function isolateCoverGrammar(parser) {
2623 var oldIsBindingElement = isBindingElement,
2624 oldIsAssignmentTarget = isAssignmentTarget,
2625 oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
2627 isBindingElement = true;
2628 isAssignmentTarget = true;
2629 firstCoverInitializedNameError = null;
2631 if (firstCoverInitializedNameError !== null) {
2632 throwUnexpectedToken(firstCoverInitializedNameError);
2634 isBindingElement = oldIsBindingElement;
2635 isAssignmentTarget = oldIsAssignmentTarget;
2636 firstCoverInitializedNameError = oldFirstCoverInitializedNameError;
2640 function inheritCoverGrammar(parser) {
2641 var oldIsBindingElement = isBindingElement,
2642 oldIsAssignmentTarget = isAssignmentTarget,
2643 oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
2645 isBindingElement = true;
2646 isAssignmentTarget = true;
2647 firstCoverInitializedNameError = null;
2649 isBindingElement = isBindingElement && oldIsBindingElement;
2650 isAssignmentTarget = isAssignmentTarget && oldIsAssignmentTarget;
2651 firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError;
2655 // ECMA-262 13.3.3 Destructuring Binding Patterns
2657 function parseArrayPattern(params) {
2658 var node = new Node(), elements = [], rest, restNode;
2661 while (!match(']')) {
2664 elements.push(null);
2667 restNode = new Node();
2669 params.push(lookahead);
2670 rest = parseVariableIdentifier(params);
2671 elements.push(restNode.finishRestElement(rest));
2674 elements.push(parsePatternWithDefault(params));
2685 return node.finishArrayPattern(elements);
2688 function parsePropertyPattern(params) {
2689 var node = new Node(), key, keyToken, computed = match('['), init;
2690 if (lookahead.type === Token.Identifier) {
2691 keyToken = lookahead;
2692 key = parseVariableIdentifier();
2694 params.push(keyToken);
2696 init = parseAssignmentExpression();
2698 return node.finishProperty(
2700 new WrappingNode(keyToken).finishAssignmentPattern(key, init), false, false);
2701 } else if (!match(':')) {
2702 params.push(keyToken);
2703 return node.finishProperty('init', key, false, key, false, true);
2706 key = parseObjectPropertyKey(params);
2709 init = parsePatternWithDefault(params);
2710 return node.finishProperty('init', key, computed, init, false, false);
2713 function parseObjectPattern(params) {
2714 var node = new Node(), properties = [];
2718 while (!match('}')) {
2719 properties.push(parsePropertyPattern(params));
2727 return node.finishObjectPattern(properties);
2730 function parsePattern(params) {
2732 return parseArrayPattern(params);
2733 } else if (match('{')) {
2734 return parseObjectPattern(params);
2736 params.push(lookahead);
2737 return parseVariableIdentifier();
2740 function parsePatternWithDefault(params) {
2741 var startToken = lookahead, pattern, previousAllowYield, right;
2742 pattern = parsePattern(params);
2745 previousAllowYield = state.allowYield;
2746 state.allowYield = true;
2747 right = isolateCoverGrammar(parseAssignmentExpression);
2748 state.allowYield = previousAllowYield;
2749 pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right);
2754 // ECMA-262 12.2.5 Array Initializer
2756 function parseArrayInitializer() {
2757 var elements = [], node = new Node(), restSpread;
2761 while (!match(']')) {
2764 elements.push(null);
2765 } else if (match('...')) {
2766 restSpread = new Node();
2768 restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression));
2771 isAssignmentTarget = isBindingElement = false;
2774 elements.push(restSpread);
2776 elements.push(inheritCoverGrammar(parseAssignmentExpression));
2786 return node.finishArrayExpression(elements);
2789 // ECMA-262 12.2.6 Object Initializer
2791 function parsePropertyFunction(node, paramInfo, isGenerator) {
2792 var previousStrict, body;
2794 isAssignmentTarget = isBindingElement = false;
2796 previousStrict = strict;
2797 body = isolateCoverGrammar(parseFunctionSourceElements);
2799 if (strict && paramInfo.firstRestricted) {
2800 tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message);
2802 if (strict && paramInfo.stricted) {
2803 tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message);
2806 strict = previousStrict;
2807 return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body, isGenerator);
2810 function parsePropertyMethodFunction() {
2811 var params, method, node = new Node(),
2812 previousAllowYield = state.allowYield;
2814 state.allowYield = false;
2815 params = parseParams();
2816 state.allowYield = previousAllowYield;
2818 state.allowYield = false;
2819 method = parsePropertyFunction(node, params, false);
2820 state.allowYield = previousAllowYield;
2825 function parseObjectPropertyKey() {
2826 var token, node = new Node(), expr;
2830 // Note: This function is called only from parseObjectProperty(), where
2831 // EOF and Punctuator tokens are already filtered out.
2833 switch (token.type) {
2834 case Token.StringLiteral:
2835 case Token.NumericLiteral:
2836 if (strict && token.octal) {
2837 tolerateUnexpectedToken(token, Messages.StrictOctalLiteral);
2839 return node.finishLiteral(token);
2840 case Token.Identifier:
2841 case Token.BooleanLiteral:
2842 case Token.NullLiteral:
2844 return node.finishIdentifier(token.value);
2845 case Token.Punctuator:
2846 if (token.value === '[') {
2847 expr = isolateCoverGrammar(parseAssignmentExpression);
2853 throwUnexpectedToken(token);
2856 function lookaheadPropertyName() {
2857 switch (lookahead.type) {
2858 case Token.Identifier:
2859 case Token.StringLiteral:
2860 case Token.BooleanLiteral:
2861 case Token.NullLiteral:
2862 case Token.NumericLiteral:
2865 case Token.Punctuator:
2866 return lookahead.value === '[';
2871 // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
2872 // it might be called at a position where there is in fact a short hand identifier pattern or a data property.
2873 // This can only be determined after we consumed up to the left parentheses.
2875 // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
2876 // is responsible to visit other options.
2877 function tryParseMethodDefinition(token, key, computed, node) {
2878 var value, options, methodNode, params,
2879 previousAllowYield = state.allowYield;
2881 if (token.type === Token.Identifier) {
2882 // check for `get` and `set`;
2884 if (token.value === 'get' && lookaheadPropertyName()) {
2885 computed = match('[');
2886 key = parseObjectPropertyKey();
2887 methodNode = new Node();
2891 state.allowYield = false;
2892 value = parsePropertyFunction(methodNode, {
2896 firstRestricted: null,
2899 state.allowYield = previousAllowYield;
2901 return node.finishProperty('get', key, computed, value, false, false);
2902 } else if (token.value === 'set' && lookaheadPropertyName()) {
2903 computed = match('[');
2904 key = parseObjectPropertyKey();
2905 methodNode = new Node();
2912 firstRestricted: null,
2916 tolerateUnexpectedToken(lookahead);
2918 state.allowYield = false;
2919 parseParam(options);
2920 state.allowYield = previousAllowYield;
2921 if (options.defaultCount === 0) {
2922 options.defaults = [];
2927 state.allowYield = false;
2928 value = parsePropertyFunction(methodNode, options, false);
2929 state.allowYield = previousAllowYield;
2931 return node.finishProperty('set', key, computed, value, false, false);
2933 } else if (token.type === Token.Punctuator && token.value === '*' && lookaheadPropertyName()) {
2934 computed = match('[');
2935 key = parseObjectPropertyKey();
2936 methodNode = new Node();
2938 state.allowYield = true;
2939 params = parseParams();
2940 state.allowYield = previousAllowYield;
2942 state.allowYield = false;
2943 value = parsePropertyFunction(methodNode, params, true);
2944 state.allowYield = previousAllowYield;
2946 return node.finishProperty('init', key, computed, value, true, false);
2949 if (key && match('(')) {
2950 value = parsePropertyMethodFunction();
2951 return node.finishProperty('init', key, computed, value, true, false);
2954 // Not a MethodDefinition.
2958 function parseObjectProperty(hasProto) {
2959 var token = lookahead, node = new Node(), computed, key, maybeMethod, proto, value;
2961 computed = match('[');
2965 key = parseObjectPropertyKey();
2967 maybeMethod = tryParseMethodDefinition(token, key, computed, node);
2973 throwUnexpectedToken(lookahead);
2976 // Check for duplicated __proto__
2978 proto = (key.type === Syntax.Identifier && key.name === '__proto__') ||
2979 (key.type === Syntax.Literal && key.value === '__proto__');
2980 if (hasProto.value && proto) {
2981 tolerateError(Messages.DuplicateProtoProperty);
2983 hasProto.value |= proto;
2988 value = inheritCoverGrammar(parseAssignmentExpression);
2989 return node.finishProperty('init', key, computed, value, false, false);
2992 if (token.type === Token.Identifier) {
2994 firstCoverInitializedNameError = lookahead;
2996 value = isolateCoverGrammar(parseAssignmentExpression);
2997 return node.finishProperty('init', key, computed,
2998 new WrappingNode(token).finishAssignmentPattern(key, value), false, true);
3000 return node.finishProperty('init', key, computed, key, false, true);
3003 throwUnexpectedToken(lookahead);
3006 function parseObjectInitializer() {
3007 var properties = [], hasProto = {value: false}, node = new Node();
3011 while (!match('}')) {
3012 properties.push(parseObjectProperty(hasProto));
3015 expectCommaSeparator();
3021 return node.finishObjectExpression(properties);
3024 function reinterpretExpressionAsPattern(expr) {
3026 switch (expr.type) {
3027 case Syntax.Identifier:
3028 case Syntax.MemberExpression:
3029 case Syntax.RestElement:
3030 case Syntax.AssignmentPattern:
3032 case Syntax.SpreadElement:
3033 expr.type = Syntax.RestElement;
3034 reinterpretExpressionAsPattern(expr.argument);
3036 case Syntax.ArrayExpression:
3037 expr.type = Syntax.ArrayPattern;
3038 for (i = 0; i < expr.elements.length; i++) {
3039 if (expr.elements[i] !== null) {
3040 reinterpretExpressionAsPattern(expr.elements[i]);
3044 case Syntax.ObjectExpression:
3045 expr.type = Syntax.ObjectPattern;
3046 for (i = 0; i < expr.properties.length; i++) {
3047 reinterpretExpressionAsPattern(expr.properties[i].value);
3050 case Syntax.AssignmentExpression:
3051 expr.type = Syntax.AssignmentPattern;
3052 reinterpretExpressionAsPattern(expr.left);
3055 // Allow other node type for tolerant parsing.
3060 // ECMA-262 12.2.9 Template Literals
3062 function parseTemplateElement(option) {
3065 if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) {
3066 throwUnexpectedToken();
3072 return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail);
3075 function parseTemplateLiteral() {
3076 var quasi, quasis, expressions, node = new Node();
3078 quasi = parseTemplateElement({ head: true });
3082 while (!quasi.tail) {
3083 expressions.push(parseExpression());
3084 quasi = parseTemplateElement({ head: false });
3088 return node.finishTemplateLiteral(quasis, expressions);
3091 // ECMA-262 12.2.10 The Grouping Operator
3093 function parseGroupExpression() {
3094 var expr, expressions, startToken, i, params = [];
3104 type: PlaceHolders.ArrowParameterPlaceHolder,
3110 startToken = lookahead;
3112 expr = parseRestElement(params);
3118 type: PlaceHolders.ArrowParameterPlaceHolder,
3123 isBindingElement = true;
3124 expr = inheritCoverGrammar(parseAssignmentExpression);
3127 isAssignmentTarget = false;
3128 expressions = [expr];
3130 while (startIndex < length) {
3137 if (!isBindingElement) {
3138 throwUnexpectedToken(lookahead);
3140 expressions.push(parseRestElement(params));
3145 isBindingElement = false;
3146 for (i = 0; i < expressions.length; i++) {
3147 reinterpretExpressionAsPattern(expressions[i]);
3150 type: PlaceHolders.ArrowParameterPlaceHolder,
3155 expressions.push(inheritCoverGrammar(parseAssignmentExpression));
3158 expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
3165 if (expr.type === Syntax.Identifier && expr.name === 'yield') {
3167 type: PlaceHolders.ArrowParameterPlaceHolder,
3172 if (!isBindingElement) {
3173 throwUnexpectedToken(lookahead);
3176 if (expr.type === Syntax.SequenceExpression) {
3177 for (i = 0; i < expr.expressions.length; i++) {
3178 reinterpretExpressionAsPattern(expr.expressions[i]);
3181 reinterpretExpressionAsPattern(expr);
3185 type: PlaceHolders.ArrowParameterPlaceHolder,
3186 params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr]
3189 isBindingElement = false;
3194 // ECMA-262 12.2 Primary Expressions
3196 function parsePrimaryExpression() {
3197 var type, token, expr, node;
3200 isBindingElement = false;
3201 return inheritCoverGrammar(parseGroupExpression);
3205 return inheritCoverGrammar(parseArrayInitializer);
3209 return inheritCoverGrammar(parseObjectInitializer);
3212 type = lookahead.type;
3215 if (type === Token.Identifier) {
3216 if (sourceType === 'module' && lookahead.value === 'await') {
3217 tolerateUnexpectedToken(lookahead);
3219 expr = node.finishIdentifier(lex().value);
3220 } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
3221 isAssignmentTarget = isBindingElement = false;
3222 if (strict && lookahead.octal) {
3223 tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral);
3225 expr = node.finishLiteral(lex());
3226 } else if (type === Token.Keyword) {
3227 if (!strict && state.allowYield && matchKeyword('yield')) {
3228 return parseNonComputedProperty();
3230 isAssignmentTarget = isBindingElement = false;
3231 if (matchKeyword('function')) {
3232 return parseFunctionExpression();
3234 if (matchKeyword('this')) {
3236 return node.finishThisExpression();
3238 if (matchKeyword('class')) {
3239 return parseClassExpression();
3241 throwUnexpectedToken(lex());
3242 } else if (type === Token.BooleanLiteral) {
3243 isAssignmentTarget = isBindingElement = false;
3245 token.value = (token.value === 'true');
3246 expr = node.finishLiteral(token);
3247 } else if (type === Token.NullLiteral) {
3248 isAssignmentTarget = isBindingElement = false;
3251 expr = node.finishLiteral(token);
3252 } else if (match('/') || match('/=')) {
3253 isAssignmentTarget = isBindingElement = false;
3256 if (typeof extra.tokens !== 'undefined') {
3257 token = collectRegex();
3259 token = scanRegExp();
3262 expr = node.finishLiteral(token);
3263 } else if (type === Token.Template) {
3264 expr = parseTemplateLiteral();
3266 throwUnexpectedToken(lex());
3272 // ECMA-262 12.3 Left-Hand-Side Expressions
3274 function parseArguments() {
3275 var args = [], expr;
3280 while (startIndex < length) {
3284 expr.finishSpreadElement(isolateCoverGrammar(parseAssignmentExpression));
3286 expr = isolateCoverGrammar(parseAssignmentExpression);
3292 expectCommaSeparator();
3301 function parseNonComputedProperty() {
3302 var token, node = new Node();
3306 if (!isIdentifierName(token)) {
3307 throwUnexpectedToken(token);
3310 return node.finishIdentifier(token.value);
3313 function parseNonComputedMember() {
3316 return parseNonComputedProperty();
3319 function parseComputedMember() {
3324 expr = isolateCoverGrammar(parseExpression);
3331 // ECMA-262 12.3.3 The new Operator
3333 function parseNewExpression() {
3334 var callee, args, node = new Node();
3336 expectKeyword('new');
3340 if (lookahead.type === Token.Identifier && lookahead.value === 'target') {
3341 if (state.inFunctionBody) {
3343 return node.finishMetaProperty('new', 'target');
3346 throwUnexpectedToken(lookahead);
3349 callee = isolateCoverGrammar(parseLeftHandSideExpression);
3350 args = match('(') ? parseArguments() : [];
3352 isAssignmentTarget = isBindingElement = false;
3354 return node.finishNewExpression(callee, args);
3357 // ECMA-262 12.3.4 Function Calls
3359 function parseLeftHandSideExpressionAllowCall() {
3360 var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn;
3362 startToken = lookahead;
3363 state.allowIn = true;
3365 if (matchKeyword('super') && state.inFunctionBody) {
3368 expr = expr.finishSuper();
3369 if (!match('(') && !match('.') && !match('[')) {
3370 throwUnexpectedToken(lookahead);
3373 expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
3378 isBindingElement = false;
3379 isAssignmentTarget = true;
3380 property = parseNonComputedMember();
3381 expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
3382 } else if (match('(')) {
3383 isBindingElement = false;
3384 isAssignmentTarget = false;
3385 args = parseArguments();
3386 expr = new WrappingNode(startToken).finishCallExpression(expr, args);
3387 } else if (match('[')) {
3388 isBindingElement = false;
3389 isAssignmentTarget = true;
3390 property = parseComputedMember();
3391 expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
3392 } else if (lookahead.type === Token.Template && lookahead.head) {
3393 quasi = parseTemplateLiteral();
3394 expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
3399 state.allowIn = previousAllowIn;
3404 // ECMA-262 12.3 Left-Hand-Side Expressions
3406 function parseLeftHandSideExpression() {
3407 var quasi, expr, property, startToken;
3408 assert(state.allowIn, 'callee of new expression always allow in keyword.');
3410 startToken = lookahead;
3412 if (matchKeyword('super') && state.inFunctionBody) {
3415 expr = expr.finishSuper();
3416 if (!match('[') && !match('.')) {
3417 throwUnexpectedToken(lookahead);
3420 expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
3425 isBindingElement = false;
3426 isAssignmentTarget = true;
3427 property = parseComputedMember();
3428 expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
3429 } else if (match('.')) {
3430 isBindingElement = false;
3431 isAssignmentTarget = true;
3432 property = parseNonComputedMember();
3433 expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
3434 } else if (lookahead.type === Token.Template && lookahead.head) {
3435 quasi = parseTemplateLiteral();
3436 expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
3444 // ECMA-262 12.4 Postfix Expressions
3446 function parsePostfixExpression() {
3447 var expr, token, startToken = lookahead;
3449 expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall);
3451 if (!hasLineTerminator && lookahead.type === Token.Punctuator) {
3452 if (match('++') || match('--')) {
3453 // ECMA-262 11.3.1, 11.3.2
3454 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
3455 tolerateError(Messages.StrictLHSPostfix);
3458 if (!isAssignmentTarget) {
3459 tolerateError(Messages.InvalidLHSInAssignment);
3462 isAssignmentTarget = isBindingElement = false;
3465 expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr);
3472 // ECMA-262 12.5 Unary Operators
3474 function parseUnaryExpression() {
3475 var token, expr, startToken;
3477 if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
3478 expr = parsePostfixExpression();
3479 } else if (match('++') || match('--')) {
3480 startToken = lookahead;
3482 expr = inheritCoverGrammar(parseUnaryExpression);
3483 // ECMA-262 11.4.4, 11.4.5
3484 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
3485 tolerateError(Messages.StrictLHSPrefix);
3488 if (!isAssignmentTarget) {
3489 tolerateError(Messages.InvalidLHSInAssignment);
3491 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
3492 isAssignmentTarget = isBindingElement = false;
3493 } else if (match('+') || match('-') || match('~') || match('!')) {
3494 startToken = lookahead;
3496 expr = inheritCoverGrammar(parseUnaryExpression);
3497 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
3498 isAssignmentTarget = isBindingElement = false;
3499 } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
3500 startToken = lookahead;
3502 expr = inheritCoverGrammar(parseUnaryExpression);
3503 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
3504 if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
3505 tolerateError(Messages.StrictDelete);
3507 isAssignmentTarget = isBindingElement = false;
3509 expr = parsePostfixExpression();
3515 function binaryPrecedence(token, allowIn) {
3518 if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
3522 switch (token.value) {
3559 prec = allowIn ? 7 : 0;
3586 // ECMA-262 12.6 Multiplicative Operators
3587 // ECMA-262 12.7 Additive Operators
3588 // ECMA-262 12.8 Bitwise Shift Operators
3589 // ECMA-262 12.9 Relational Operators
3590 // ECMA-262 12.10 Equality Operators
3591 // ECMA-262 12.11 Binary Bitwise Operators
3592 // ECMA-262 12.12 Binary Logical Operators
3594 function parseBinaryExpression() {
3595 var marker, markers, expr, token, prec, stack, right, operator, left, i;
3598 left = inheritCoverGrammar(parseUnaryExpression);
3601 prec = binaryPrecedence(token, state.allowIn);
3605 isAssignmentTarget = isBindingElement = false;
3609 markers = [marker, lookahead];
3610 right = isolateCoverGrammar(parseUnaryExpression);
3612 stack = [left, token, right];
3614 while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
3616 // Reduce: make a binary expression from the three topmost entries.
3617 while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
3618 right = stack.pop();
3619 operator = stack.pop().value;
3622 expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right);
3630 markers.push(lookahead);
3631 expr = isolateCoverGrammar(parseUnaryExpression);
3635 // Final reduce to clean-up the stack.
3636 i = stack.length - 1;
3640 expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
3648 // ECMA-262 12.13 Conditional Operator
3650 function parseConditionalExpression() {
3651 var expr, previousAllowIn, consequent, alternate, startToken;
3653 startToken = lookahead;
3655 expr = inheritCoverGrammar(parseBinaryExpression);
3658 previousAllowIn = state.allowIn;
3659 state.allowIn = true;
3660 consequent = isolateCoverGrammar(parseAssignmentExpression);
3661 state.allowIn = previousAllowIn;
3663 alternate = isolateCoverGrammar(parseAssignmentExpression);
3665 expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate);
3666 isAssignmentTarget = isBindingElement = false;
3672 // ECMA-262 14.2 Arrow Function Definitions
3674 function parseConciseBody() {
3676 return parseFunctionSourceElements();
3678 return isolateCoverGrammar(parseAssignmentExpression);
3681 function checkPatternParam(options, param) {
3683 switch (param.type) {
3684 case Syntax.Identifier:
3685 validateParam(options, param, param.name);
3687 case Syntax.RestElement:
3688 checkPatternParam(options, param.argument);
3690 case Syntax.AssignmentPattern:
3691 checkPatternParam(options, param.left);
3693 case Syntax.ArrayPattern:
3694 for (i = 0; i < param.elements.length; i++) {
3695 if (param.elements[i] !== null) {
3696 checkPatternParam(options, param.elements[i]);
3700 case Syntax.YieldExpression:
3703 assert(param.type === Syntax.ObjectPattern, 'Invalid type');
3704 for (i = 0; i < param.properties.length; i++) {
3705 checkPatternParam(options, param.properties[i].value);
3710 function reinterpretAsCoverFormalsList(expr) {
3711 var i, len, param, params, defaults, defaultCount, options, token;
3717 switch (expr.type) {
3718 case Syntax.Identifier:
3720 case PlaceHolders.ArrowParameterPlaceHolder:
3721 params = expr.params;
3731 for (i = 0, len = params.length; i < len; i += 1) {
3733 switch (param.type) {
3734 case Syntax.AssignmentPattern:
3735 params[i] = param.left;
3736 if (param.right.type === Syntax.YieldExpression) {
3737 if (param.right.argument) {
3738 throwUnexpectedToken(lookahead);
3740 param.right.type = Syntax.Identifier;
3741 param.right.name = 'yield';
3742 delete param.right.argument;
3743 delete param.right.delegate;
3745 defaults.push(param.right);
3747 checkPatternParam(options, param.left);
3750 checkPatternParam(options, param);
3752 defaults.push(null);
3757 if (strict || !state.allowYield) {
3758 for (i = 0, len = params.length; i < len; i += 1) {
3760 if (param.type === Syntax.YieldExpression) {
3761 throwUnexpectedToken(lookahead);
3766 if (options.message === Messages.StrictParamDupe) {
3767 token = strict ? options.stricted : options.firstRestricted;
3768 throwUnexpectedToken(token, options.message);
3771 if (defaultCount === 0) {
3778 stricted: options.stricted,
3779 firstRestricted: options.firstRestricted,
3780 message: options.message
3784 function parseArrowFunctionExpression(options, node) {
3785 var previousStrict, previousAllowYield, body;
3787 if (hasLineTerminator) {
3788 tolerateUnexpectedToken(lookahead);
3792 previousStrict = strict;
3793 previousAllowYield = state.allowYield;
3794 state.allowYield = true;
3796 body = parseConciseBody();
3798 if (strict && options.firstRestricted) {
3799 throwUnexpectedToken(options.firstRestricted, options.message);
3801 if (strict && options.stricted) {
3802 tolerateUnexpectedToken(options.stricted, options.message);
3805 strict = previousStrict;
3806 state.allowYield = previousAllowYield;
3808 return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement);
3811 // ECMA-262 14.4 Yield expression
3813 function parseYieldExpression() {
3814 var argument, expr, delegate, previousAllowYield;
3819 expectKeyword('yield');
3821 if (!hasLineTerminator) {
3822 previousAllowYield = state.allowYield;
3823 state.allowYield = false;
3824 delegate = match('*');
3827 argument = parseAssignmentExpression();
3829 if (!match(';') && !match('}') && !match(')') && lookahead.type !== Token.EOF) {
3830 argument = parseAssignmentExpression();
3833 state.allowYield = previousAllowYield;
3836 return expr.finishYieldExpression(argument, delegate);
3839 // ECMA-262 12.14 Assignment Operators
3841 function parseAssignmentExpression() {
3842 var token, expr, right, list, startToken;
3844 startToken = lookahead;
3847 if (!state.allowYield && matchKeyword('yield')) {
3848 return parseYieldExpression();
3851 expr = parseConditionalExpression();
3853 if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) {
3854 isAssignmentTarget = isBindingElement = false;
3855 list = reinterpretAsCoverFormalsList(expr);
3858 firstCoverInitializedNameError = null;
3859 return parseArrowFunctionExpression(list, new WrappingNode(startToken));
3865 if (matchAssign()) {
3866 if (!isAssignmentTarget) {
3867 tolerateError(Messages.InvalidLHSInAssignment);
3871 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
3872 tolerateUnexpectedToken(token, Messages.StrictLHSAssignment);
3876 isAssignmentTarget = isBindingElement = false;
3878 reinterpretExpressionAsPattern(expr);
3882 right = isolateCoverGrammar(parseAssignmentExpression);
3883 expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right);
3884 firstCoverInitializedNameError = null;
3890 // ECMA-262 12.15 Comma Operator
3892 function parseExpression() {
3893 var expr, startToken = lookahead, expressions;
3895 expr = isolateCoverGrammar(parseAssignmentExpression);
3898 expressions = [expr];
3900 while (startIndex < length) {
3905 expressions.push(isolateCoverGrammar(parseAssignmentExpression));
3908 expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
3914 // ECMA-262 13.2 Block
3916 function parseStatementListItem() {
3917 if (lookahead.type === Token.Keyword) {
3918 switch (lookahead.value) {
3920 if (sourceType !== 'module') {
3921 tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration);
3923 return parseExportDeclaration();
3925 if (sourceType !== 'module') {
3926 tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration);
3928 return parseImportDeclaration();
3931 return parseLexicalDeclaration({inFor: false});
3933 return parseFunctionDeclaration(new Node());
3935 return parseClassDeclaration();
3939 return parseStatement();
3942 function parseStatementList() {
3944 while (startIndex < length) {
3948 list.push(parseStatementListItem());
3954 function parseBlock() {
3955 var block, node = new Node();
3959 block = parseStatementList();
3963 return node.finishBlockStatement(block);
3966 // ECMA-262 13.3.2 Variable Statement
3968 function parseVariableIdentifier() {
3969 var token, node = new Node();
3973 if (token.type === Token.Keyword && token.value === 'yield') {
3975 tolerateUnexpectedToken(token, Messages.StrictReservedWord);
3976 } if (!state.allowYield) {
3977 throwUnexpectedToken(token);
3979 } else if (token.type !== Token.Identifier) {
3980 if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) {
3981 tolerateUnexpectedToken(token, Messages.StrictReservedWord);
3983 throwUnexpectedToken(token);
3985 } else if (sourceType === 'module' && token.type === Token.Identifier && token.value === 'await') {
3986 tolerateUnexpectedToken(token);
3989 return node.finishIdentifier(token.value);
3992 function parseVariableDeclaration() {
3993 var init = null, id, node = new Node(), params = [];
3995 id = parsePattern(params);
3998 if (strict && isRestrictedWord(id.name)) {
3999 tolerateError(Messages.StrictVarName);
4004 init = isolateCoverGrammar(parseAssignmentExpression);
4005 } else if (id.type !== Syntax.Identifier) {
4009 return node.finishVariableDeclarator(id, init);
4012 function parseVariableDeclarationList() {
4016 list.push(parseVariableDeclaration());
4021 } while (startIndex < length);
4026 function parseVariableStatement(node) {
4029 expectKeyword('var');
4031 declarations = parseVariableDeclarationList();
4035 return node.finishVariableDeclaration(declarations);
4038 // ECMA-262 13.3.1 Let and Const Declarations
4040 function parseLexicalBinding(kind, options) {
4041 var init = null, id, node = new Node(), params = [];
4043 id = parsePattern(params);
4046 if (strict && id.type === Syntax.Identifier && isRestrictedWord(id.name)) {
4047 tolerateError(Messages.StrictVarName);
4050 if (kind === 'const') {
4051 if (!matchKeyword('in') && !matchContextualKeyword('of')) {
4053 init = isolateCoverGrammar(parseAssignmentExpression);
4055 } else if ((!options.inFor && id.type !== Syntax.Identifier) || match('=')) {
4057 init = isolateCoverGrammar(parseAssignmentExpression);
4060 return node.finishVariableDeclarator(id, init);
4063 function parseBindingList(kind, options) {
4067 list.push(parseLexicalBinding(kind, options));
4072 } while (startIndex < length);
4077 function parseLexicalDeclaration(options) {
4078 var kind, declarations, node = new Node();
4081 assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
4083 declarations = parseBindingList(kind, options);
4087 return node.finishLexicalDeclaration(declarations, kind);
4090 function parseRestElement(params) {
4091 var param, node = new Node();
4096 throwError(Messages.ObjectPatternAsRestParameter);
4099 params.push(lookahead);
4101 param = parseVariableIdentifier();
4104 throwError(Messages.DefaultRestParameter);
4108 throwError(Messages.ParameterAfterRestParameter);
4111 return node.finishRestElement(param);
4114 // ECMA-262 13.4 Empty Statement
4116 function parseEmptyStatement(node) {
4118 return node.finishEmptyStatement();
4121 // ECMA-262 12.4 Expression Statement
4123 function parseExpressionStatement(node) {
4124 var expr = parseExpression();
4126 return node.finishExpressionStatement(expr);
4129 // ECMA-262 13.6 If statement
4131 function parseIfStatement(node) {
4132 var test, consequent, alternate;
4134 expectKeyword('if');
4138 test = parseExpression();
4142 consequent = parseStatement();
4144 if (matchKeyword('else')) {
4146 alternate = parseStatement();
4151 return node.finishIfStatement(test, consequent, alternate);
4154 // ECMA-262 13.7 Iteration Statements
4156 function parseDoWhileStatement(node) {
4157 var body, test, oldInIteration;
4159 expectKeyword('do');
4161 oldInIteration = state.inIteration;
4162 state.inIteration = true;
4164 body = parseStatement();
4166 state.inIteration = oldInIteration;
4168 expectKeyword('while');
4172 test = parseExpression();
4180 return node.finishDoWhileStatement(body, test);
4183 function parseWhileStatement(node) {
4184 var test, body, oldInIteration;
4186 expectKeyword('while');
4190 test = parseExpression();
4194 oldInIteration = state.inIteration;
4195 state.inIteration = true;
4197 body = parseStatement();
4199 state.inIteration = oldInIteration;
4201 return node.finishWhileStatement(test, body);
4204 function parseForStatement(node) {
4205 var init, forIn, initSeq, initStartToken, test, update, left, right, kind, declarations,
4206 body, oldInIteration, previousAllowIn = state.allowIn;
4208 init = test = update = null;
4211 expectKeyword('for');
4218 if (matchKeyword('var')) {
4222 state.allowIn = false;
4223 init = init.finishVariableDeclaration(parseVariableDeclarationList());
4224 state.allowIn = previousAllowIn;
4226 if (init.declarations.length === 1 && matchKeyword('in')) {
4229 right = parseExpression();
4231 } else if (init.declarations.length === 1 && init.declarations[0].init === null && matchContextualKeyword('of')) {
4234 right = parseAssignmentExpression();
4240 } else if (matchKeyword('const') || matchKeyword('let')) {
4244 state.allowIn = false;
4245 declarations = parseBindingList(kind, {inFor: true});
4246 state.allowIn = previousAllowIn;
4248 if (declarations.length === 1 && declarations[0].init === null && matchKeyword('in')) {
4249 init = init.finishLexicalDeclaration(declarations, kind);
4252 right = parseExpression();
4254 } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) {
4255 init = init.finishLexicalDeclaration(declarations, kind);
4258 right = parseAssignmentExpression();
4263 init = init.finishLexicalDeclaration(declarations, kind);
4266 initStartToken = lookahead;
4267 state.allowIn = false;
4268 init = inheritCoverGrammar(parseAssignmentExpression);
4269 state.allowIn = previousAllowIn;
4271 if (matchKeyword('in')) {
4272 if (!isAssignmentTarget) {
4273 tolerateError(Messages.InvalidLHSInForIn);
4277 reinterpretExpressionAsPattern(init);
4279 right = parseExpression();
4281 } else if (matchContextualKeyword('of')) {
4282 if (!isAssignmentTarget) {
4283 tolerateError(Messages.InvalidLHSInForLoop);
4287 reinterpretExpressionAsPattern(init);
4289 right = parseAssignmentExpression();
4295 while (match(',')) {
4297 initSeq.push(isolateCoverGrammar(parseAssignmentExpression));
4299 init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq);
4306 if (typeof left === 'undefined') {
4309 test = parseExpression();
4314 update = parseExpression();
4320 oldInIteration = state.inIteration;
4321 state.inIteration = true;
4323 body = isolateCoverGrammar(parseStatement);
4325 state.inIteration = oldInIteration;
4327 return (typeof left === 'undefined') ?
4328 node.finishForStatement(init, test, update, body) :
4329 forIn ? node.finishForInStatement(left, right, body) :
4330 node.finishForOfStatement(left, right, body);
4333 // ECMA-262 13.8 The continue statement
4335 function parseContinueStatement(node) {
4336 var label = null, key;
4338 expectKeyword('continue');
4340 // Optimize the most common form: 'continue;'.
4341 if (source.charCodeAt(startIndex) === 0x3B) {
4344 if (!state.inIteration) {
4345 throwError(Messages.IllegalContinue);
4348 return node.finishContinueStatement(null);
4351 if (hasLineTerminator) {
4352 if (!state.inIteration) {
4353 throwError(Messages.IllegalContinue);
4356 return node.finishContinueStatement(null);
4359 if (lookahead.type === Token.Identifier) {
4360 label = parseVariableIdentifier();
4362 key = '$' + label.name;
4363 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
4364 throwError(Messages.UnknownLabel, label.name);
4370 if (label === null && !state.inIteration) {
4371 throwError(Messages.IllegalContinue);
4374 return node.finishContinueStatement(label);
4377 // ECMA-262 13.9 The break statement
4379 function parseBreakStatement(node) {
4380 var label = null, key;
4382 expectKeyword('break');
4384 // Catch the very common case first: immediately a semicolon (U+003B).
4385 if (source.charCodeAt(lastIndex) === 0x3B) {
4388 if (!(state.inIteration || state.inSwitch)) {
4389 throwError(Messages.IllegalBreak);
4392 return node.finishBreakStatement(null);
4395 if (hasLineTerminator) {
4396 if (!(state.inIteration || state.inSwitch)) {
4397 throwError(Messages.IllegalBreak);
4400 return node.finishBreakStatement(null);
4403 if (lookahead.type === Token.Identifier) {
4404 label = parseVariableIdentifier();
4406 key = '$' + label.name;
4407 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
4408 throwError(Messages.UnknownLabel, label.name);
4414 if (label === null && !(state.inIteration || state.inSwitch)) {
4415 throwError(Messages.IllegalBreak);
4418 return node.finishBreakStatement(label);
4421 // ECMA-262 13.10 The return statement
4423 function parseReturnStatement(node) {
4424 var argument = null;
4426 expectKeyword('return');
4428 if (!state.inFunctionBody) {
4429 tolerateError(Messages.IllegalReturn);
4432 // 'return' followed by a space and an identifier is very common.
4433 if (source.charCodeAt(lastIndex) === 0x20) {
4434 if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) {
4435 argument = parseExpression();
4437 return node.finishReturnStatement(argument);
4441 if (hasLineTerminator) {
4443 return node.finishReturnStatement(null);
4447 if (!match('}') && lookahead.type !== Token.EOF) {
4448 argument = parseExpression();
4454 return node.finishReturnStatement(argument);
4457 // ECMA-262 13.11 The with statement
4459 function parseWithStatement(node) {
4463 tolerateError(Messages.StrictModeWith);
4466 expectKeyword('with');
4470 object = parseExpression();
4474 body = parseStatement();
4476 return node.finishWithStatement(object, body);
4479 // ECMA-262 13.12 The switch statement
4481 function parseSwitchCase() {
4482 var test, consequent = [], statement, node = new Node();
4484 if (matchKeyword('default')) {
4488 expectKeyword('case');
4489 test = parseExpression();
4493 while (startIndex < length) {
4494 if (match('}') || matchKeyword('default') || matchKeyword('case')) {
4497 statement = parseStatementListItem();
4498 consequent.push(statement);
4501 return node.finishSwitchCase(test, consequent);
4504 function parseSwitchStatement(node) {
4505 var discriminant, cases, clause, oldInSwitch, defaultFound;
4507 expectKeyword('switch');
4511 discriminant = parseExpression();
4521 return node.finishSwitchStatement(discriminant, cases);
4524 oldInSwitch = state.inSwitch;
4525 state.inSwitch = true;
4526 defaultFound = false;
4528 while (startIndex < length) {
4532 clause = parseSwitchCase();
4533 if (clause.test === null) {
4535 throwError(Messages.MultipleDefaultsInSwitch);
4537 defaultFound = true;
4542 state.inSwitch = oldInSwitch;
4546 return node.finishSwitchStatement(discriminant, cases);
4549 // ECMA-262 13.14 The throw statement
4551 function parseThrowStatement(node) {
4554 expectKeyword('throw');
4556 if (hasLineTerminator) {
4557 throwError(Messages.NewlineAfterThrow);
4560 argument = parseExpression();
4564 return node.finishThrowStatement(argument);
4567 // ECMA-262 13.15 The try statement
4569 function parseCatchClause() {
4570 var param, params = [], paramMap = {}, key, i, body, node = new Node();
4572 expectKeyword('catch');
4576 throwUnexpectedToken(lookahead);
4579 param = parsePattern(params);
4580 for (i = 0; i < params.length; i++) {
4581 key = '$' + params[i].value;
4582 if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
4583 tolerateError(Messages.DuplicateBinding, params[i].value);
4585 paramMap[key] = true;
4589 if (strict && isRestrictedWord(param.name)) {
4590 tolerateError(Messages.StrictCatchVariable);
4594 body = parseBlock();
4595 return node.finishCatchClause(param, body);
4598 function parseTryStatement(node) {
4599 var block, handler = null, finalizer = null;
4601 expectKeyword('try');
4603 block = parseBlock();
4605 if (matchKeyword('catch')) {
4606 handler = parseCatchClause();
4609 if (matchKeyword('finally')) {
4611 finalizer = parseBlock();
4614 if (!handler && !finalizer) {
4615 throwError(Messages.NoCatchOrFinally);
4618 return node.finishTryStatement(block, handler, finalizer);
4621 // ECMA-262 13.16 The debugger statement
4623 function parseDebuggerStatement(node) {
4624 expectKeyword('debugger');
4628 return node.finishDebuggerStatement();
4633 function parseStatement() {
4634 var type = lookahead.type,
4640 if (type === Token.EOF) {
4641 throwUnexpectedToken(lookahead);
4644 if (type === Token.Punctuator && lookahead.value === '{') {
4645 return parseBlock();
4647 isAssignmentTarget = isBindingElement = true;
4650 if (type === Token.Punctuator) {
4651 switch (lookahead.value) {
4653 return parseEmptyStatement(node);
4655 return parseExpressionStatement(node);
4659 } else if (type === Token.Keyword) {
4660 switch (lookahead.value) {
4662 return parseBreakStatement(node);
4664 return parseContinueStatement(node);
4666 return parseDebuggerStatement(node);
4668 return parseDoWhileStatement(node);
4670 return parseForStatement(node);
4672 return parseFunctionDeclaration(node);
4674 return parseIfStatement(node);
4676 return parseReturnStatement(node);
4678 return parseSwitchStatement(node);
4680 return parseThrowStatement(node);
4682 return parseTryStatement(node);
4684 return parseVariableStatement(node);
4686 return parseWhileStatement(node);
4688 return parseWithStatement(node);
4694 expr = parseExpression();
4696 // ECMA-262 12.12 Labelled Statements
4697 if ((expr.type === Syntax.Identifier) && match(':')) {
4700 key = '$' + expr.name;
4701 if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
4702 throwError(Messages.Redeclaration, 'Label', expr.name);
4705 state.labelSet[key] = true;
4706 labeledBody = parseStatement();
4707 delete state.labelSet[key];
4708 return node.finishLabeledStatement(expr, labeledBody);
4713 return node.finishExpressionStatement(expr);
4716 // ECMA-262 14.1 Function Definition
4718 function parseFunctionSourceElements() {
4719 var statement, body = [], token, directive, firstRestricted,
4720 oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount,
4725 while (startIndex < length) {
4726 if (lookahead.type !== Token.StringLiteral) {
4731 statement = parseStatementListItem();
4732 body.push(statement);
4733 if (statement.expression.type !== Syntax.Literal) {
4734 // this is not directive
4737 directive = source.slice(token.start + 1, token.end - 1);
4738 if (directive === 'use strict') {
4740 if (firstRestricted) {
4741 tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
4744 if (!firstRestricted && token.octal) {
4745 firstRestricted = token;
4750 oldLabelSet = state.labelSet;
4751 oldInIteration = state.inIteration;
4752 oldInSwitch = state.inSwitch;
4753 oldInFunctionBody = state.inFunctionBody;
4754 oldParenthesisCount = state.parenthesizedCount;
4756 state.labelSet = {};
4757 state.inIteration = false;
4758 state.inSwitch = false;
4759 state.inFunctionBody = true;
4760 state.parenthesizedCount = 0;
4762 while (startIndex < length) {
4766 body.push(parseStatementListItem());
4771 state.labelSet = oldLabelSet;
4772 state.inIteration = oldInIteration;
4773 state.inSwitch = oldInSwitch;
4774 state.inFunctionBody = oldInFunctionBody;
4775 state.parenthesizedCount = oldParenthesisCount;
4777 return node.finishBlockStatement(body);
4780 function validateParam(options, param, name) {
4781 var key = '$' + name;
4783 if (isRestrictedWord(name)) {
4784 options.stricted = param;
4785 options.message = Messages.StrictParamName;
4787 if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
4788 options.stricted = param;
4789 options.message = Messages.StrictParamDupe;
4791 } else if (!options.firstRestricted) {
4792 if (isRestrictedWord(name)) {
4793 options.firstRestricted = param;
4794 options.message = Messages.StrictParamName;
4795 } else if (isStrictModeReservedWord(name)) {
4796 options.firstRestricted = param;
4797 options.message = Messages.StrictReservedWord;
4798 } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
4799 options.stricted = param;
4800 options.message = Messages.StrictParamDupe;
4803 options.paramSet[key] = true;
4806 function parseParam(options) {
4807 var token, param, params = [], i, def;
4810 if (token.value === '...') {
4811 param = parseRestElement(params);
4812 validateParam(options, param.argument, param.argument.name);
4813 options.params.push(param);
4814 options.defaults.push(null);
4818 param = parsePatternWithDefault(params);
4819 for (i = 0; i < params.length; i++) {
4820 validateParam(options, params[i], params[i].value);
4823 if (param.type === Syntax.AssignmentPattern) {
4826 ++options.defaultCount;
4829 options.params.push(param);
4830 options.defaults.push(def);
4835 function parseParams(firstRestricted) {
4842 firstRestricted: firstRestricted
4848 options.paramSet = {};
4849 while (startIndex < length) {
4850 if (!parseParam(options)) {
4859 if (options.defaultCount === 0) {
4860 options.defaults = [];
4864 params: options.params,
4865 defaults: options.defaults,
4866 stricted: options.stricted,
4867 firstRestricted: options.firstRestricted,
4868 message: options.message
4872 function parseFunctionDeclaration(node, identifierIsOptional) {
4873 var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict,
4874 isGenerator, previousAllowYield;
4876 previousAllowYield = state.allowYield;
4878 expectKeyword('function');
4880 isGenerator = match('*');
4885 if (!identifierIsOptional || !match('(')) {
4887 id = parseVariableIdentifier();
4889 if (isRestrictedWord(token.value)) {
4890 tolerateUnexpectedToken(token, Messages.StrictFunctionName);
4893 if (isRestrictedWord(token.value)) {
4894 firstRestricted = token;
4895 message = Messages.StrictFunctionName;
4896 } else if (isStrictModeReservedWord(token.value)) {
4897 firstRestricted = token;
4898 message = Messages.StrictReservedWord;
4903 state.allowYield = !isGenerator;
4904 tmp = parseParams(firstRestricted);
4905 params = tmp.params;
4906 defaults = tmp.defaults;
4907 stricted = tmp.stricted;
4908 firstRestricted = tmp.firstRestricted;
4910 message = tmp.message;
4914 previousStrict = strict;
4915 body = parseFunctionSourceElements();
4916 if (strict && firstRestricted) {
4917 throwUnexpectedToken(firstRestricted, message);
4919 if (strict && stricted) {
4920 tolerateUnexpectedToken(stricted, message);
4923 strict = previousStrict;
4924 state.allowYield = previousAllowYield;
4926 return node.finishFunctionDeclaration(id, params, defaults, body, isGenerator);
4929 function parseFunctionExpression() {
4930 var token, id = null, stricted, firstRestricted, message, tmp,
4931 params = [], defaults = [], body, previousStrict, node = new Node(),
4932 isGenerator, previousAllowYield;
4934 previousAllowYield = state.allowYield;
4936 expectKeyword('function');
4938 isGenerator = match('*');
4943 state.allowYield = !isGenerator;
4946 id = (!strict && !isGenerator && matchKeyword('yield')) ? parseNonComputedProperty() : parseVariableIdentifier();
4948 if (isRestrictedWord(token.value)) {
4949 tolerateUnexpectedToken(token, Messages.StrictFunctionName);
4952 if (isRestrictedWord(token.value)) {
4953 firstRestricted = token;
4954 message = Messages.StrictFunctionName;
4955 } else if (isStrictModeReservedWord(token.value)) {
4956 firstRestricted = token;
4957 message = Messages.StrictReservedWord;
4962 tmp = parseParams(firstRestricted);
4963 params = tmp.params;
4964 defaults = tmp.defaults;
4965 stricted = tmp.stricted;
4966 firstRestricted = tmp.firstRestricted;
4968 message = tmp.message;
4971 previousStrict = strict;
4972 body = parseFunctionSourceElements();
4973 if (strict && firstRestricted) {
4974 throwUnexpectedToken(firstRestricted, message);
4976 if (strict && stricted) {
4977 tolerateUnexpectedToken(stricted, message);
4979 strict = previousStrict;
4980 state.allowYield = previousAllowYield;
4982 return node.finishFunctionExpression(id, params, defaults, body, isGenerator);
4985 // ECMA-262 14.5 Class Definitions
4987 function parseClassBody() {
4988 var classBody, token, isStatic, hasConstructor = false, body, method, computed, key;
4990 classBody = new Node();
4994 while (!match('}')) {
4998 method = new Node();
5001 computed = match('[');
5005 key = parseObjectPropertyKey();
5006 if (key.name === 'static' && (lookaheadPropertyName() || match('*'))) {
5009 computed = match('[');
5013 key = parseObjectPropertyKey();
5017 method = tryParseMethodDefinition(token, key, computed, method);
5019 method['static'] = isStatic; // jscs:ignore requireDotNotation
5020 if (method.kind === 'init') {
5021 method.kind = 'method';
5024 if (!method.computed && (method.key.name || method.key.value.toString()) === 'constructor') {
5025 if (method.kind !== 'method' || !method.method || method.value.generator) {
5026 throwUnexpectedToken(token, Messages.ConstructorSpecialMethod);
5028 if (hasConstructor) {
5029 throwUnexpectedToken(token, Messages.DuplicateConstructor);
5031 hasConstructor = true;
5033 method.kind = 'constructor';
5036 if (!method.computed && (method.key.name || method.key.value.toString()) === 'prototype') {
5037 throwUnexpectedToken(token, Messages.StaticPrototype);
5040 method.type = Syntax.MethodDefinition;
5041 delete method.method;
5042 delete method.shorthand;
5045 throwUnexpectedToken(lookahead);
5050 return classBody.finishClassBody(body);
5053 function parseClassDeclaration(identifierIsOptional) {
5054 var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
5057 expectKeyword('class');
5059 if (!identifierIsOptional || lookahead.type === Token.Identifier) {
5060 id = parseVariableIdentifier();
5063 if (matchKeyword('extends')) {
5065 superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
5067 classBody = parseClassBody();
5068 strict = previousStrict;
5070 return classNode.finishClassDeclaration(id, superClass, classBody);
5073 function parseClassExpression() {
5074 var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
5077 expectKeyword('class');
5079 if (lookahead.type === Token.Identifier) {
5080 id = parseVariableIdentifier();
5083 if (matchKeyword('extends')) {
5085 superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
5087 classBody = parseClassBody();
5088 strict = previousStrict;
5090 return classNode.finishClassExpression(id, superClass, classBody);
5093 // ECMA-262 15.2 Modules
5095 function parseModuleSpecifier() {
5096 var node = new Node();
5098 if (lookahead.type !== Token.StringLiteral) {
5099 throwError(Messages.InvalidModuleSpecifier);
5101 return node.finishLiteral(lex());
5104 // ECMA-262 15.2.3 Exports
5106 function parseExportSpecifier() {
5107 var exported, local, node = new Node(), def;
5108 if (matchKeyword('default')) {
5109 // export {default} from 'something';
5112 local = def.finishIdentifier('default');
5114 local = parseVariableIdentifier();
5116 if (matchContextualKeyword('as')) {
5118 exported = parseNonComputedProperty();
5120 return node.finishExportSpecifier(local, exported);
5123 function parseExportNamedDeclaration(node) {
5124 var declaration = null,
5125 isExportFromIdentifier,
5126 src = null, specifiers = [];
5128 // non-default export
5129 if (lookahead.type === Token.Keyword) {
5131 // export var f = 1;
5132 switch (lookahead.value) {
5138 declaration = parseStatementListItem();
5139 return node.finishExportNamedDeclaration(declaration, specifiers, null);
5144 while (!match('}')) {
5145 isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default');
5146 specifiers.push(parseExportSpecifier());
5156 if (matchContextualKeyword('from')) {
5158 // export {default} from 'foo';
5159 // export {foo} from 'foo';
5161 src = parseModuleSpecifier();
5163 } else if (isExportFromIdentifier) {
5165 // export {default}; // missing fromClause
5166 throwError(lookahead.value ?
5167 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
5173 return node.finishExportNamedDeclaration(declaration, specifiers, src);
5176 function parseExportDefaultDeclaration(node) {
5177 var declaration = null,
5181 // export default ...
5182 expectKeyword('default');
5184 if (matchKeyword('function')) {
5186 // export default function foo () {}
5187 // export default function () {}
5188 declaration = parseFunctionDeclaration(new Node(), true);
5189 return node.finishExportDefaultDeclaration(declaration);
5191 if (matchKeyword('class')) {
5192 declaration = parseClassDeclaration(true);
5193 return node.finishExportDefaultDeclaration(declaration);
5196 if (matchContextualKeyword('from')) {
5197 throwError(Messages.UnexpectedToken, lookahead.value);
5201 // export default {};
5202 // export default [];
5203 // export default (1 + 2);
5205 expression = parseObjectInitializer();
5206 } else if (match('[')) {
5207 expression = parseArrayInitializer();
5209 expression = parseAssignmentExpression();
5212 return node.finishExportDefaultDeclaration(expression);
5215 function parseExportAllDeclaration(node) {
5219 // export * from 'foo';
5221 if (!matchContextualKeyword('from')) {
5222 throwError(lookahead.value ?
5223 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
5226 src = parseModuleSpecifier();
5229 return node.finishExportAllDeclaration(src);
5232 function parseExportDeclaration() {
5233 var node = new Node();
5234 if (state.inFunctionBody) {
5235 throwError(Messages.IllegalExportDeclaration);
5238 expectKeyword('export');
5240 if (matchKeyword('default')) {
5241 return parseExportDefaultDeclaration(node);
5244 return parseExportAllDeclaration(node);
5246 return parseExportNamedDeclaration(node);
5249 // ECMA-262 15.2.2 Imports
5251 function parseImportSpecifier() {
5252 // import {<foo as bar>} ...;
5253 var local, imported, node = new Node();
5255 imported = parseNonComputedProperty();
5256 if (matchContextualKeyword('as')) {
5258 local = parseVariableIdentifier();
5261 return node.finishImportSpecifier(local, imported);
5264 function parseNamedImports() {
5265 var specifiers = [];
5266 // {foo, bar as bas}
5268 while (!match('}')) {
5269 specifiers.push(parseImportSpecifier());
5281 function parseImportDefaultSpecifier() {
5282 // import <foo> ...;
5283 var local, node = new Node();
5285 local = parseNonComputedProperty();
5287 return node.finishImportDefaultSpecifier(local);
5290 function parseImportNamespaceSpecifier() {
5291 // import <* as foo> ...;
5292 var local, node = new Node();
5295 if (!matchContextualKeyword('as')) {
5296 throwError(Messages.NoAsAfterImportNamespace);
5299 local = parseNonComputedProperty();
5301 return node.finishImportNamespaceSpecifier(local);
5304 function parseImportDeclaration() {
5305 var specifiers = [], src, node = new Node();
5307 if (state.inFunctionBody) {
5308 throwError(Messages.IllegalImportDeclaration);
5311 expectKeyword('import');
5313 if (lookahead.type === Token.StringLiteral) {
5315 src = parseModuleSpecifier();
5320 specifiers = specifiers.concat(parseNamedImports());
5321 } else if (match('*')) {
5323 specifiers.push(parseImportNamespaceSpecifier());
5324 } else if (isIdentifierName(lookahead) && !matchKeyword('default')) {
5326 specifiers.push(parseImportDefaultSpecifier());
5330 // import foo, * as foo
5331 specifiers.push(parseImportNamespaceSpecifier());
5332 } else if (match('{')) {
5333 // import foo, {bar}
5334 specifiers = specifiers.concat(parseNamedImports());
5336 throwUnexpectedToken(lookahead);
5340 throwUnexpectedToken(lex());
5343 if (!matchContextualKeyword('from')) {
5344 throwError(lookahead.value ?
5345 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
5348 src = parseModuleSpecifier();
5352 return node.finishImportDeclaration(specifiers, src);
5355 // ECMA-262 15.1 Scripts
5357 function parseScriptBody() {
5358 var statement, body = [], token, directive, firstRestricted;
5360 while (startIndex < length) {
5362 if (token.type !== Token.StringLiteral) {
5366 statement = parseStatementListItem();
5367 body.push(statement);
5368 if (statement.expression.type !== Syntax.Literal) {
5369 // this is not directive
5372 directive = source.slice(token.start + 1, token.end - 1);
5373 if (directive === 'use strict') {
5375 if (firstRestricted) {
5376 tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
5379 if (!firstRestricted && token.octal) {
5380 firstRestricted = token;
5385 while (startIndex < length) {
5386 statement = parseStatementListItem();
5387 /* istanbul ignore if */
5388 if (typeof statement === 'undefined') {
5391 body.push(statement);
5396 function parseProgram() {
5402 body = parseScriptBody();
5403 return node.finishProgram(body);
5406 function filterTokenLocation() {
5407 var i, entry, token, tokens = [];
5409 for (i = 0; i < extra.tokens.length; ++i) {
5410 entry = extra.tokens[i];
5417 pattern: entry.regex.pattern,
5418 flags: entry.regex.flags
5422 token.range = entry.range;
5425 token.loc = entry.loc;
5430 extra.tokens = tokens;
5433 function tokenize(code, options) {
5438 if (typeof code !== 'string' && !(code instanceof String)) {
5439 code = toString(code);
5444 lineNumber = (source.length > 0) ? 1 : 0;
5447 startLineNumber = lineNumber;
5448 startLineStart = lineStart;
5449 length = source.length;
5455 inFunctionBody: false,
5458 lastCommentStart: -1,
5464 // Options matching.
5465 options = options || {};
5467 // Of course we collect tokens here.
5468 options.tokens = true;
5470 extra.tokenize = true;
5471 // The following two fields are necessary to compute the Regex tokens.
5472 extra.openParenToken = -1;
5473 extra.openCurlyToken = -1;
5475 extra.range = (typeof options.range === 'boolean') && options.range;
5476 extra.loc = (typeof options.loc === 'boolean') && options.loc;
5478 if (typeof options.comment === 'boolean' && options.comment) {
5479 extra.comments = [];
5481 if (typeof options.tolerant === 'boolean' && options.tolerant) {
5487 if (lookahead.type === Token.EOF) {
5488 return extra.tokens;
5492 while (lookahead.type !== Token.EOF) {
5495 } catch (lexError) {
5497 recordError(lexError);
5498 // We have to break on the first error
5499 // to avoid infinite loops.
5507 filterTokenLocation();
5508 tokens = extra.tokens;
5509 if (typeof extra.comments !== 'undefined') {
5510 tokens.comments = extra.comments;
5512 if (typeof extra.errors !== 'undefined') {
5513 tokens.errors = extra.errors;
5523 function parse(code, options) {
5524 var program, toString;
5527 if (typeof code !== 'string' && !(code instanceof String)) {
5528 code = toString(code);
5533 lineNumber = (source.length > 0) ? 1 : 0;
5536 startLineNumber = lineNumber;
5537 startLineStart = lineStart;
5538 length = source.length;
5544 inFunctionBody: false,
5547 lastCommentStart: -1,
5550 sourceType = 'script';
5554 if (typeof options !== 'undefined') {
5555 extra.range = (typeof options.range === 'boolean') && options.range;
5556 extra.loc = (typeof options.loc === 'boolean') && options.loc;
5557 extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
5559 if (extra.loc && options.source !== null && options.source !== undefined) {
5560 extra.source = toString(options.source);
5563 if (typeof options.tokens === 'boolean' && options.tokens) {
5566 if (typeof options.comment === 'boolean' && options.comment) {
5567 extra.comments = [];
5569 if (typeof options.tolerant === 'boolean' && options.tolerant) {
5572 if (extra.attachComment) {
5574 extra.comments = [];
5575 extra.bottomRightStack = [];
5576 extra.trailingComments = [];
5577 extra.leadingComments = [];
5579 if (options.sourceType === 'module') {
5580 // very restrictive condition for now
5581 sourceType = options.sourceType;
5587 program = parseProgram();
5588 if (typeof extra.comments !== 'undefined') {
5589 program.comments = extra.comments;
5591 if (typeof extra.tokens !== 'undefined') {
5592 filterTokenLocation();
5593 program.tokens = extra.tokens;
5595 if (typeof extra.errors !== 'undefined') {
5596 program.errors = extra.errors;
5607 // Sync with *.json manifests.
5608 exports.version = '2.5.0';
5610 exports.tokenize = tokenize;
5612 exports.parse = parse;
5615 /* istanbul ignore next */
5616 exports.Syntax = (function () {
5617 var name, types = {};
5619 if (typeof Object.create === 'function') {
5620 types = Object.create(null);
5623 for (name in Syntax) {
5624 if (Syntax.hasOwnProperty(name)) {
5625 types[name] = Syntax[name];
5629 if (typeof Object.freeze === 'function') {
5630 Object.freeze(types);
5637 /* vim: set sw=4 ts=4 et tw=80 : */