1'use strict'; 2 3Object.defineProperty(exports, '__esModule', { value: true }); 4 5const beforeExpr = true; 6const startsExpr = true; 7const isLoop = true; 8const isAssign = true; 9const prefix = true; 10const postfix = true; 11class TokenType { 12 constructor(label, conf = {}) { 13 this.label = label; 14 this.keyword = conf.keyword; 15 this.beforeExpr = !!conf.beforeExpr; 16 this.startsExpr = !!conf.startsExpr; 17 this.rightAssociative = !!conf.rightAssociative; 18 this.isLoop = !!conf.isLoop; 19 this.isAssign = !!conf.isAssign; 20 this.prefix = !!conf.prefix; 21 this.postfix = !!conf.postfix; 22 this.binop = conf.binop != null ? conf.binop : null; 23 this.updateContext = null; 24 } 25 26} 27const keywords = new Map(); 28 29function createKeyword(name, options = {}) { 30 options.keyword = name; 31 const token = new TokenType(name, options); 32 keywords.set(name, token); 33 return token; 34} 35 36function createBinop(name, binop) { 37 return new TokenType(name, { 38 beforeExpr, 39 binop 40 }); 41} 42 43const types = { 44 num: new TokenType("num", { 45 startsExpr 46 }), 47 bigint: new TokenType("bigint", { 48 startsExpr 49 }), 50 regexp: new TokenType("regexp", { 51 startsExpr 52 }), 53 string: new TokenType("string", { 54 startsExpr 55 }), 56 name: new TokenType("name", { 57 startsExpr 58 }), 59 eof: new TokenType("eof"), 60 bracketL: new TokenType("[", { 61 beforeExpr, 62 startsExpr 63 }), 64 bracketR: new TokenType("]"), 65 braceL: new TokenType("{", { 66 beforeExpr, 67 startsExpr 68 }), 69 braceBarL: new TokenType("{|", { 70 beforeExpr, 71 startsExpr 72 }), 73 braceR: new TokenType("}"), 74 braceBarR: new TokenType("|}"), 75 parenL: new TokenType("(", { 76 beforeExpr, 77 startsExpr 78 }), 79 parenR: new TokenType(")"), 80 comma: new TokenType(",", { 81 beforeExpr 82 }), 83 semi: new TokenType(";", { 84 beforeExpr 85 }), 86 colon: new TokenType(":", { 87 beforeExpr 88 }), 89 doubleColon: new TokenType("::", { 90 beforeExpr 91 }), 92 dot: new TokenType("."), 93 question: new TokenType("?", { 94 beforeExpr 95 }), 96 questionDot: new TokenType("?."), 97 arrow: new TokenType("=>", { 98 beforeExpr 99 }), 100 template: new TokenType("template"), 101 ellipsis: new TokenType("...", { 102 beforeExpr 103 }), 104 backQuote: new TokenType("`", { 105 startsExpr 106 }), 107 dollarBraceL: new TokenType("${", { 108 beforeExpr, 109 startsExpr 110 }), 111 at: new TokenType("@"), 112 hash: new TokenType("#", { 113 startsExpr 114 }), 115 interpreterDirective: new TokenType("#!..."), 116 eq: new TokenType("=", { 117 beforeExpr, 118 isAssign 119 }), 120 assign: new TokenType("_=", { 121 beforeExpr, 122 isAssign 123 }), 124 incDec: new TokenType("++/--", { 125 prefix, 126 postfix, 127 startsExpr 128 }), 129 bang: new TokenType("!", { 130 beforeExpr, 131 prefix, 132 startsExpr 133 }), 134 tilde: new TokenType("~", { 135 beforeExpr, 136 prefix, 137 startsExpr 138 }), 139 pipeline: createBinop("|>", 0), 140 nullishCoalescing: createBinop("??", 1), 141 logicalOR: createBinop("||", 1), 142 logicalAND: createBinop("&&", 2), 143 bitwiseOR: createBinop("|", 3), 144 bitwiseXOR: createBinop("^", 4), 145 bitwiseAND: createBinop("&", 5), 146 equality: createBinop("==/!=/===/!==", 6), 147 relational: createBinop("</>/<=/>=", 7), 148 bitShift: createBinop("<</>>/>>>", 8), 149 plusMin: new TokenType("+/-", { 150 beforeExpr, 151 binop: 9, 152 prefix, 153 startsExpr 154 }), 155 modulo: createBinop("%", 10), 156 star: createBinop("*", 10), 157 slash: createBinop("/", 10), 158 exponent: new TokenType("**", { 159 beforeExpr, 160 binop: 11, 161 rightAssociative: true 162 }), 163 _break: createKeyword("break"), 164 _case: createKeyword("case", { 165 beforeExpr 166 }), 167 _catch: createKeyword("catch"), 168 _continue: createKeyword("continue"), 169 _debugger: createKeyword("debugger"), 170 _default: createKeyword("default", { 171 beforeExpr 172 }), 173 _do: createKeyword("do", { 174 isLoop, 175 beforeExpr 176 }), 177 _else: createKeyword("else", { 178 beforeExpr 179 }), 180 _finally: createKeyword("finally"), 181 _for: createKeyword("for", { 182 isLoop 183 }), 184 _function: createKeyword("function", { 185 startsExpr 186 }), 187 _if: createKeyword("if"), 188 _return: createKeyword("return", { 189 beforeExpr 190 }), 191 _switch: createKeyword("switch"), 192 _throw: createKeyword("throw", { 193 beforeExpr, 194 prefix, 195 startsExpr 196 }), 197 _try: createKeyword("try"), 198 _var: createKeyword("var"), 199 _const: createKeyword("const"), 200 _while: createKeyword("while", { 201 isLoop 202 }), 203 _with: createKeyword("with"), 204 _new: createKeyword("new", { 205 beforeExpr, 206 startsExpr 207 }), 208 _this: createKeyword("this", { 209 startsExpr 210 }), 211 _super: createKeyword("super", { 212 startsExpr 213 }), 214 _class: createKeyword("class", { 215 startsExpr 216 }), 217 _extends: createKeyword("extends", { 218 beforeExpr 219 }), 220 _export: createKeyword("export"), 221 _import: createKeyword("import", { 222 startsExpr 223 }), 224 _null: createKeyword("null", { 225 startsExpr 226 }), 227 _true: createKeyword("true", { 228 startsExpr 229 }), 230 _false: createKeyword("false", { 231 startsExpr 232 }), 233 _in: createKeyword("in", { 234 beforeExpr, 235 binop: 7 236 }), 237 _instanceof: createKeyword("instanceof", { 238 beforeExpr, 239 binop: 7 240 }), 241 _typeof: createKeyword("typeof", { 242 beforeExpr, 243 prefix, 244 startsExpr 245 }), 246 _void: createKeyword("void", { 247 beforeExpr, 248 prefix, 249 startsExpr 250 }), 251 _delete: createKeyword("delete", { 252 beforeExpr, 253 prefix, 254 startsExpr 255 }) 256}; 257 258const SCOPE_OTHER = 0b000000000, 259 SCOPE_PROGRAM = 0b000000001, 260 SCOPE_FUNCTION = 0b000000010, 261 SCOPE_ASYNC = 0b000000100, 262 SCOPE_GENERATOR = 0b000001000, 263 SCOPE_ARROW = 0b000010000, 264 SCOPE_SIMPLE_CATCH = 0b000100000, 265 SCOPE_SUPER = 0b001000000, 266 SCOPE_DIRECT_SUPER = 0b010000000, 267 SCOPE_CLASS = 0b100000000, 268 SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION; 269function functionFlags(isAsync, isGenerator) { 270 return SCOPE_FUNCTION | (isAsync ? SCOPE_ASYNC : 0) | (isGenerator ? SCOPE_GENERATOR : 0); 271} 272const BIND_KIND_VALUE = 0b00000000001, 273 BIND_KIND_TYPE = 0b00000000010, 274 BIND_SCOPE_VAR = 0b00000000100, 275 BIND_SCOPE_LEXICAL = 0b00000001000, 276 BIND_SCOPE_FUNCTION = 0b00000010000, 277 BIND_FLAGS_NONE = 0b00001000000, 278 BIND_FLAGS_CLASS = 0b00010000000, 279 BIND_FLAGS_TS_ENUM = 0b00100000000, 280 BIND_FLAGS_TS_CONST_ENUM = 0b01000000000, 281 BIND_FLAGS_TS_EXPORT_ONLY = 0b10000000000; 282const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_CLASS, 283 BIND_LEXICAL = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | 0, 284 BIND_VAR = BIND_KIND_VALUE | 0 | BIND_SCOPE_VAR | 0, 285 BIND_FUNCTION = BIND_KIND_VALUE | 0 | BIND_SCOPE_FUNCTION | 0, 286 BIND_TS_INTERFACE = 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_CLASS, 287 BIND_TS_TYPE = 0 | BIND_KIND_TYPE | 0 | 0, 288 BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM, 289 BIND_TS_FN_TYPE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY, 290 BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE, 291 BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE, 292 BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM, 293 BIND_TS_NAMESPACE = BIND_TS_FN_TYPE; 294 295function isSimpleProperty(node) { 296 return node != null && node.type === "Property" && node.kind === "init" && node.method === false; 297} 298 299var estree = (superClass => class extends superClass { 300 estreeParseRegExpLiteral({ 301 pattern, 302 flags 303 }) { 304 let regex = null; 305 306 try { 307 regex = new RegExp(pattern, flags); 308 } catch (e) {} 309 310 const node = this.estreeParseLiteral(regex); 311 node.regex = { 312 pattern, 313 flags 314 }; 315 return node; 316 } 317 318 estreeParseLiteral(value) { 319 return this.parseLiteral(value, "Literal"); 320 } 321 322 directiveToStmt(directive) { 323 const directiveLiteral = directive.value; 324 const stmt = this.startNodeAt(directive.start, directive.loc.start); 325 const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); 326 expression.value = directiveLiteral.value; 327 expression.raw = directiveLiteral.extra.raw; 328 stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); 329 stmt.directive = directiveLiteral.extra.raw.slice(1, -1); 330 return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); 331 } 332 333 initFunction(node, isAsync) { 334 super.initFunction(node, isAsync); 335 node.expression = false; 336 } 337 338 checkDeclaration(node) { 339 if (isSimpleProperty(node)) { 340 this.checkDeclaration(node.value); 341 } else { 342 super.checkDeclaration(node); 343 } 344 } 345 346 checkGetterSetterParams(method) { 347 const prop = method; 348 const paramCount = prop.kind === "get" ? 0 : 1; 349 const start = prop.start; 350 351 if (prop.value.params.length !== paramCount) { 352 if (prop.kind === "get") { 353 this.raise(start, "getter must not have any formal parameters"); 354 } else { 355 this.raise(start, "setter must have exactly one formal parameter"); 356 } 357 } 358 359 if (prop.kind === "set" && prop.value.params[0].type === "RestElement") { 360 this.raise(start, "setter function argument must not be a rest parameter"); 361 } 362 } 363 364 checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) { 365 switch (expr.type) { 366 case "ObjectPattern": 367 expr.properties.forEach(prop => { 368 this.checkLVal(prop.type === "Property" ? prop.value : prop, bindingType, checkClashes, "object destructuring pattern"); 369 }); 370 break; 371 372 default: 373 super.checkLVal(expr, bindingType, checkClashes, contextDescription); 374 } 375 } 376 377 checkPropClash(prop, propHash) { 378 if (prop.type === "SpreadElement" || prop.computed || prop.method || prop.shorthand) { 379 return; 380 } 381 382 const key = prop.key; 383 const name = key.type === "Identifier" ? key.name : String(key.value); 384 385 if (name === "__proto__" && prop.kind === "init") { 386 if (propHash.proto) { 387 this.raise(key.start, "Redefinition of __proto__ property"); 388 } 389 390 propHash.proto = true; 391 } 392 } 393 394 isStrictBody(node) { 395 const isBlockStatement = node.body.type === "BlockStatement"; 396 397 if (isBlockStatement && node.body.body.length > 0) { 398 for (let _i = 0, _node$body$body = node.body.body; _i < _node$body$body.length; _i++) { 399 const directive = _node$body$body[_i]; 400 401 if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") { 402 if (directive.expression.value === "use strict") return true; 403 } else { 404 break; 405 } 406 } 407 } 408 409 return false; 410 } 411 412 isValidDirective(stmt) { 413 return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && (!stmt.expression.extra || !stmt.expression.extra.parenthesized); 414 } 415 416 stmtToDirective(stmt) { 417 const directive = super.stmtToDirective(stmt); 418 const value = stmt.expression.value; 419 directive.value.value = value; 420 return directive; 421 } 422 423 parseBlockBody(node, allowDirectives, topLevel, end) { 424 super.parseBlockBody(node, allowDirectives, topLevel, end); 425 const directiveStatements = node.directives.map(d => this.directiveToStmt(d)); 426 node.body = directiveStatements.concat(node.body); 427 delete node.directives; 428 } 429 430 pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { 431 this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true); 432 433 if (method.typeParameters) { 434 method.value.typeParameters = method.typeParameters; 435 delete method.typeParameters; 436 } 437 438 classBody.body.push(method); 439 } 440 441 parseExprAtom(refShorthandDefaultPos) { 442 switch (this.state.type) { 443 case types.regexp: 444 return this.estreeParseRegExpLiteral(this.state.value); 445 446 case types.num: 447 case types.string: 448 return this.estreeParseLiteral(this.state.value); 449 450 case types._null: 451 return this.estreeParseLiteral(null); 452 453 case types._true: 454 return this.estreeParseLiteral(true); 455 456 case types._false: 457 return this.estreeParseLiteral(false); 458 459 default: 460 return super.parseExprAtom(refShorthandDefaultPos); 461 } 462 } 463 464 parseLiteral(value, type, startPos, startLoc) { 465 const node = super.parseLiteral(value, type, startPos, startLoc); 466 node.raw = node.extra.raw; 467 delete node.extra; 468 return node; 469 } 470 471 parseFunctionBody(node, allowExpression, isMethod = false) { 472 super.parseFunctionBody(node, allowExpression, isMethod); 473 node.expression = node.body.type !== "BlockStatement"; 474 } 475 476 parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { 477 let funcNode = this.startNode(); 478 funcNode.kind = node.kind; 479 funcNode = super.parseMethod(funcNode, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope); 480 funcNode.type = "FunctionExpression"; 481 delete funcNode.kind; 482 node.value = funcNode; 483 type = type === "ClassMethod" ? "MethodDefinition" : type; 484 return this.finishNode(node, type); 485 } 486 487 parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) { 488 const node = super.parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc); 489 490 if (node) { 491 node.type = "Property"; 492 if (node.kind === "method") node.kind = "init"; 493 node.shorthand = false; 494 } 495 496 return node; 497 } 498 499 parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { 500 const node = super.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); 501 502 if (node) { 503 node.kind = "init"; 504 node.type = "Property"; 505 } 506 507 return node; 508 } 509 510 toAssignable(node, isBinding, contextDescription) { 511 if (isSimpleProperty(node)) { 512 this.toAssignable(node.value, isBinding, contextDescription); 513 return node; 514 } 515 516 return super.toAssignable(node, isBinding, contextDescription); 517 } 518 519 toAssignableObjectExpressionProp(prop, isBinding, isLast) { 520 if (prop.kind === "get" || prop.kind === "set") { 521 this.raise(prop.key.start, "Object pattern can't contain getter or setter"); 522 } else if (prop.method) { 523 this.raise(prop.key.start, "Object pattern can't contain methods"); 524 } else { 525 super.toAssignableObjectExpressionProp(prop, isBinding, isLast); 526 } 527 } 528 529}); 530 531const lineBreak = /\r\n?|[\n\u2028\u2029]/; 532const lineBreakG = new RegExp(lineBreak.source, "g"); 533function isNewLine(code) { 534 switch (code) { 535 case 10: 536 case 13: 537 case 8232: 538 case 8233: 539 return true; 540 541 default: 542 return false; 543 } 544} 545const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; 546function isWhitespace(code) { 547 switch (code) { 548 case 0x0009: 549 case 0x000b: 550 case 0x000c: 551 case 32: 552 case 160: 553 case 5760: 554 case 0x2000: 555 case 0x2001: 556 case 0x2002: 557 case 0x2003: 558 case 0x2004: 559 case 0x2005: 560 case 0x2006: 561 case 0x2007: 562 case 0x2008: 563 case 0x2009: 564 case 0x200a: 565 case 0x202f: 566 case 0x205f: 567 case 0x3000: 568 case 0xfeff: 569 return true; 570 571 default: 572 return false; 573 } 574} 575 576class TokContext { 577 constructor(token, isExpr, preserveSpace, override) { 578 this.token = token; 579 this.isExpr = !!isExpr; 580 this.preserveSpace = !!preserveSpace; 581 this.override = override; 582 } 583 584} 585const types$1 = { 586 braceStatement: new TokContext("{", false), 587 braceExpression: new TokContext("{", true), 588 templateQuasi: new TokContext("${", false), 589 parenStatement: new TokContext("(", false), 590 parenExpression: new TokContext("(", true), 591 template: new TokContext("`", true, true, p => p.readTmplToken()), 592 functionExpression: new TokContext("function", true), 593 functionStatement: new TokContext("function", false) 594}; 595 596types.parenR.updateContext = types.braceR.updateContext = function () { 597 if (this.state.context.length === 1) { 598 this.state.exprAllowed = true; 599 return; 600 } 601 602 let out = this.state.context.pop(); 603 604 if (out === types$1.braceStatement && this.curContext().token === "function") { 605 out = this.state.context.pop(); 606 } 607 608 this.state.exprAllowed = !out.isExpr; 609}; 610 611types.name.updateContext = function (prevType) { 612 let allowed = false; 613 614 if (prevType !== types.dot) { 615 if (this.state.value === "of" && !this.state.exprAllowed || this.state.value === "yield" && this.scope.inGenerator) { 616 allowed = true; 617 } 618 } 619 620 this.state.exprAllowed = allowed; 621 622 if (this.state.isIterator) { 623 this.state.isIterator = false; 624 } 625}; 626 627types.braceL.updateContext = function (prevType) { 628 this.state.context.push(this.braceIsBlock(prevType) ? types$1.braceStatement : types$1.braceExpression); 629 this.state.exprAllowed = true; 630}; 631 632types.dollarBraceL.updateContext = function () { 633 this.state.context.push(types$1.templateQuasi); 634 this.state.exprAllowed = true; 635}; 636 637types.parenL.updateContext = function (prevType) { 638 const statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; 639 this.state.context.push(statementParens ? types$1.parenStatement : types$1.parenExpression); 640 this.state.exprAllowed = true; 641}; 642 643types.incDec.updateContext = function () {}; 644 645types._function.updateContext = types._class.updateContext = function (prevType) { 646 if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && !(prevType === types._return && lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) && !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) { 647 this.state.context.push(types$1.functionExpression); 648 } else { 649 this.state.context.push(types$1.functionStatement); 650 } 651 652 this.state.exprAllowed = false; 653}; 654 655types.backQuote.updateContext = function () { 656 if (this.curContext() === types$1.template) { 657 this.state.context.pop(); 658 } else { 659 this.state.context.push(types$1.template); 660 } 661 662 this.state.exprAllowed = false; 663}; 664 665const reservedWords = { 666 strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], 667 strictBind: ["eval", "arguments"] 668}; 669const reservedWordsStrictSet = new Set(reservedWords.strict); 670const reservedWordsStrictBindSet = new Set(reservedWords.strict.concat(reservedWords.strictBind)); 671const isReservedWord = (word, inModule) => { 672 return inModule && word === "await" || word === "enum"; 673}; 674function isStrictReservedWord(word, inModule) { 675 return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); 676} 677function isStrictBindReservedWord(word, inModule) { 678 return isReservedWord(word, inModule) || reservedWordsStrictBindSet.has(word); 679} 680function isKeyword(word) { 681 return keywords.has(word); 682} 683const keywordRelationalOperator = /^in(stanceof)?$/; 684let nonASCIIidentifierStartChars = "\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\u0560-\u0588\u05d0-\u05ea\u05ef-\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\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\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\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\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-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7c6\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\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-\uab67\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; 685let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; 686const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); 687const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); 688nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; 689const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 477, 28, 11, 0, 9, 21, 155, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 12, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 0, 33, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 0, 161, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 270, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 754, 9486, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541]; 690const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 525, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 232, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 792487, 239]; 691 692function isInAstralSet(code, set) { 693 let pos = 0x10000; 694 695 for (let i = 0, length = set.length; i < length; i += 2) { 696 pos += set[i]; 697 if (pos > code) return false; 698 pos += set[i + 1]; 699 if (pos >= code) return true; 700 } 701 702 return false; 703} 704 705function isIdentifierStart(code) { 706 if (code < 65) return code === 36; 707 if (code <= 90) return true; 708 if (code < 97) return code === 95; 709 if (code <= 122) return true; 710 711 if (code <= 0xffff) { 712 return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); 713 } 714 715 return isInAstralSet(code, astralIdentifierStartCodes); 716} 717function isIteratorStart(current, next) { 718 return current === 64 && next === 64; 719} 720function isIdentifierChar(code) { 721 if (code < 48) return code === 36; 722 if (code < 58) return true; 723 if (code < 65) return false; 724 if (code <= 90) return true; 725 if (code < 97) return code === 95; 726 if (code <= 122) return true; 727 728 if (code <= 0xffff) { 729 return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); 730 } 731 732 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); 733} 734 735const reservedTypes = ["any", "bool", "boolean", "empty", "false", "mixed", "null", "number", "static", "string", "true", "typeof", "void", "interface", "extends", "_"]; 736 737function isEsModuleType(bodyElement) { 738 return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration"); 739} 740 741function hasTypeImportKind(node) { 742 return node.importKind === "type" || node.importKind === "typeof"; 743} 744 745function isMaybeDefaultImport(state) { 746 return (state.type === types.name || !!state.type.keyword) && state.value !== "from"; 747} 748 749const exportSuggestions = { 750 const: "declare export var", 751 let: "declare export var", 752 type: "export type", 753 interface: "export interface" 754}; 755 756function partition(list, test) { 757 const list1 = []; 758 const list2 = []; 759 760 for (let i = 0; i < list.length; i++) { 761 (test(list[i], i, list) ? list1 : list2).push(list[i]); 762 } 763 764 return [list1, list2]; 765} 766 767const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/; 768var flow = (superClass => class extends superClass { 769 constructor(options, input) { 770 super(options, input); 771 this.flowPragma = undefined; 772 } 773 774 shouldParseTypes() { 775 return this.getPluginOption("flow", "all") || this.flowPragma === "flow"; 776 } 777 778 finishToken(type, val) { 779 if (type !== types.string && type !== types.semi && type !== types.interpreterDirective) { 780 if (this.flowPragma === undefined) { 781 this.flowPragma = null; 782 } 783 } 784 785 return super.finishToken(type, val); 786 } 787 788 addComment(comment) { 789 if (this.flowPragma === undefined) { 790 const matches = FLOW_PRAGMA_REGEX.exec(comment.value); 791 792 if (!matches) ; else if (matches[1] === "flow") { 793 this.flowPragma = "flow"; 794 } else if (matches[1] === "noflow") { 795 this.flowPragma = "noflow"; 796 } else { 797 throw new Error("Unexpected flow pragma"); 798 } 799 } 800 801 return super.addComment(comment); 802 } 803 804 flowParseTypeInitialiser(tok) { 805 const oldInType = this.state.inType; 806 this.state.inType = true; 807 this.expect(tok || types.colon); 808 const type = this.flowParseType(); 809 this.state.inType = oldInType; 810 return type; 811 } 812 813 flowParsePredicate() { 814 const node = this.startNode(); 815 const moduloLoc = this.state.startLoc; 816 const moduloPos = this.state.start; 817 this.expect(types.modulo); 818 const checksLoc = this.state.startLoc; 819 this.expectContextual("checks"); 820 821 if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { 822 this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here."); 823 } 824 825 if (this.eat(types.parenL)) { 826 node.value = this.parseExpression(); 827 this.expect(types.parenR); 828 return this.finishNode(node, "DeclaredPredicate"); 829 } else { 830 return this.finishNode(node, "InferredPredicate"); 831 } 832 } 833 834 flowParseTypeAndPredicateInitialiser() { 835 const oldInType = this.state.inType; 836 this.state.inType = true; 837 this.expect(types.colon); 838 let type = null; 839 let predicate = null; 840 841 if (this.match(types.modulo)) { 842 this.state.inType = oldInType; 843 predicate = this.flowParsePredicate(); 844 } else { 845 type = this.flowParseType(); 846 this.state.inType = oldInType; 847 848 if (this.match(types.modulo)) { 849 predicate = this.flowParsePredicate(); 850 } 851 } 852 853 return [type, predicate]; 854 } 855 856 flowParseDeclareClass(node) { 857 this.next(); 858 this.flowParseInterfaceish(node, true); 859 return this.finishNode(node, "DeclareClass"); 860 } 861 862 flowParseDeclareFunction(node) { 863 this.next(); 864 const id = node.id = this.parseIdentifier(); 865 const typeNode = this.startNode(); 866 const typeContainer = this.startNode(); 867 868 if (this.isRelational("<")) { 869 typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); 870 } else { 871 typeNode.typeParameters = null; 872 } 873 874 this.expect(types.parenL); 875 const tmp = this.flowParseFunctionTypeParams(); 876 typeNode.params = tmp.params; 877 typeNode.rest = tmp.rest; 878 this.expect(types.parenR); 879 [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); 880 typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); 881 id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); 882 this.resetEndLocation(id); 883 this.semicolon(); 884 return this.finishNode(node, "DeclareFunction"); 885 } 886 887 flowParseDeclare(node, insideModule) { 888 if (this.match(types._class)) { 889 return this.flowParseDeclareClass(node); 890 } else if (this.match(types._function)) { 891 return this.flowParseDeclareFunction(node); 892 } else if (this.match(types._var)) { 893 return this.flowParseDeclareVariable(node); 894 } else if (this.eatContextual("module")) { 895 if (this.match(types.dot)) { 896 return this.flowParseDeclareModuleExports(node); 897 } else { 898 if (insideModule) { 899 this.unexpected(this.state.lastTokStart, "`declare module` cannot be used inside another `declare module`"); 900 } 901 902 return this.flowParseDeclareModule(node); 903 } 904 } else if (this.isContextual("type")) { 905 return this.flowParseDeclareTypeAlias(node); 906 } else if (this.isContextual("opaque")) { 907 return this.flowParseDeclareOpaqueType(node); 908 } else if (this.isContextual("interface")) { 909 return this.flowParseDeclareInterface(node); 910 } else if (this.match(types._export)) { 911 return this.flowParseDeclareExportDeclaration(node, insideModule); 912 } else { 913 throw this.unexpected(); 914 } 915 } 916 917 flowParseDeclareVariable(node) { 918 this.next(); 919 node.id = this.flowParseTypeAnnotatableIdentifier(true); 920 this.semicolon(); 921 return this.finishNode(node, "DeclareVariable"); 922 } 923 924 flowParseDeclareModule(node) { 925 this.scope.enter(SCOPE_OTHER); 926 927 if (this.match(types.string)) { 928 node.id = this.parseExprAtom(); 929 } else { 930 node.id = this.parseIdentifier(); 931 } 932 933 const bodyNode = node.body = this.startNode(); 934 const body = bodyNode.body = []; 935 this.expect(types.braceL); 936 937 while (!this.match(types.braceR)) { 938 let bodyNode = this.startNode(); 939 940 if (this.match(types._import)) { 941 this.next(); 942 943 if (!this.isContextual("type") && !this.match(types._typeof)) { 944 this.unexpected(this.state.lastTokStart, "Imports within a `declare module` body must always be `import type` or `import typeof`"); 945 } 946 947 this.parseImport(bodyNode); 948 } else { 949 this.expectContextual("declare", "Only declares and type imports are allowed inside declare module"); 950 bodyNode = this.flowParseDeclare(bodyNode, true); 951 } 952 953 body.push(bodyNode); 954 } 955 956 this.scope.exit(); 957 this.expect(types.braceR); 958 this.finishNode(bodyNode, "BlockStatement"); 959 let kind = null; 960 let hasModuleExport = false; 961 const errorMessage = "Found both `declare module.exports` and `declare export` in the same module. " + "Modules can only have 1 since they are either an ES module or they are a CommonJS module"; 962 body.forEach(bodyElement => { 963 if (isEsModuleType(bodyElement)) { 964 if (kind === "CommonJS") { 965 this.unexpected(bodyElement.start, errorMessage); 966 } 967 968 kind = "ES"; 969 } else if (bodyElement.type === "DeclareModuleExports") { 970 if (hasModuleExport) { 971 this.unexpected(bodyElement.start, "Duplicate `declare module.exports` statement"); 972 } 973 974 if (kind === "ES") this.unexpected(bodyElement.start, errorMessage); 975 kind = "CommonJS"; 976 hasModuleExport = true; 977 } 978 }); 979 node.kind = kind || "CommonJS"; 980 return this.finishNode(node, "DeclareModule"); 981 } 982 983 flowParseDeclareExportDeclaration(node, insideModule) { 984 this.expect(types._export); 985 986 if (this.eat(types._default)) { 987 if (this.match(types._function) || this.match(types._class)) { 988 node.declaration = this.flowParseDeclare(this.startNode()); 989 } else { 990 node.declaration = this.flowParseType(); 991 this.semicolon(); 992 } 993 994 node.default = true; 995 return this.finishNode(node, "DeclareExportDeclaration"); 996 } else { 997 if (this.match(types._const) || this.isLet() || (this.isContextual("type") || this.isContextual("interface")) && !insideModule) { 998 const label = this.state.value; 999 const suggestion = exportSuggestions[label]; 1000 this.unexpected(this.state.start, `\`declare export ${label}\` is not supported. Use \`${suggestion}\` instead`); 1001 } 1002 1003 if (this.match(types._var) || this.match(types._function) || this.match(types._class) || this.isContextual("opaque")) { 1004 node.declaration = this.flowParseDeclare(this.startNode()); 1005 node.default = false; 1006 return this.finishNode(node, "DeclareExportDeclaration"); 1007 } else if (this.match(types.star) || this.match(types.braceL) || this.isContextual("interface") || this.isContextual("type") || this.isContextual("opaque")) { 1008 node = this.parseExport(node); 1009 1010 if (node.type === "ExportNamedDeclaration") { 1011 node.type = "ExportDeclaration"; 1012 node.default = false; 1013 delete node.exportKind; 1014 } 1015 1016 node.type = "Declare" + node.type; 1017 return node; 1018 } 1019 } 1020 1021 throw this.unexpected(); 1022 } 1023 1024 flowParseDeclareModuleExports(node) { 1025 this.next(); 1026 this.expectContextual("exports"); 1027 node.typeAnnotation = this.flowParseTypeAnnotation(); 1028 this.semicolon(); 1029 return this.finishNode(node, "DeclareModuleExports"); 1030 } 1031 1032 flowParseDeclareTypeAlias(node) { 1033 this.next(); 1034 this.flowParseTypeAlias(node); 1035 node.type = "DeclareTypeAlias"; 1036 return node; 1037 } 1038 1039 flowParseDeclareOpaqueType(node) { 1040 this.next(); 1041 this.flowParseOpaqueType(node, true); 1042 node.type = "DeclareOpaqueType"; 1043 return node; 1044 } 1045 1046 flowParseDeclareInterface(node) { 1047 this.next(); 1048 this.flowParseInterfaceish(node); 1049 return this.finishNode(node, "DeclareInterface"); 1050 } 1051 1052 flowParseInterfaceish(node, isClass = false) { 1053 node.id = this.flowParseRestrictedIdentifier(!isClass); 1054 1055 if (this.isRelational("<")) { 1056 node.typeParameters = this.flowParseTypeParameterDeclaration(); 1057 } else { 1058 node.typeParameters = null; 1059 } 1060 1061 node.extends = []; 1062 node.implements = []; 1063 node.mixins = []; 1064 1065 if (this.eat(types._extends)) { 1066 do { 1067 node.extends.push(this.flowParseInterfaceExtends()); 1068 } while (!isClass && this.eat(types.comma)); 1069 } 1070 1071 if (this.isContextual("mixins")) { 1072 this.next(); 1073 1074 do { 1075 node.mixins.push(this.flowParseInterfaceExtends()); 1076 } while (this.eat(types.comma)); 1077 } 1078 1079 if (this.isContextual("implements")) { 1080 this.next(); 1081 1082 do { 1083 node.implements.push(this.flowParseInterfaceExtends()); 1084 } while (this.eat(types.comma)); 1085 } 1086 1087 node.body = this.flowParseObjectType({ 1088 allowStatic: isClass, 1089 allowExact: false, 1090 allowSpread: false, 1091 allowProto: isClass, 1092 allowInexact: false 1093 }); 1094 } 1095 1096 flowParseInterfaceExtends() { 1097 const node = this.startNode(); 1098 node.id = this.flowParseQualifiedTypeIdentifier(); 1099 1100 if (this.isRelational("<")) { 1101 node.typeParameters = this.flowParseTypeParameterInstantiation(); 1102 } else { 1103 node.typeParameters = null; 1104 } 1105 1106 return this.finishNode(node, "InterfaceExtends"); 1107 } 1108 1109 flowParseInterface(node) { 1110 this.flowParseInterfaceish(node); 1111 return this.finishNode(node, "InterfaceDeclaration"); 1112 } 1113 1114 checkNotUnderscore(word) { 1115 if (word === "_") { 1116 throw this.unexpected(null, "`_` is only allowed as a type argument to call or new"); 1117 } 1118 } 1119 1120 checkReservedType(word, startLoc) { 1121 if (reservedTypes.indexOf(word) > -1) { 1122 this.raise(startLoc, `Cannot overwrite reserved type ${word}`); 1123 } 1124 } 1125 1126 flowParseRestrictedIdentifier(liberal) { 1127 this.checkReservedType(this.state.value, this.state.start); 1128 return this.parseIdentifier(liberal); 1129 } 1130 1131 flowParseTypeAlias(node) { 1132 node.id = this.flowParseRestrictedIdentifier(); 1133 this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); 1134 1135 if (this.isRelational("<")) { 1136 node.typeParameters = this.flowParseTypeParameterDeclaration(); 1137 } else { 1138 node.typeParameters = null; 1139 } 1140 1141 node.right = this.flowParseTypeInitialiser(types.eq); 1142 this.semicolon(); 1143 return this.finishNode(node, "TypeAlias"); 1144 } 1145 1146 flowParseOpaqueType(node, declare) { 1147 this.expectContextual("type"); 1148 node.id = this.flowParseRestrictedIdentifier(true); 1149 this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); 1150 1151 if (this.isRelational("<")) { 1152 node.typeParameters = this.flowParseTypeParameterDeclaration(); 1153 } else { 1154 node.typeParameters = null; 1155 } 1156 1157 node.supertype = null; 1158 1159 if (this.match(types.colon)) { 1160 node.supertype = this.flowParseTypeInitialiser(types.colon); 1161 } 1162 1163 node.impltype = null; 1164 1165 if (!declare) { 1166 node.impltype = this.flowParseTypeInitialiser(types.eq); 1167 } 1168 1169 this.semicolon(); 1170 return this.finishNode(node, "OpaqueType"); 1171 } 1172 1173 flowParseTypeParameter(requireDefault = false) { 1174 const nodeStart = this.state.start; 1175 const node = this.startNode(); 1176 const variance = this.flowParseVariance(); 1177 const ident = this.flowParseTypeAnnotatableIdentifier(); 1178 node.name = ident.name; 1179 node.variance = variance; 1180 node.bound = ident.typeAnnotation; 1181 1182 if (this.match(types.eq)) { 1183 this.eat(types.eq); 1184 node.default = this.flowParseType(); 1185 } else { 1186 if (requireDefault) { 1187 this.unexpected(nodeStart, "Type parameter declaration needs a default, since a preceding type parameter declaration has a default."); 1188 } 1189 } 1190 1191 return this.finishNode(node, "TypeParameter"); 1192 } 1193 1194 flowParseTypeParameterDeclaration() { 1195 const oldInType = this.state.inType; 1196 const node = this.startNode(); 1197 node.params = []; 1198 this.state.inType = true; 1199 1200 if (this.isRelational("<") || this.match(types.jsxTagStart)) { 1201 this.next(); 1202 } else { 1203 this.unexpected(); 1204 } 1205 1206 let defaultRequired = false; 1207 1208 do { 1209 const typeParameter = this.flowParseTypeParameter(defaultRequired); 1210 node.params.push(typeParameter); 1211 1212 if (typeParameter.default) { 1213 defaultRequired = true; 1214 } 1215 1216 if (!this.isRelational(">")) { 1217 this.expect(types.comma); 1218 } 1219 } while (!this.isRelational(">")); 1220 1221 this.expectRelational(">"); 1222 this.state.inType = oldInType; 1223 return this.finishNode(node, "TypeParameterDeclaration"); 1224 } 1225 1226 flowParseTypeParameterInstantiation() { 1227 const node = this.startNode(); 1228 const oldInType = this.state.inType; 1229 node.params = []; 1230 this.state.inType = true; 1231 this.expectRelational("<"); 1232 const oldNoAnonFunctionType = this.state.noAnonFunctionType; 1233 this.state.noAnonFunctionType = false; 1234 1235 while (!this.isRelational(">")) { 1236 node.params.push(this.flowParseType()); 1237 1238 if (!this.isRelational(">")) { 1239 this.expect(types.comma); 1240 } 1241 } 1242 1243 this.state.noAnonFunctionType = oldNoAnonFunctionType; 1244 this.expectRelational(">"); 1245 this.state.inType = oldInType; 1246 return this.finishNode(node, "TypeParameterInstantiation"); 1247 } 1248 1249 flowParseTypeParameterInstantiationCallOrNew() { 1250 const node = this.startNode(); 1251 const oldInType = this.state.inType; 1252 node.params = []; 1253 this.state.inType = true; 1254 this.expectRelational("<"); 1255 1256 while (!this.isRelational(">")) { 1257 node.params.push(this.flowParseTypeOrImplicitInstantiation()); 1258 1259 if (!this.isRelational(">")) { 1260 this.expect(types.comma); 1261 } 1262 } 1263 1264 this.expectRelational(">"); 1265 this.state.inType = oldInType; 1266 return this.finishNode(node, "TypeParameterInstantiation"); 1267 } 1268 1269 flowParseInterfaceType() { 1270 const node = this.startNode(); 1271 this.expectContextual("interface"); 1272 node.extends = []; 1273 1274 if (this.eat(types._extends)) { 1275 do { 1276 node.extends.push(this.flowParseInterfaceExtends()); 1277 } while (this.eat(types.comma)); 1278 } 1279 1280 node.body = this.flowParseObjectType({ 1281 allowStatic: false, 1282 allowExact: false, 1283 allowSpread: false, 1284 allowProto: false, 1285 allowInexact: false 1286 }); 1287 return this.finishNode(node, "InterfaceTypeAnnotation"); 1288 } 1289 1290 flowParseObjectPropertyKey() { 1291 return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); 1292 } 1293 1294 flowParseObjectTypeIndexer(node, isStatic, variance) { 1295 node.static = isStatic; 1296 1297 if (this.lookahead().type === types.colon) { 1298 node.id = this.flowParseObjectPropertyKey(); 1299 node.key = this.flowParseTypeInitialiser(); 1300 } else { 1301 node.id = null; 1302 node.key = this.flowParseType(); 1303 } 1304 1305 this.expect(types.bracketR); 1306 node.value = this.flowParseTypeInitialiser(); 1307 node.variance = variance; 1308 return this.finishNode(node, "ObjectTypeIndexer"); 1309 } 1310 1311 flowParseObjectTypeInternalSlot(node, isStatic) { 1312 node.static = isStatic; 1313 node.id = this.flowParseObjectPropertyKey(); 1314 this.expect(types.bracketR); 1315 this.expect(types.bracketR); 1316 1317 if (this.isRelational("<") || this.match(types.parenL)) { 1318 node.method = true; 1319 node.optional = false; 1320 node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); 1321 } else { 1322 node.method = false; 1323 1324 if (this.eat(types.question)) { 1325 node.optional = true; 1326 } 1327 1328 node.value = this.flowParseTypeInitialiser(); 1329 } 1330 1331 return this.finishNode(node, "ObjectTypeInternalSlot"); 1332 } 1333 1334 flowParseObjectTypeMethodish(node) { 1335 node.params = []; 1336 node.rest = null; 1337 node.typeParameters = null; 1338 1339 if (this.isRelational("<")) { 1340 node.typeParameters = this.flowParseTypeParameterDeclaration(); 1341 } 1342 1343 this.expect(types.parenL); 1344 1345 while (!this.match(types.parenR) && !this.match(types.ellipsis)) { 1346 node.params.push(this.flowParseFunctionTypeParam()); 1347 1348 if (!this.match(types.parenR)) { 1349 this.expect(types.comma); 1350 } 1351 } 1352 1353 if (this.eat(types.ellipsis)) { 1354 node.rest = this.flowParseFunctionTypeParam(); 1355 } 1356 1357 this.expect(types.parenR); 1358 node.returnType = this.flowParseTypeInitialiser(); 1359 return this.finishNode(node, "FunctionTypeAnnotation"); 1360 } 1361 1362 flowParseObjectTypeCallProperty(node, isStatic) { 1363 const valueNode = this.startNode(); 1364 node.static = isStatic; 1365 node.value = this.flowParseObjectTypeMethodish(valueNode); 1366 return this.finishNode(node, "ObjectTypeCallProperty"); 1367 } 1368 1369 flowParseObjectType({ 1370 allowStatic, 1371 allowExact, 1372 allowSpread, 1373 allowProto, 1374 allowInexact 1375 }) { 1376 const oldInType = this.state.inType; 1377 this.state.inType = true; 1378 const nodeStart = this.startNode(); 1379 nodeStart.callProperties = []; 1380 nodeStart.properties = []; 1381 nodeStart.indexers = []; 1382 nodeStart.internalSlots = []; 1383 let endDelim; 1384 let exact; 1385 let inexact = false; 1386 1387 if (allowExact && this.match(types.braceBarL)) { 1388 this.expect(types.braceBarL); 1389 endDelim = types.braceBarR; 1390 exact = true; 1391 } else { 1392 this.expect(types.braceL); 1393 endDelim = types.braceR; 1394 exact = false; 1395 } 1396 1397 nodeStart.exact = exact; 1398 1399 while (!this.match(endDelim)) { 1400 let isStatic = false; 1401 let protoStart = null; 1402 const node = this.startNode(); 1403 1404 if (allowProto && this.isContextual("proto")) { 1405 const lookahead = this.lookahead(); 1406 1407 if (lookahead.type !== types.colon && lookahead.type !== types.question) { 1408 this.next(); 1409 protoStart = this.state.start; 1410 allowStatic = false; 1411 } 1412 } 1413 1414 if (allowStatic && this.isContextual("static")) { 1415 const lookahead = this.lookahead(); 1416 1417 if (lookahead.type !== types.colon && lookahead.type !== types.question) { 1418 this.next(); 1419 isStatic = true; 1420 } 1421 } 1422 1423 const variance = this.flowParseVariance(); 1424 1425 if (this.eat(types.bracketL)) { 1426 if (protoStart != null) { 1427 this.unexpected(protoStart); 1428 } 1429 1430 if (this.eat(types.bracketL)) { 1431 if (variance) { 1432 this.unexpected(variance.start); 1433 } 1434 1435 nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic)); 1436 } else { 1437 nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); 1438 } 1439 } else if (this.match(types.parenL) || this.isRelational("<")) { 1440 if (protoStart != null) { 1441 this.unexpected(protoStart); 1442 } 1443 1444 if (variance) { 1445 this.unexpected(variance.start); 1446 } 1447 1448 nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); 1449 } else { 1450 let kind = "init"; 1451 1452 if (this.isContextual("get") || this.isContextual("set")) { 1453 const lookahead = this.lookahead(); 1454 1455 if (lookahead.type === types.name || lookahead.type === types.string || lookahead.type === types.num) { 1456 kind = this.state.value; 1457 this.next(); 1458 } 1459 } 1460 1461 const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact); 1462 1463 if (propOrInexact === null) { 1464 inexact = true; 1465 } else { 1466 nodeStart.properties.push(propOrInexact); 1467 } 1468 } 1469 1470 this.flowObjectTypeSemicolon(); 1471 } 1472 1473 this.expect(endDelim); 1474 1475 if (allowSpread) { 1476 nodeStart.inexact = inexact; 1477 } 1478 1479 const out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); 1480 this.state.inType = oldInType; 1481 return out; 1482 } 1483 1484 flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) { 1485 if (this.match(types.ellipsis)) { 1486 if (!allowSpread) { 1487 this.unexpected(null, "Spread operator cannot appear in class or interface definitions"); 1488 } 1489 1490 if (protoStart != null) { 1491 this.unexpected(protoStart); 1492 } 1493 1494 if (variance) { 1495 this.unexpected(variance.start, "Spread properties cannot have variance"); 1496 } 1497 1498 this.expect(types.ellipsis); 1499 const isInexactToken = this.eat(types.comma) || this.eat(types.semi); 1500 1501 if (this.match(types.braceR)) { 1502 if (allowInexact) return null; 1503 this.unexpected(null, "Explicit inexact syntax is only allowed inside inexact objects"); 1504 } 1505 1506 if (this.match(types.braceBarR)) { 1507 this.unexpected(null, "Explicit inexact syntax cannot appear inside an explicit exact object type"); 1508 } 1509 1510 if (isInexactToken) { 1511 this.unexpected(null, "Explicit inexact syntax must appear at the end of an inexact object"); 1512 } 1513 1514 node.argument = this.flowParseType(); 1515 return this.finishNode(node, "ObjectTypeSpreadProperty"); 1516 } else { 1517 node.key = this.flowParseObjectPropertyKey(); 1518 node.static = isStatic; 1519 node.proto = protoStart != null; 1520 node.kind = kind; 1521 let optional = false; 1522 1523 if (this.isRelational("<") || this.match(types.parenL)) { 1524 node.method = true; 1525 1526 if (protoStart != null) { 1527 this.unexpected(protoStart); 1528 } 1529 1530 if (variance) { 1531 this.unexpected(variance.start); 1532 } 1533 1534 node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); 1535 1536 if (kind === "get" || kind === "set") { 1537 this.flowCheckGetterSetterParams(node); 1538 } 1539 } else { 1540 if (kind !== "init") this.unexpected(); 1541 node.method = false; 1542 1543 if (this.eat(types.question)) { 1544 optional = true; 1545 } 1546 1547 node.value = this.flowParseTypeInitialiser(); 1548 node.variance = variance; 1549 } 1550 1551 node.optional = optional; 1552 return this.finishNode(node, "ObjectTypeProperty"); 1553 } 1554 } 1555 1556 flowCheckGetterSetterParams(property) { 1557 const paramCount = property.kind === "get" ? 0 : 1; 1558 const start = property.start; 1559 const length = property.value.params.length + (property.value.rest ? 1 : 0); 1560 1561 if (length !== paramCount) { 1562 if (property.kind === "get") { 1563 this.raise(start, "getter must not have any formal parameters"); 1564 } else { 1565 this.raise(start, "setter must have exactly one formal parameter"); 1566 } 1567 } 1568 1569 if (property.kind === "set" && property.value.rest) { 1570 this.raise(start, "setter function argument must not be a rest parameter"); 1571 } 1572 } 1573 1574 flowObjectTypeSemicolon() { 1575 if (!this.eat(types.semi) && !this.eat(types.comma) && !this.match(types.braceR) && !this.match(types.braceBarR)) { 1576 this.unexpected(); 1577 } 1578 } 1579 1580 flowParseQualifiedTypeIdentifier(startPos, startLoc, id) { 1581 startPos = startPos || this.state.start; 1582 startLoc = startLoc || this.state.startLoc; 1583 let node = id || this.parseIdentifier(); 1584 1585 while (this.eat(types.dot)) { 1586 const node2 = this.startNodeAt(startPos, startLoc); 1587 node2.qualification = node; 1588 node2.id = this.parseIdentifier(); 1589 node = this.finishNode(node2, "QualifiedTypeIdentifier"); 1590 } 1591 1592 return node; 1593 } 1594 1595 flowParseGenericType(startPos, startLoc, id) { 1596 const node = this.startNodeAt(startPos, startLoc); 1597 node.typeParameters = null; 1598 node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); 1599 1600 if (this.isRelational("<")) { 1601 node.typeParameters = this.flowParseTypeParameterInstantiation(); 1602 } 1603 1604 return this.finishNode(node, "GenericTypeAnnotation"); 1605 } 1606 1607 flowParseTypeofType() { 1608 const node = this.startNode(); 1609 this.expect(types._typeof); 1610 node.argument = this.flowParsePrimaryType(); 1611 return this.finishNode(node, "TypeofTypeAnnotation"); 1612 } 1613 1614 flowParseTupleType() { 1615 const node = this.startNode(); 1616 node.types = []; 1617 this.expect(types.bracketL); 1618 1619 while (this.state.pos < this.length && !this.match(types.bracketR)) { 1620 node.types.push(this.flowParseType()); 1621 if (this.match(types.bracketR)) break; 1622 this.expect(types.comma); 1623 } 1624 1625 this.expect(types.bracketR); 1626 return this.finishNode(node, "TupleTypeAnnotation"); 1627 } 1628 1629 flowParseFunctionTypeParam() { 1630 let name = null; 1631 let optional = false; 1632 let typeAnnotation = null; 1633 const node = this.startNode(); 1634 const lh = this.lookahead(); 1635 1636 if (lh.type === types.colon || lh.type === types.question) { 1637 name = this.parseIdentifier(); 1638 1639 if (this.eat(types.question)) { 1640 optional = true; 1641 } 1642 1643 typeAnnotation = this.flowParseTypeInitialiser(); 1644 } else { 1645 typeAnnotation = this.flowParseType(); 1646 } 1647 1648 node.name = name; 1649 node.optional = optional; 1650 node.typeAnnotation = typeAnnotation; 1651 return this.finishNode(node, "FunctionTypeParam"); 1652 } 1653 1654 reinterpretTypeAsFunctionTypeParam(type) { 1655 const node = this.startNodeAt(type.start, type.loc.start); 1656 node.name = null; 1657 node.optional = false; 1658 node.typeAnnotation = type; 1659 return this.finishNode(node, "FunctionTypeParam"); 1660 } 1661 1662 flowParseFunctionTypeParams(params = []) { 1663 let rest = null; 1664 1665 while (!this.match(types.parenR) && !this.match(types.ellipsis)) { 1666 params.push(this.flowParseFunctionTypeParam()); 1667 1668 if (!this.match(types.parenR)) { 1669 this.expect(types.comma); 1670 } 1671 } 1672 1673 if (this.eat(types.ellipsis)) { 1674 rest = this.flowParseFunctionTypeParam(); 1675 } 1676 1677 return { 1678 params, 1679 rest 1680 }; 1681 } 1682 1683 flowIdentToTypeAnnotation(startPos, startLoc, node, id) { 1684 switch (id.name) { 1685 case "any": 1686 return this.finishNode(node, "AnyTypeAnnotation"); 1687 1688 case "bool": 1689 case "boolean": 1690 return this.finishNode(node, "BooleanTypeAnnotation"); 1691 1692 case "mixed": 1693 return this.finishNode(node, "MixedTypeAnnotation"); 1694 1695 case "empty": 1696 return this.finishNode(node, "EmptyTypeAnnotation"); 1697 1698 case "number": 1699 return this.finishNode(node, "NumberTypeAnnotation"); 1700 1701 case "string": 1702 return this.finishNode(node, "StringTypeAnnotation"); 1703 1704 default: 1705 this.checkNotUnderscore(id.name); 1706 return this.flowParseGenericType(startPos, startLoc, id); 1707 } 1708 } 1709 1710 flowParsePrimaryType() { 1711 const startPos = this.state.start; 1712 const startLoc = this.state.startLoc; 1713 const node = this.startNode(); 1714 let tmp; 1715 let type; 1716 let isGroupedType = false; 1717 const oldNoAnonFunctionType = this.state.noAnonFunctionType; 1718 1719 switch (this.state.type) { 1720 case types.name: 1721 if (this.isContextual("interface")) { 1722 return this.flowParseInterfaceType(); 1723 } 1724 1725 return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); 1726 1727 case types.braceL: 1728 return this.flowParseObjectType({ 1729 allowStatic: false, 1730 allowExact: false, 1731 allowSpread: true, 1732 allowProto: false, 1733 allowInexact: true 1734 }); 1735 1736 case types.braceBarL: 1737 return this.flowParseObjectType({ 1738 allowStatic: false, 1739 allowExact: true, 1740 allowSpread: true, 1741 allowProto: false, 1742 allowInexact: false 1743 }); 1744 1745 case types.bracketL: 1746 this.state.noAnonFunctionType = false; 1747 type = this.flowParseTupleType(); 1748 this.state.noAnonFunctionType = oldNoAnonFunctionType; 1749 return type; 1750 1751 case types.relational: 1752 if (this.state.value === "<") { 1753 node.typeParameters = this.flowParseTypeParameterDeclaration(); 1754 this.expect(types.parenL); 1755 tmp = this.flowParseFunctionTypeParams(); 1756 node.params = tmp.params; 1757 node.rest = tmp.rest; 1758 this.expect(types.parenR); 1759 this.expect(types.arrow); 1760 node.returnType = this.flowParseType(); 1761 return this.finishNode(node, "FunctionTypeAnnotation"); 1762 } 1763 1764 break; 1765 1766 case types.parenL: 1767 this.next(); 1768 1769 if (!this.match(types.parenR) && !this.match(types.ellipsis)) { 1770 if (this.match(types.name)) { 1771 const token = this.lookahead().type; 1772 isGroupedType = token !== types.question && token !== types.colon; 1773 } else { 1774 isGroupedType = true; 1775 } 1776 } 1777 1778 if (isGroupedType) { 1779 this.state.noAnonFunctionType = false; 1780 type = this.flowParseType(); 1781 this.state.noAnonFunctionType = oldNoAnonFunctionType; 1782 1783 if (this.state.noAnonFunctionType || !(this.match(types.comma) || this.match(types.parenR) && this.lookahead().type === types.arrow)) { 1784 this.expect(types.parenR); 1785 return type; 1786 } else { 1787 this.eat(types.comma); 1788 } 1789 } 1790 1791 if (type) { 1792 tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]); 1793 } else { 1794 tmp = this.flowParseFunctionTypeParams(); 1795 } 1796 1797 node.params = tmp.params; 1798 node.rest = tmp.rest; 1799 this.expect(types.parenR); 1800 this.expect(types.arrow); 1801 node.returnType = this.flowParseType(); 1802 node.typeParameters = null; 1803 return this.finishNode(node, "FunctionTypeAnnotation"); 1804 1805 case types.string: 1806 return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); 1807 1808 case types._true: 1809 case types._false: 1810 node.value = this.match(types._true); 1811 this.next(); 1812 return this.finishNode(node, "BooleanLiteralTypeAnnotation"); 1813 1814 case types.plusMin: 1815 if (this.state.value === "-") { 1816 this.next(); 1817 1818 if (this.match(types.num)) { 1819 return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start); 1820 } 1821 1822 if (this.match(types.bigint)) { 1823 return this.parseLiteral(-this.state.value, "BigIntLiteralTypeAnnotation", node.start, node.loc.start); 1824 } 1825 1826 this.unexpected(null, `Unexpected token, expected "number" or "bigint"`); 1827 } 1828 1829 this.unexpected(); 1830 1831 case types.num: 1832 return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); 1833 1834 case types.bigint: 1835 return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation"); 1836 1837 case types._void: 1838 this.next(); 1839 return this.finishNode(node, "VoidTypeAnnotation"); 1840 1841 case types._null: 1842 this.next(); 1843 return this.finishNode(node, "NullLiteralTypeAnnotation"); 1844 1845 case types._this: 1846 this.next(); 1847 return this.finishNode(node, "ThisTypeAnnotation"); 1848 1849 case types.star: 1850 this.next(); 1851 return this.finishNode(node, "ExistsTypeAnnotation"); 1852 1853 default: 1854 if (this.state.type.keyword === "typeof") { 1855 return this.flowParseTypeofType(); 1856 } else if (this.state.type.keyword) { 1857 const label = this.state.type.label; 1858 this.next(); 1859 return super.createIdentifier(node, label); 1860 } 1861 1862 } 1863 1864 throw this.unexpected(); 1865 } 1866 1867 flowParsePostfixType() { 1868 const startPos = this.state.start, 1869 startLoc = this.state.startLoc; 1870 let type = this.flowParsePrimaryType(); 1871 1872 while (this.match(types.bracketL) && !this.canInsertSemicolon()) { 1873 const node = this.startNodeAt(startPos, startLoc); 1874 node.elementType = type; 1875 this.expect(types.bracketL); 1876 this.expect(types.bracketR); 1877 type = this.finishNode(node, "ArrayTypeAnnotation"); 1878 } 1879 1880 return type; 1881 } 1882 1883 flowParsePrefixType() { 1884 const node = this.startNode(); 1885 1886 if (this.eat(types.question)) { 1887 node.typeAnnotation = this.flowParsePrefixType(); 1888 return this.finishNode(node, "NullableTypeAnnotation"); 1889 } else { 1890 return this.flowParsePostfixType(); 1891 } 1892 } 1893 1894 flowParseAnonFunctionWithoutParens() { 1895 const param = this.flowParsePrefixType(); 1896 1897 if (!this.state.noAnonFunctionType && this.eat(types.arrow)) { 1898 const node = this.startNodeAt(param.start, param.loc.start); 1899 node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; 1900 node.rest = null; 1901 node.returnType = this.flowParseType(); 1902 node.typeParameters = null; 1903 return this.finishNode(node, "FunctionTypeAnnotation"); 1904 } 1905 1906 return param; 1907 } 1908 1909 flowParseIntersectionType() { 1910 const node = this.startNode(); 1911 this.eat(types.bitwiseAND); 1912 const type = this.flowParseAnonFunctionWithoutParens(); 1913 node.types = [type]; 1914 1915 while (this.eat(types.bitwiseAND)) { 1916 node.types.push(this.flowParseAnonFunctionWithoutParens()); 1917 } 1918 1919 return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); 1920 } 1921 1922 flowParseUnionType() { 1923 const node = this.startNode(); 1924 this.eat(types.bitwiseOR); 1925 const type = this.flowParseIntersectionType(); 1926 node.types = [type]; 1927 1928 while (this.eat(types.bitwiseOR)) { 1929 node.types.push(this.flowParseIntersectionType()); 1930 } 1931 1932 return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); 1933 } 1934 1935 flowParseType() { 1936 const oldInType = this.state.inType; 1937 this.state.inType = true; 1938 const type = this.flowParseUnionType(); 1939 this.state.inType = oldInType; 1940 this.state.exprAllowed = this.state.exprAllowed || this.state.noAnonFunctionType; 1941 return type; 1942 } 1943 1944 flowParseTypeOrImplicitInstantiation() { 1945 if (this.state.type === types.name && this.state.value === "_") { 1946 const startPos = this.state.start; 1947 const startLoc = this.state.startLoc; 1948 const node = this.parseIdentifier(); 1949 return this.flowParseGenericType(startPos, startLoc, node); 1950 } else { 1951 return this.flowParseType(); 1952 } 1953 } 1954 1955 flowParseTypeAnnotation() { 1956 const node = this.startNode(); 1957 node.typeAnnotation = this.flowParseTypeInitialiser(); 1958 return this.finishNode(node, "TypeAnnotation"); 1959 } 1960 1961 flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) { 1962 const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier(); 1963 1964 if (this.match(types.colon)) { 1965 ident.typeAnnotation = this.flowParseTypeAnnotation(); 1966 this.resetEndLocation(ident); 1967 } 1968 1969 return ident; 1970 } 1971 1972 typeCastToParameter(node) { 1973 node.expression.typeAnnotation = node.typeAnnotation; 1974 this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); 1975 return node.expression; 1976 } 1977 1978 flowParseVariance() { 1979 let variance = null; 1980 1981 if (this.match(types.plusMin)) { 1982 variance = this.startNode(); 1983 1984 if (this.state.value === "+") { 1985 variance.kind = "plus"; 1986 } else { 1987 variance.kind = "minus"; 1988 } 1989 1990 this.next(); 1991 this.finishNode(variance, "Variance"); 1992 } 1993 1994 return variance; 1995 } 1996 1997 parseFunctionBody(node, allowExpressionBody, isMethod = false) { 1998 if (allowExpressionBody) { 1999 return this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod)); 2000 } 2001 2002 return super.parseFunctionBody(node, false, isMethod); 2003 } 2004 2005 parseFunctionBodyAndFinish(node, type, isMethod = false) { 2006 if (this.match(types.colon)) { 2007 const typeNode = this.startNode(); 2008 [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); 2009 node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null; 2010 } 2011 2012 super.parseFunctionBodyAndFinish(node, type, isMethod); 2013 } 2014 2015 parseStatement(context, topLevel) { 2016 if (this.state.strict && this.match(types.name) && this.state.value === "interface") { 2017 const node = this.startNode(); 2018 this.next(); 2019 return this.flowParseInterface(node); 2020 } else { 2021 const stmt = super.parseStatement(context, topLevel); 2022 2023 if (this.flowPragma === undefined && !this.isValidDirective(stmt)) { 2024 this.flowPragma = null; 2025 } 2026 2027 return stmt; 2028 } 2029 } 2030 2031 parseExpressionStatement(node, expr) { 2032 if (expr.type === "Identifier") { 2033 if (expr.name === "declare") { 2034 if (this.match(types._class) || this.match(types.name) || this.match(types._function) || this.match(types._var) || this.match(types._export)) { 2035 return this.flowParseDeclare(node); 2036 } 2037 } else if (this.match(types.name)) { 2038 if (expr.name === "interface") { 2039 return this.flowParseInterface(node); 2040 } else if (expr.name === "type") { 2041 return this.flowParseTypeAlias(node); 2042 } else if (expr.name === "opaque") { 2043 return this.flowParseOpaqueType(node, false); 2044 } 2045 } 2046 } 2047 2048 return super.parseExpressionStatement(node, expr); 2049 } 2050 2051 shouldParseExportDeclaration() { 2052 return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || super.shouldParseExportDeclaration(); 2053 } 2054 2055 isExportDefaultSpecifier() { 2056 if (this.match(types.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque")) { 2057 return false; 2058 } 2059 2060 return super.isExportDefaultSpecifier(); 2061 } 2062 2063 parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { 2064 if (!this.match(types.question)) return expr; 2065 2066 if (refNeedsArrowPos) { 2067 const state = this.state.clone(); 2068 2069 try { 2070 return super.parseConditional(expr, noIn, startPos, startLoc); 2071 } catch (err) { 2072 if (err instanceof SyntaxError) { 2073 this.state = state; 2074 refNeedsArrowPos.start = err.pos || this.state.start; 2075 return expr; 2076 } else { 2077 throw err; 2078 } 2079 } 2080 } 2081 2082 this.expect(types.question); 2083 const state = this.state.clone(); 2084 const originalNoArrowAt = this.state.noArrowAt; 2085 const node = this.startNodeAt(startPos, startLoc); 2086 let { 2087 consequent, 2088 failed 2089 } = this.tryParseConditionalConsequent(); 2090 let [valid, invalid] = this.getArrowLikeExpressions(consequent); 2091 2092 if (failed || invalid.length > 0) { 2093 const noArrowAt = [...originalNoArrowAt]; 2094 2095 if (invalid.length > 0) { 2096 this.state = state; 2097 this.state.noArrowAt = noArrowAt; 2098 2099 for (let i = 0; i < invalid.length; i++) { 2100 noArrowAt.push(invalid[i].start); 2101 } 2102 2103 ({ 2104 consequent, 2105 failed 2106 } = this.tryParseConditionalConsequent()); 2107 [valid, invalid] = this.getArrowLikeExpressions(consequent); 2108 } 2109 2110 if (failed && valid.length > 1) { 2111 this.raise(state.start, "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate."); 2112 } 2113 2114 if (failed && valid.length === 1) { 2115 this.state = state; 2116 this.state.noArrowAt = noArrowAt.concat(valid[0].start); 2117 ({ 2118 consequent, 2119 failed 2120 } = this.tryParseConditionalConsequent()); 2121 } 2122 2123 this.getArrowLikeExpressions(consequent, true); 2124 } 2125 2126 this.state.noArrowAt = originalNoArrowAt; 2127 this.expect(types.colon); 2128 node.test = expr; 2129 node.consequent = consequent; 2130 node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(noIn, undefined, undefined, undefined)); 2131 return this.finishNode(node, "ConditionalExpression"); 2132 } 2133 2134 tryParseConditionalConsequent() { 2135 this.state.noArrowParamsConversionAt.push(this.state.start); 2136 const consequent = this.parseMaybeAssign(); 2137 const failed = !this.match(types.colon); 2138 this.state.noArrowParamsConversionAt.pop(); 2139 return { 2140 consequent, 2141 failed 2142 }; 2143 } 2144 2145 getArrowLikeExpressions(node, disallowInvalid) { 2146 const stack = [node]; 2147 const arrows = []; 2148 2149 while (stack.length !== 0) { 2150 const node = stack.pop(); 2151 2152 if (node.type === "ArrowFunctionExpression") { 2153 if (node.typeParameters || !node.returnType) { 2154 this.toAssignableList(node.params, true, "arrow function parameters"); 2155 this.scope.enter(functionFlags(false, false) | SCOPE_ARROW); 2156 super.checkParams(node, false, true); 2157 this.scope.exit(); 2158 } else { 2159 arrows.push(node); 2160 } 2161 2162 stack.push(node.body); 2163 } else if (node.type === "ConditionalExpression") { 2164 stack.push(node.consequent); 2165 stack.push(node.alternate); 2166 } 2167 } 2168 2169 if (disallowInvalid) { 2170 for (let i = 0; i < arrows.length; i++) { 2171 this.toAssignableList(node.params, true, "arrow function parameters"); 2172 } 2173 2174 return [arrows, []]; 2175 } 2176 2177 return partition(arrows, node => { 2178 try { 2179 this.toAssignableList(node.params, true, "arrow function parameters"); 2180 return true; 2181 } catch (err) { 2182 return false; 2183 } 2184 }); 2185 } 2186 2187 forwardNoArrowParamsConversionAt(node, parse) { 2188 let result; 2189 2190 if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { 2191 this.state.noArrowParamsConversionAt.push(this.state.start); 2192 result = parse(); 2193 this.state.noArrowParamsConversionAt.pop(); 2194 } else { 2195 result = parse(); 2196 } 2197 2198 return result; 2199 } 2200 2201 parseParenItem(node, startPos, startLoc) { 2202 node = super.parseParenItem(node, startPos, startLoc); 2203 2204 if (this.eat(types.question)) { 2205 node.optional = true; 2206 this.resetEndLocation(node); 2207 } 2208 2209 if (this.match(types.colon)) { 2210 const typeCastNode = this.startNodeAt(startPos, startLoc); 2211 typeCastNode.expression = node; 2212 typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); 2213 return this.finishNode(typeCastNode, "TypeCastExpression"); 2214 } 2215 2216 return node; 2217 } 2218 2219 assertModuleNodeAllowed(node) { 2220 if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") { 2221 return; 2222 } 2223 2224 super.assertModuleNodeAllowed(node); 2225 } 2226 2227 parseExport(node) { 2228 const decl = super.parseExport(node); 2229 2230 if (decl.type === "ExportNamedDeclaration" || decl.type === "ExportAllDeclaration") { 2231 decl.exportKind = decl.exportKind || "value"; 2232 } 2233 2234 return decl; 2235 } 2236 2237 parseExportDeclaration(node) { 2238 if (this.isContextual("type")) { 2239 node.exportKind = "type"; 2240 const declarationNode = this.startNode(); 2241 this.next(); 2242 2243 if (this.match(types.braceL)) { 2244 node.specifiers = this.parseExportSpecifiers(); 2245 this.parseExportFrom(node); 2246 return null; 2247 } else { 2248 return this.flowParseTypeAlias(declarationNode); 2249 } 2250 } else if (this.isContextual("opaque")) { 2251 node.exportKind = "type"; 2252 const declarationNode = this.startNode(); 2253 this.next(); 2254 return this.flowParseOpaqueType(declarationNode, false); 2255 } else if (this.isContextual("interface")) { 2256 node.exportKind = "type"; 2257 const declarationNode = this.startNode(); 2258 this.next(); 2259 return this.flowParseInterface(declarationNode); 2260 } else { 2261 return super.parseExportDeclaration(node); 2262 } 2263 } 2264 2265 eatExportStar(node) { 2266 if (super.eatExportStar(...arguments)) return true; 2267 2268 if (this.isContextual("type") && this.lookahead().type === types.star) { 2269 node.exportKind = "type"; 2270 this.next(); 2271 this.next(); 2272 return true; 2273 } 2274 2275 return false; 2276 } 2277 2278 maybeParseExportNamespaceSpecifier(node) { 2279 const pos = this.state.start; 2280 const hasNamespace = super.maybeParseExportNamespaceSpecifier(node); 2281 2282 if (hasNamespace && node.exportKind === "type") { 2283 this.unexpected(pos); 2284 } 2285 2286 return hasNamespace; 2287 } 2288 2289 parseClassId(node, isStatement, optionalId) { 2290 super.parseClassId(node, isStatement, optionalId); 2291 2292 if (this.isRelational("<")) { 2293 node.typeParameters = this.flowParseTypeParameterDeclaration(); 2294 } 2295 } 2296 2297 getTokenFromCode(code) { 2298 const next = this.input.charCodeAt(this.state.pos + 1); 2299 2300 if (code === 123 && next === 124) { 2301 return this.finishOp(types.braceBarL, 2); 2302 } else if (this.state.inType && (code === 62 || code === 60)) { 2303 return this.finishOp(types.relational, 1); 2304 } else if (isIteratorStart(code, next)) { 2305 this.state.isIterator = true; 2306 return super.readWord(); 2307 } else { 2308 return super.getTokenFromCode(code); 2309 } 2310 } 2311 2312 toAssignable(node, isBinding, contextDescription) { 2313 if (node.type === "TypeCastExpression") { 2314 return super.toAssignable(this.typeCastToParameter(node), isBinding, contextDescription); 2315 } else { 2316 return super.toAssignable(node, isBinding, contextDescription); 2317 } 2318 } 2319 2320 toAssignableList(exprList, isBinding, contextDescription) { 2321 for (let i = 0; i < exprList.length; i++) { 2322 const expr = exprList[i]; 2323 2324 if (expr && expr.type === "TypeCastExpression") { 2325 exprList[i] = this.typeCastToParameter(expr); 2326 } 2327 } 2328 2329 return super.toAssignableList(exprList, isBinding, contextDescription); 2330 } 2331 2332 toReferencedList(exprList, isParenthesizedExpr) { 2333 for (let i = 0; i < exprList.length; i++) { 2334 const expr = exprList[i]; 2335 2336 if (expr && expr.type === "TypeCastExpression" && (!expr.extra || !expr.extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) { 2337 this.raise(expr.typeAnnotation.start, "The type cast expression is expected to be wrapped with parenthesis"); 2338 } 2339 } 2340 2341 return exprList; 2342 } 2343 2344 checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) { 2345 if (expr.type !== "TypeCastExpression") { 2346 return super.checkLVal(expr, bindingType, checkClashes, contextDescription); 2347 } 2348 } 2349 2350 parseClassProperty(node) { 2351 if (this.match(types.colon)) { 2352 node.typeAnnotation = this.flowParseTypeAnnotation(); 2353 } 2354 2355 return super.parseClassProperty(node); 2356 } 2357 2358 parseClassPrivateProperty(node) { 2359 if (this.match(types.colon)) { 2360 node.typeAnnotation = this.flowParseTypeAnnotation(); 2361 } 2362 2363 return super.parseClassPrivateProperty(node); 2364 } 2365 2366 isClassMethod() { 2367 return this.isRelational("<") || super.isClassMethod(); 2368 } 2369 2370 isClassProperty() { 2371 return this.match(types.colon) || super.isClassProperty(); 2372 } 2373 2374 isNonstaticConstructor(method) { 2375 return !this.match(types.colon) && super.isNonstaticConstructor(method); 2376 } 2377 2378 pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { 2379 if (method.variance) { 2380 this.unexpected(method.variance.start); 2381 } 2382 2383 delete method.variance; 2384 2385 if (this.isRelational("<")) { 2386 method.typeParameters = this.flowParseTypeParameterDeclaration(); 2387 } 2388 2389 super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); 2390 } 2391 2392 pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { 2393 if (method.variance) { 2394 this.unexpected(method.variance.start); 2395 } 2396 2397 delete method.variance; 2398 2399 if (this.isRelational("<")) { 2400 method.typeParameters = this.flowParseTypeParameterDeclaration(); 2401 } 2402 2403 super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); 2404 } 2405 2406 parseClassSuper(node) { 2407 super.parseClassSuper(node); 2408 2409 if (node.superClass && this.isRelational("<")) { 2410 node.superTypeParameters = this.flowParseTypeParameterInstantiation(); 2411 } 2412 2413 if (this.isContextual("implements")) { 2414 this.next(); 2415 const implemented = node.implements = []; 2416 2417 do { 2418 const node = this.startNode(); 2419 node.id = this.flowParseRestrictedIdentifier(true); 2420 2421 if (this.isRelational("<")) { 2422 node.typeParameters = this.flowParseTypeParameterInstantiation(); 2423 } else { 2424 node.typeParameters = null; 2425 } 2426 2427 implemented.push(this.finishNode(node, "ClassImplements")); 2428 } while (this.eat(types.comma)); 2429 } 2430 } 2431 2432 parsePropertyName(node) { 2433 const variance = this.flowParseVariance(); 2434 const key = super.parsePropertyName(node); 2435 node.variance = variance; 2436 return key; 2437 } 2438 2439 parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos, containsEsc) { 2440 if (prop.variance) { 2441 this.unexpected(prop.variance.start); 2442 } 2443 2444 delete prop.variance; 2445 let typeParameters; 2446 2447 if (this.isRelational("<")) { 2448 typeParameters = this.flowParseTypeParameterDeclaration(); 2449 if (!this.match(types.parenL)) this.unexpected(); 2450 } 2451 2452 super.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos, containsEsc); 2453 2454 if (typeParameters) { 2455 (prop.value || prop).typeParameters = typeParameters; 2456 } 2457 } 2458 2459 parseAssignableListItemTypes(param) { 2460 if (this.eat(types.question)) { 2461 if (param.type !== "Identifier") { 2462 throw this.raise(param.start, "A binding pattern parameter cannot be optional in an implementation signature."); 2463 } 2464 2465 param.optional = true; 2466 } 2467 2468 if (this.match(types.colon)) { 2469 param.typeAnnotation = this.flowParseTypeAnnotation(); 2470 } 2471 2472 this.resetEndLocation(param); 2473 return param; 2474 } 2475 2476 parseMaybeDefault(startPos, startLoc, left) { 2477 const node = super.parseMaybeDefault(startPos, startLoc, left); 2478 2479 if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { 2480 this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, " + "e.g. instead of `age = 25: number` use `age: number = 25`"); 2481 } 2482 2483 return node; 2484 } 2485 2486 shouldParseDefaultImport(node) { 2487 if (!hasTypeImportKind(node)) { 2488 return super.shouldParseDefaultImport(node); 2489 } 2490 2491 return isMaybeDefaultImport(this.state); 2492 } 2493 2494 parseImportSpecifierLocal(node, specifier, type, contextDescription) { 2495 specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true) : this.parseIdentifier(); 2496 this.checkLVal(specifier.local, BIND_LEXICAL, undefined, contextDescription); 2497 node.specifiers.push(this.finishNode(specifier, type)); 2498 } 2499 2500 maybeParseDefaultImportSpecifier(node) { 2501 node.importKind = "value"; 2502 let kind = null; 2503 2504 if (this.match(types._typeof)) { 2505 kind = "typeof"; 2506 } else if (this.isContextual("type")) { 2507 kind = "type"; 2508 } 2509 2510 if (kind) { 2511 const lh = this.lookahead(); 2512 2513 if (kind === "type" && lh.type === types.star) { 2514 this.unexpected(lh.start); 2515 } 2516 2517 if (isMaybeDefaultImport(lh) || lh.type === types.braceL || lh.type === types.star) { 2518 this.next(); 2519 node.importKind = kind; 2520 } 2521 } 2522 2523 return super.maybeParseDefaultImportSpecifier(node); 2524 } 2525 2526 parseImportSpecifier(node) { 2527 const specifier = this.startNode(); 2528 const firstIdentLoc = this.state.start; 2529 const firstIdent = this.parseIdentifier(true); 2530 let specifierTypeKind = null; 2531 2532 if (firstIdent.name === "type") { 2533 specifierTypeKind = "type"; 2534 } else if (firstIdent.name === "typeof") { 2535 specifierTypeKind = "typeof"; 2536 } 2537 2538 let isBinding = false; 2539 2540 if (this.isContextual("as") && !this.isLookaheadContextual("as")) { 2541 const as_ident = this.parseIdentifier(true); 2542 2543 if (specifierTypeKind !== null && !this.match(types.name) && !this.state.type.keyword) { 2544 specifier.imported = as_ident; 2545 specifier.importKind = specifierTypeKind; 2546 specifier.local = as_ident.__clone(); 2547 } else { 2548 specifier.imported = firstIdent; 2549 specifier.importKind = null; 2550 specifier.local = this.parseIdentifier(); 2551 } 2552 } else if (specifierTypeKind !== null && (this.match(types.name) || this.state.type.keyword)) { 2553 specifier.imported = this.parseIdentifier(true); 2554 specifier.importKind = specifierTypeKind; 2555 2556 if (this.eatContextual("as")) { 2557 specifier.local = this.parseIdentifier(); 2558 } else { 2559 isBinding = true; 2560 specifier.local = specifier.imported.__clone(); 2561 } 2562 } else { 2563 isBinding = true; 2564 specifier.imported = firstIdent; 2565 specifier.importKind = null; 2566 specifier.local = specifier.imported.__clone(); 2567 } 2568 2569 const nodeIsTypeImport = hasTypeImportKind(node); 2570 const specifierIsTypeImport = hasTypeImportKind(specifier); 2571 2572 if (nodeIsTypeImport && specifierIsTypeImport) { 2573 this.raise(firstIdentLoc, "The `type` and `typeof` keywords on named imports can only be used on regular " + "`import` statements. It cannot be used with `import type` or `import typeof` statements"); 2574 } 2575 2576 if (nodeIsTypeImport || specifierIsTypeImport) { 2577 this.checkReservedType(specifier.local.name, specifier.local.start); 2578 } 2579 2580 if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) { 2581 this.checkReservedWord(specifier.local.name, specifier.start, true, true); 2582 } 2583 2584 this.checkLVal(specifier.local, BIND_LEXICAL, undefined, "import specifier"); 2585 node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); 2586 } 2587 2588 parseFunctionParams(node, allowModifiers) { 2589 const kind = node.kind; 2590 2591 if (kind !== "get" && kind !== "set" && this.isRelational("<")) { 2592 node.typeParameters = this.flowParseTypeParameterDeclaration(); 2593 } 2594 2595 super.parseFunctionParams(node, allowModifiers); 2596 } 2597 2598 parseVarId(decl, kind) { 2599 super.parseVarId(decl, kind); 2600 2601 if (this.match(types.colon)) { 2602 decl.id.typeAnnotation = this.flowParseTypeAnnotation(); 2603 this.resetEndLocation(decl.id); 2604 } 2605 } 2606 2607 parseAsyncArrowFromCallExpression(node, call) { 2608 if (this.match(types.colon)) { 2609 const oldNoAnonFunctionType = this.state.noAnonFunctionType; 2610 this.state.noAnonFunctionType = true; 2611 node.returnType = this.flowParseTypeAnnotation(); 2612 this.state.noAnonFunctionType = oldNoAnonFunctionType; 2613 } 2614 2615 return super.parseAsyncArrowFromCallExpression(node, call); 2616 } 2617 2618 shouldParseAsyncArrow() { 2619 return this.match(types.colon) || super.shouldParseAsyncArrow(); 2620 } 2621 2622 parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) { 2623 let jsxError = null; 2624 2625 if (this.hasPlugin("jsx") && (this.match(types.jsxTagStart) || this.isRelational("<"))) { 2626 const state = this.state.clone(); 2627 2628 try { 2629 return super.parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos); 2630 } catch (err) { 2631 if (err instanceof SyntaxError) { 2632 this.state = state; 2633 const cLength = this.state.context.length; 2634 2635 if (this.state.context[cLength - 1] === types$1.j_oTag) { 2636 this.state.context.length -= 2; 2637 } 2638 2639 jsxError = err; 2640 } else { 2641 throw err; 2642 } 2643 } 2644 } 2645 2646 if (jsxError != null || this.isRelational("<")) { 2647 let arrowExpression; 2648 let typeParameters; 2649 2650 try { 2651 typeParameters = this.flowParseTypeParameterDeclaration(); 2652 arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => super.parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos)); 2653 arrowExpression.typeParameters = typeParameters; 2654 this.resetStartLocationFromNode(arrowExpression, typeParameters); 2655 } catch (err) { 2656 throw jsxError || err; 2657 } 2658 2659 if (arrowExpression.type === "ArrowFunctionExpression") { 2660 return arrowExpression; 2661 } else if (jsxError != null) { 2662 throw jsxError; 2663 } else { 2664 this.raise(typeParameters.start, "Expected an arrow function after this type parameter declaration"); 2665 } 2666 } 2667 2668 return super.parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos); 2669 } 2670 2671 parseArrow(node) { 2672 if (this.match(types.colon)) { 2673 const state = this.state.clone(); 2674 2675 try { 2676 const oldNoAnonFunctionType = this.state.noAnonFunctionType; 2677 this.state.noAnonFunctionType = true; 2678 const typeNode = this.startNode(); 2679 [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); 2680 this.state.noAnonFunctionType = oldNoAnonFunctionType; 2681 if (this.canInsertSemicolon()) this.unexpected(); 2682 if (!this.match(types.arrow)) this.unexpected(); 2683 node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null; 2684 } catch (err) { 2685 if (err instanceof SyntaxError) { 2686 this.state = state; 2687 } else { 2688 throw err; 2689 } 2690 } 2691 } 2692 2693 return super.parseArrow(node); 2694 } 2695 2696 shouldParseArrow() { 2697 return this.match(types.colon) || super.shouldParseArrow(); 2698 } 2699 2700 setArrowFunctionParameters(node, params) { 2701 if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { 2702 node.params = params; 2703 } else { 2704 super.setArrowFunctionParameters(node, params); 2705 } 2706 } 2707 2708 checkParams(node, allowDuplicates, isArrowFunction) { 2709 if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { 2710 return; 2711 } 2712 2713 return super.checkParams(node, allowDuplicates, isArrowFunction); 2714 } 2715 2716 parseParenAndDistinguishExpression(canBeArrow) { 2717 return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1); 2718 } 2719 2720 parseSubscripts(base, startPos, startLoc, noCalls) { 2721 if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startPos) !== -1) { 2722 this.next(); 2723 const node = this.startNodeAt(startPos, startLoc); 2724 node.callee = base; 2725 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 2726 base = this.finishNode(node, "CallExpression"); 2727 } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) { 2728 const state = this.state.clone(); 2729 let error; 2730 2731 try { 2732 const node = this.parseAsyncArrowWithTypeParameters(startPos, startLoc); 2733 if (node) return node; 2734 } catch (e) { 2735 error = e; 2736 } 2737 2738 this.state = state; 2739 2740 try { 2741 return super.parseSubscripts(base, startPos, startLoc, noCalls); 2742 } catch (e) { 2743 throw error || e; 2744 } 2745 } 2746 2747 return super.parseSubscripts(base, startPos, startLoc, noCalls); 2748 } 2749 2750 parseSubscript(base, startPos, startLoc, noCalls, subscriptState, maybeAsyncArrow) { 2751 if (this.match(types.questionDot) && this.isLookaheadRelational("<")) { 2752 this.expectPlugin("optionalChaining"); 2753 subscriptState.optionalChainMember = true; 2754 2755 if (noCalls) { 2756 subscriptState.stop = true; 2757 return base; 2758 } 2759 2760 this.next(); 2761 const node = this.startNodeAt(startPos, startLoc); 2762 node.callee = base; 2763 node.typeArguments = this.flowParseTypeParameterInstantiation(); 2764 this.expect(types.parenL); 2765 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 2766 node.optional = true; 2767 return this.finishNode(node, "OptionalCallExpression"); 2768 } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) { 2769 const node = this.startNodeAt(startPos, startLoc); 2770 node.callee = base; 2771 const state = this.state.clone(); 2772 2773 try { 2774 node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew(); 2775 this.expect(types.parenL); 2776 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 2777 2778 if (subscriptState.optionalChainMember) { 2779 node.optional = false; 2780 return this.finishNode(node, "OptionalCallExpression"); 2781 } 2782 2783 return this.finishNode(node, "CallExpression"); 2784 } catch (e) { 2785 if (e instanceof SyntaxError) { 2786 this.state = state; 2787 } else { 2788 throw e; 2789 } 2790 } 2791 } 2792 2793 return super.parseSubscript(base, startPos, startLoc, noCalls, subscriptState, maybeAsyncArrow); 2794 } 2795 2796 parseNewArguments(node) { 2797 let targs = null; 2798 2799 if (this.shouldParseTypes() && this.isRelational("<")) { 2800 const state = this.state.clone(); 2801 2802 try { 2803 targs = this.flowParseTypeParameterInstantiationCallOrNew(); 2804 } catch (e) { 2805 if (e instanceof SyntaxError) { 2806 this.state = state; 2807 } else { 2808 throw e; 2809 } 2810 } 2811 } 2812 2813 node.typeArguments = targs; 2814 super.parseNewArguments(node); 2815 } 2816 2817 parseAsyncArrowWithTypeParameters(startPos, startLoc) { 2818 const node = this.startNodeAt(startPos, startLoc); 2819 this.parseFunctionParams(node); 2820 if (!this.parseArrow(node)) return; 2821 return this.parseArrowExpression(node, undefined, true); 2822 } 2823 2824 readToken_mult_modulo(code) { 2825 const next = this.input.charCodeAt(this.state.pos + 1); 2826 2827 if (code === 42 && next === 47 && this.state.hasFlowComment) { 2828 this.state.hasFlowComment = false; 2829 this.state.pos += 2; 2830 this.nextToken(); 2831 return; 2832 } 2833 2834 super.readToken_mult_modulo(code); 2835 } 2836 2837 readToken_pipe_amp(code) { 2838 const next = this.input.charCodeAt(this.state.pos + 1); 2839 2840 if (code === 124 && next === 125) { 2841 this.finishOp(types.braceBarR, 2); 2842 return; 2843 } 2844 2845 super.readToken_pipe_amp(code); 2846 } 2847 2848 parseTopLevel(file, program) { 2849 const fileNode = super.parseTopLevel(file, program); 2850 2851 if (this.state.hasFlowComment) { 2852 this.unexpected(null, "Unterminated flow-comment"); 2853 } 2854 2855 return fileNode; 2856 } 2857 2858 skipBlockComment() { 2859 if (this.hasPlugin("flowComments") && this.skipFlowComment()) { 2860 if (this.state.hasFlowComment) { 2861 this.unexpected(null, "Cannot have a flow comment inside another flow comment"); 2862 } 2863 2864 this.hasFlowCommentCompletion(); 2865 this.state.pos += this.skipFlowComment(); 2866 this.state.hasFlowComment = true; 2867 return; 2868 } 2869 2870 if (this.state.hasFlowComment) { 2871 const end = this.input.indexOf("*-/", this.state.pos += 2); 2872 if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment"); 2873 this.state.pos = end + 3; 2874 return; 2875 } 2876 2877 super.skipBlockComment(); 2878 } 2879 2880 skipFlowComment() { 2881 const { 2882 pos 2883 } = this.state; 2884 let shiftToFirstNonWhiteSpace = 2; 2885 2886 while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) { 2887 shiftToFirstNonWhiteSpace++; 2888 } 2889 2890 const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos); 2891 const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1); 2892 2893 if (ch2 === 58 && ch3 === 58) { 2894 return shiftToFirstNonWhiteSpace + 2; 2895 } 2896 2897 if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") { 2898 return shiftToFirstNonWhiteSpace + 12; 2899 } 2900 2901 if (ch2 === 58 && ch3 !== 58) { 2902 return shiftToFirstNonWhiteSpace; 2903 } 2904 2905 return false; 2906 } 2907 2908 hasFlowCommentCompletion() { 2909 const end = this.input.indexOf("*/", this.state.pos); 2910 2911 if (end === -1) { 2912 this.raise(this.state.pos, "Unterminated comment"); 2913 } 2914 } 2915 2916}); 2917 2918const entities = { 2919 quot: "\u0022", 2920 amp: "&", 2921 apos: "\u0027", 2922 lt: "<", 2923 gt: ">", 2924 nbsp: "\u00A0", 2925 iexcl: "\u00A1", 2926 cent: "\u00A2", 2927 pound: "\u00A3", 2928 curren: "\u00A4", 2929 yen: "\u00A5", 2930 brvbar: "\u00A6", 2931 sect: "\u00A7", 2932 uml: "\u00A8", 2933 copy: "\u00A9", 2934 ordf: "\u00AA", 2935 laquo: "\u00AB", 2936 not: "\u00AC", 2937 shy: "\u00AD", 2938 reg: "\u00AE", 2939 macr: "\u00AF", 2940 deg: "\u00B0", 2941 plusmn: "\u00B1", 2942 sup2: "\u00B2", 2943 sup3: "\u00B3", 2944 acute: "\u00B4", 2945 micro: "\u00B5", 2946 para: "\u00B6", 2947 middot: "\u00B7", 2948 cedil: "\u00B8", 2949 sup1: "\u00B9", 2950 ordm: "\u00BA", 2951 raquo: "\u00BB", 2952 frac14: "\u00BC", 2953 frac12: "\u00BD", 2954 frac34: "\u00BE", 2955 iquest: "\u00BF", 2956 Agrave: "\u00C0", 2957 Aacute: "\u00C1", 2958 Acirc: "\u00C2", 2959 Atilde: "\u00C3", 2960 Auml: "\u00C4", 2961 Aring: "\u00C5", 2962 AElig: "\u00C6", 2963 Ccedil: "\u00C7", 2964 Egrave: "\u00C8", 2965 Eacute: "\u00C9", 2966 Ecirc: "\u00CA", 2967 Euml: "\u00CB", 2968 Igrave: "\u00CC", 2969 Iacute: "\u00CD", 2970 Icirc: "\u00CE", 2971 Iuml: "\u00CF", 2972 ETH: "\u00D0", 2973 Ntilde: "\u00D1", 2974 Ograve: "\u00D2", 2975 Oacute: "\u00D3", 2976 Ocirc: "\u00D4", 2977 Otilde: "\u00D5", 2978 Ouml: "\u00D6", 2979 times: "\u00D7", 2980 Oslash: "\u00D8", 2981 Ugrave: "\u00D9", 2982 Uacute: "\u00DA", 2983 Ucirc: "\u00DB", 2984 Uuml: "\u00DC", 2985 Yacute: "\u00DD", 2986 THORN: "\u00DE", 2987 szlig: "\u00DF", 2988 agrave: "\u00E0", 2989 aacute: "\u00E1", 2990 acirc: "\u00E2", 2991 atilde: "\u00E3", 2992 auml: "\u00E4", 2993 aring: "\u00E5", 2994 aelig: "\u00E6", 2995 ccedil: "\u00E7", 2996 egrave: "\u00E8", 2997 eacute: "\u00E9", 2998 ecirc: "\u00EA", 2999 euml: "\u00EB", 3000 igrave: "\u00EC", 3001 iacute: "\u00ED", 3002 icirc: "\u00EE", 3003 iuml: "\u00EF", 3004 eth: "\u00F0", 3005 ntilde: "\u00F1", 3006 ograve: "\u00F2", 3007 oacute: "\u00F3", 3008 ocirc: "\u00F4", 3009 otilde: "\u00F5", 3010 ouml: "\u00F6", 3011 divide: "\u00F7", 3012 oslash: "\u00F8", 3013 ugrave: "\u00F9", 3014 uacute: "\u00FA", 3015 ucirc: "\u00FB", 3016 uuml: "\u00FC", 3017 yacute: "\u00FD", 3018 thorn: "\u00FE", 3019 yuml: "\u00FF", 3020 OElig: "\u0152", 3021 oelig: "\u0153", 3022 Scaron: "\u0160", 3023 scaron: "\u0161", 3024 Yuml: "\u0178", 3025 fnof: "\u0192", 3026 circ: "\u02C6", 3027 tilde: "\u02DC", 3028 Alpha: "\u0391", 3029 Beta: "\u0392", 3030 Gamma: "\u0393", 3031 Delta: "\u0394", 3032 Epsilon: "\u0395", 3033 Zeta: "\u0396", 3034 Eta: "\u0397", 3035 Theta: "\u0398", 3036 Iota: "\u0399", 3037 Kappa: "\u039A", 3038 Lambda: "\u039B", 3039 Mu: "\u039C", 3040 Nu: "\u039D", 3041 Xi: "\u039E", 3042 Omicron: "\u039F", 3043 Pi: "\u03A0", 3044 Rho: "\u03A1", 3045 Sigma: "\u03A3", 3046 Tau: "\u03A4", 3047 Upsilon: "\u03A5", 3048 Phi: "\u03A6", 3049 Chi: "\u03A7", 3050 Psi: "\u03A8", 3051 Omega: "\u03A9", 3052 alpha: "\u03B1", 3053 beta: "\u03B2", 3054 gamma: "\u03B3", 3055 delta: "\u03B4", 3056 epsilon: "\u03B5", 3057 zeta: "\u03B6", 3058 eta: "\u03B7", 3059 theta: "\u03B8", 3060 iota: "\u03B9", 3061 kappa: "\u03BA", 3062 lambda: "\u03BB", 3063 mu: "\u03BC", 3064 nu: "\u03BD", 3065 xi: "\u03BE", 3066 omicron: "\u03BF", 3067 pi: "\u03C0", 3068 rho: "\u03C1", 3069 sigmaf: "\u03C2", 3070 sigma: "\u03C3", 3071 tau: "\u03C4", 3072 upsilon: "\u03C5", 3073 phi: "\u03C6", 3074 chi: "\u03C7", 3075 psi: "\u03C8", 3076 omega: "\u03C9", 3077 thetasym: "\u03D1", 3078 upsih: "\u03D2", 3079 piv: "\u03D6", 3080 ensp: "\u2002", 3081 emsp: "\u2003", 3082 thinsp: "\u2009", 3083 zwnj: "\u200C", 3084 zwj: "\u200D", 3085 lrm: "\u200E", 3086 rlm: "\u200F", 3087 ndash: "\u2013", 3088 mdash: "\u2014", 3089 lsquo: "\u2018", 3090 rsquo: "\u2019", 3091 sbquo: "\u201A", 3092 ldquo: "\u201C", 3093 rdquo: "\u201D", 3094 bdquo: "\u201E", 3095 dagger: "\u2020", 3096 Dagger: "\u2021", 3097 bull: "\u2022", 3098 hellip: "\u2026", 3099 permil: "\u2030", 3100 prime: "\u2032", 3101 Prime: "\u2033", 3102 lsaquo: "\u2039", 3103 rsaquo: "\u203A", 3104 oline: "\u203E", 3105 frasl: "\u2044", 3106 euro: "\u20AC", 3107 image: "\u2111", 3108 weierp: "\u2118", 3109 real: "\u211C", 3110 trade: "\u2122", 3111 alefsym: "\u2135", 3112 larr: "\u2190", 3113 uarr: "\u2191", 3114 rarr: "\u2192", 3115 darr: "\u2193", 3116 harr: "\u2194", 3117 crarr: "\u21B5", 3118 lArr: "\u21D0", 3119 uArr: "\u21D1", 3120 rArr: "\u21D2", 3121 dArr: "\u21D3", 3122 hArr: "\u21D4", 3123 forall: "\u2200", 3124 part: "\u2202", 3125 exist: "\u2203", 3126 empty: "\u2205", 3127 nabla: "\u2207", 3128 isin: "\u2208", 3129 notin: "\u2209", 3130 ni: "\u220B", 3131 prod: "\u220F", 3132 sum: "\u2211", 3133 minus: "\u2212", 3134 lowast: "\u2217", 3135 radic: "\u221A", 3136 prop: "\u221D", 3137 infin: "\u221E", 3138 ang: "\u2220", 3139 and: "\u2227", 3140 or: "\u2228", 3141 cap: "\u2229", 3142 cup: "\u222A", 3143 int: "\u222B", 3144 there4: "\u2234", 3145 sim: "\u223C", 3146 cong: "\u2245", 3147 asymp: "\u2248", 3148 ne: "\u2260", 3149 equiv: "\u2261", 3150 le: "\u2264", 3151 ge: "\u2265", 3152 sub: "\u2282", 3153 sup: "\u2283", 3154 nsub: "\u2284", 3155 sube: "\u2286", 3156 supe: "\u2287", 3157 oplus: "\u2295", 3158 otimes: "\u2297", 3159 perp: "\u22A5", 3160 sdot: "\u22C5", 3161 lceil: "\u2308", 3162 rceil: "\u2309", 3163 lfloor: "\u230A", 3164 rfloor: "\u230B", 3165 lang: "\u2329", 3166 rang: "\u232A", 3167 loz: "\u25CA", 3168 spades: "\u2660", 3169 clubs: "\u2663", 3170 hearts: "\u2665", 3171 diams: "\u2666" 3172}; 3173 3174const HEX_NUMBER = /^[\da-fA-F]+$/; 3175const DECIMAL_NUMBER = /^\d+$/; 3176types$1.j_oTag = new TokContext("<tag", false); 3177types$1.j_cTag = new TokContext("</tag", false); 3178types$1.j_expr = new TokContext("<tag>...</tag>", true, true); 3179types.jsxName = new TokenType("jsxName"); 3180types.jsxText = new TokenType("jsxText", { 3181 beforeExpr: true 3182}); 3183types.jsxTagStart = new TokenType("jsxTagStart", { 3184 startsExpr: true 3185}); 3186types.jsxTagEnd = new TokenType("jsxTagEnd"); 3187 3188types.jsxTagStart.updateContext = function () { 3189 this.state.context.push(types$1.j_expr); 3190 this.state.context.push(types$1.j_oTag); 3191 this.state.exprAllowed = false; 3192}; 3193 3194types.jsxTagEnd.updateContext = function (prevType) { 3195 const out = this.state.context.pop(); 3196 3197 if (out === types$1.j_oTag && prevType === types.slash || out === types$1.j_cTag) { 3198 this.state.context.pop(); 3199 this.state.exprAllowed = this.curContext() === types$1.j_expr; 3200 } else { 3201 this.state.exprAllowed = true; 3202 } 3203}; 3204 3205function isFragment(object) { 3206 return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false; 3207} 3208 3209function getQualifiedJSXName(object) { 3210 if (object.type === "JSXIdentifier") { 3211 return object.name; 3212 } 3213 3214 if (object.type === "JSXNamespacedName") { 3215 return object.namespace.name + ":" + object.name.name; 3216 } 3217 3218 if (object.type === "JSXMemberExpression") { 3219 return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property); 3220 } 3221 3222 throw new Error("Node had unexpected type: " + object.type); 3223} 3224 3225var jsx = (superClass => class extends superClass { 3226 jsxReadToken() { 3227 let out = ""; 3228 let chunkStart = this.state.pos; 3229 3230 for (;;) { 3231 if (this.state.pos >= this.length) { 3232 this.raise(this.state.start, "Unterminated JSX contents"); 3233 } 3234 3235 const ch = this.input.charCodeAt(this.state.pos); 3236 3237 switch (ch) { 3238 case 60: 3239 case 123: 3240 if (this.state.pos === this.state.start) { 3241 if (ch === 60 && this.state.exprAllowed) { 3242 ++this.state.pos; 3243 return this.finishToken(types.jsxTagStart); 3244 } 3245 3246 return super.getTokenFromCode(ch); 3247 } 3248 3249 out += this.input.slice(chunkStart, this.state.pos); 3250 return this.finishToken(types.jsxText, out); 3251 3252 case 38: 3253 out += this.input.slice(chunkStart, this.state.pos); 3254 out += this.jsxReadEntity(); 3255 chunkStart = this.state.pos; 3256 break; 3257 3258 default: 3259 if (isNewLine(ch)) { 3260 out += this.input.slice(chunkStart, this.state.pos); 3261 out += this.jsxReadNewLine(true); 3262 chunkStart = this.state.pos; 3263 } else { 3264 ++this.state.pos; 3265 } 3266 3267 } 3268 } 3269 } 3270 3271 jsxReadNewLine(normalizeCRLF) { 3272 const ch = this.input.charCodeAt(this.state.pos); 3273 let out; 3274 ++this.state.pos; 3275 3276 if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { 3277 ++this.state.pos; 3278 out = normalizeCRLF ? "\n" : "\r\n"; 3279 } else { 3280 out = String.fromCharCode(ch); 3281 } 3282 3283 ++this.state.curLine; 3284 this.state.lineStart = this.state.pos; 3285 return out; 3286 } 3287 3288 jsxReadString(quote) { 3289 let out = ""; 3290 let chunkStart = ++this.state.pos; 3291 3292 for (;;) { 3293 if (this.state.pos >= this.length) { 3294 this.raise(this.state.start, "Unterminated string constant"); 3295 } 3296 3297 const ch = this.input.charCodeAt(this.state.pos); 3298 if (ch === quote) break; 3299 3300 if (ch === 38) { 3301 out += this.input.slice(chunkStart, this.state.pos); 3302 out += this.jsxReadEntity(); 3303 chunkStart = this.state.pos; 3304 } else if (isNewLine(ch)) { 3305 out += this.input.slice(chunkStart, this.state.pos); 3306 out += this.jsxReadNewLine(false); 3307 chunkStart = this.state.pos; 3308 } else { 3309 ++this.state.pos; 3310 } 3311 } 3312 3313 out += this.input.slice(chunkStart, this.state.pos++); 3314 return this.finishToken(types.string, out); 3315 } 3316 3317 jsxReadEntity() { 3318 let str = ""; 3319 let count = 0; 3320 let entity; 3321 let ch = this.input[this.state.pos]; 3322 const startPos = ++this.state.pos; 3323 3324 while (this.state.pos < this.length && count++ < 10) { 3325 ch = this.input[this.state.pos++]; 3326 3327 if (ch === ";") { 3328 if (str[0] === "#") { 3329 if (str[1] === "x") { 3330 str = str.substr(2); 3331 3332 if (HEX_NUMBER.test(str)) { 3333 entity = String.fromCodePoint(parseInt(str, 16)); 3334 } 3335 } else { 3336 str = str.substr(1); 3337 3338 if (DECIMAL_NUMBER.test(str)) { 3339 entity = String.fromCodePoint(parseInt(str, 10)); 3340 } 3341 } 3342 } else { 3343 entity = entities[str]; 3344 } 3345 3346 break; 3347 } 3348 3349 str += ch; 3350 } 3351 3352 if (!entity) { 3353 this.state.pos = startPos; 3354 return "&"; 3355 } 3356 3357 return entity; 3358 } 3359 3360 jsxReadWord() { 3361 let ch; 3362 const start = this.state.pos; 3363 3364 do { 3365 ch = this.input.charCodeAt(++this.state.pos); 3366 } while (isIdentifierChar(ch) || ch === 45); 3367 3368 return this.finishToken(types.jsxName, this.input.slice(start, this.state.pos)); 3369 } 3370 3371 jsxParseIdentifier() { 3372 const node = this.startNode(); 3373 3374 if (this.match(types.jsxName)) { 3375 node.name = this.state.value; 3376 } else if (this.state.type.keyword) { 3377 node.name = this.state.type.keyword; 3378 } else { 3379 this.unexpected(); 3380 } 3381 3382 this.next(); 3383 return this.finishNode(node, "JSXIdentifier"); 3384 } 3385 3386 jsxParseNamespacedName() { 3387 const startPos = this.state.start; 3388 const startLoc = this.state.startLoc; 3389 const name = this.jsxParseIdentifier(); 3390 if (!this.eat(types.colon)) return name; 3391 const node = this.startNodeAt(startPos, startLoc); 3392 node.namespace = name; 3393 node.name = this.jsxParseIdentifier(); 3394 return this.finishNode(node, "JSXNamespacedName"); 3395 } 3396 3397 jsxParseElementName() { 3398 const startPos = this.state.start; 3399 const startLoc = this.state.startLoc; 3400 let node = this.jsxParseNamespacedName(); 3401 3402 while (this.eat(types.dot)) { 3403 const newNode = this.startNodeAt(startPos, startLoc); 3404 newNode.object = node; 3405 newNode.property = this.jsxParseIdentifier(); 3406 node = this.finishNode(newNode, "JSXMemberExpression"); 3407 } 3408 3409 return node; 3410 } 3411 3412 jsxParseAttributeValue() { 3413 let node; 3414 3415 switch (this.state.type) { 3416 case types.braceL: 3417 node = this.startNode(); 3418 this.next(); 3419 node = this.jsxParseExpressionContainer(node); 3420 3421 if (node.expression.type === "JSXEmptyExpression") { 3422 throw this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); 3423 } else { 3424 return node; 3425 } 3426 3427 case types.jsxTagStart: 3428 case types.string: 3429 return this.parseExprAtom(); 3430 3431 default: 3432 throw this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); 3433 } 3434 } 3435 3436 jsxParseEmptyExpression() { 3437 const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); 3438 return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); 3439 } 3440 3441 jsxParseSpreadChild(node) { 3442 this.next(); 3443 node.expression = this.parseExpression(); 3444 this.expect(types.braceR); 3445 return this.finishNode(node, "JSXSpreadChild"); 3446 } 3447 3448 jsxParseExpressionContainer(node) { 3449 if (this.match(types.braceR)) { 3450 node.expression = this.jsxParseEmptyExpression(); 3451 } else { 3452 node.expression = this.parseExpression(); 3453 } 3454 3455 this.expect(types.braceR); 3456 return this.finishNode(node, "JSXExpressionContainer"); 3457 } 3458 3459 jsxParseAttribute() { 3460 const node = this.startNode(); 3461 3462 if (this.eat(types.braceL)) { 3463 this.expect(types.ellipsis); 3464 node.argument = this.parseMaybeAssign(); 3465 this.expect(types.braceR); 3466 return this.finishNode(node, "JSXSpreadAttribute"); 3467 } 3468 3469 node.name = this.jsxParseNamespacedName(); 3470 node.value = this.eat(types.eq) ? this.jsxParseAttributeValue() : null; 3471 return this.finishNode(node, "JSXAttribute"); 3472 } 3473 3474 jsxParseOpeningElementAt(startPos, startLoc) { 3475 const node = this.startNodeAt(startPos, startLoc); 3476 3477 if (this.match(types.jsxTagEnd)) { 3478 this.expect(types.jsxTagEnd); 3479 return this.finishNode(node, "JSXOpeningFragment"); 3480 } 3481 3482 node.name = this.jsxParseElementName(); 3483 return this.jsxParseOpeningElementAfterName(node); 3484 } 3485 3486 jsxParseOpeningElementAfterName(node) { 3487 const attributes = []; 3488 3489 while (!this.match(types.slash) && !this.match(types.jsxTagEnd)) { 3490 attributes.push(this.jsxParseAttribute()); 3491 } 3492 3493 node.attributes = attributes; 3494 node.selfClosing = this.eat(types.slash); 3495 this.expect(types.jsxTagEnd); 3496 return this.finishNode(node, "JSXOpeningElement"); 3497 } 3498 3499 jsxParseClosingElementAt(startPos, startLoc) { 3500 const node = this.startNodeAt(startPos, startLoc); 3501 3502 if (this.match(types.jsxTagEnd)) { 3503 this.expect(types.jsxTagEnd); 3504 return this.finishNode(node, "JSXClosingFragment"); 3505 } 3506 3507 node.name = this.jsxParseElementName(); 3508 this.expect(types.jsxTagEnd); 3509 return this.finishNode(node, "JSXClosingElement"); 3510 } 3511 3512 jsxParseElementAt(startPos, startLoc) { 3513 const node = this.startNodeAt(startPos, startLoc); 3514 const children = []; 3515 const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); 3516 let closingElement = null; 3517 3518 if (!openingElement.selfClosing) { 3519 contents: for (;;) { 3520 switch (this.state.type) { 3521 case types.jsxTagStart: 3522 startPos = this.state.start; 3523 startLoc = this.state.startLoc; 3524 this.next(); 3525 3526 if (this.eat(types.slash)) { 3527 closingElement = this.jsxParseClosingElementAt(startPos, startLoc); 3528 break contents; 3529 } 3530 3531 children.push(this.jsxParseElementAt(startPos, startLoc)); 3532 break; 3533 3534 case types.jsxText: 3535 children.push(this.parseExprAtom()); 3536 break; 3537 3538 case types.braceL: 3539 { 3540 const node = this.startNode(); 3541 this.next(); 3542 3543 if (this.match(types.ellipsis)) { 3544 children.push(this.jsxParseSpreadChild(node)); 3545 } else { 3546 children.push(this.jsxParseExpressionContainer(node)); 3547 } 3548 3549 break; 3550 } 3551 3552 default: 3553 throw this.unexpected(); 3554 } 3555 } 3556 3557 if (isFragment(openingElement) && !isFragment(closingElement)) { 3558 this.raise(closingElement.start, "Expected corresponding JSX closing tag for <>"); 3559 } else if (!isFragment(openingElement) && isFragment(closingElement)) { 3560 this.raise(closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">"); 3561 } else if (!isFragment(openingElement) && !isFragment(closingElement)) { 3562 if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { 3563 this.raise(closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">"); 3564 } 3565 } 3566 } 3567 3568 if (isFragment(openingElement)) { 3569 node.openingFragment = openingElement; 3570 node.closingFragment = closingElement; 3571 } else { 3572 node.openingElement = openingElement; 3573 node.closingElement = closingElement; 3574 } 3575 3576 node.children = children; 3577 3578 if (this.match(types.relational) && this.state.value === "<") { 3579 this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag. " + "Did you want a JSX fragment <>...</>?"); 3580 } 3581 3582 return isFragment(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement"); 3583 } 3584 3585 jsxParseElement() { 3586 const startPos = this.state.start; 3587 const startLoc = this.state.startLoc; 3588 this.next(); 3589 return this.jsxParseElementAt(startPos, startLoc); 3590 } 3591 3592 parseExprAtom(refShortHandDefaultPos) { 3593 if (this.match(types.jsxText)) { 3594 return this.parseLiteral(this.state.value, "JSXText"); 3595 } else if (this.match(types.jsxTagStart)) { 3596 return this.jsxParseElement(); 3597 } else if (this.isRelational("<") && this.input.charCodeAt(this.state.pos) !== 33) { 3598 this.finishToken(types.jsxTagStart); 3599 return this.jsxParseElement(); 3600 } else { 3601 return super.parseExprAtom(refShortHandDefaultPos); 3602 } 3603 } 3604 3605 getTokenFromCode(code) { 3606 if (this.state.inPropertyName) return super.getTokenFromCode(code); 3607 const context = this.curContext(); 3608 3609 if (context === types$1.j_expr) { 3610 return this.jsxReadToken(); 3611 } 3612 3613 if (context === types$1.j_oTag || context === types$1.j_cTag) { 3614 if (isIdentifierStart(code)) { 3615 return this.jsxReadWord(); 3616 } 3617 3618 if (code === 62) { 3619 ++this.state.pos; 3620 return this.finishToken(types.jsxTagEnd); 3621 } 3622 3623 if ((code === 34 || code === 39) && context === types$1.j_oTag) { 3624 return this.jsxReadString(code); 3625 } 3626 } 3627 3628 if (code === 60 && this.state.exprAllowed && this.input.charCodeAt(this.state.pos + 1) !== 33) { 3629 ++this.state.pos; 3630 return this.finishToken(types.jsxTagStart); 3631 } 3632 3633 return super.getTokenFromCode(code); 3634 } 3635 3636 updateContext(prevType) { 3637 if (this.match(types.braceL)) { 3638 const curContext = this.curContext(); 3639 3640 if (curContext === types$1.j_oTag) { 3641 this.state.context.push(types$1.braceExpression); 3642 } else if (curContext === types$1.j_expr) { 3643 this.state.context.push(types$1.templateQuasi); 3644 } else { 3645 super.updateContext(prevType); 3646 } 3647 3648 this.state.exprAllowed = true; 3649 } else if (this.match(types.slash) && prevType === types.jsxTagStart) { 3650 this.state.context.length -= 2; 3651 this.state.context.push(types$1.j_cTag); 3652 this.state.exprAllowed = false; 3653 } else { 3654 return super.updateContext(prevType); 3655 } 3656 } 3657 3658}); 3659 3660class Scope { 3661 constructor(flags) { 3662 this.var = []; 3663 this.lexical = []; 3664 this.functions = []; 3665 this.flags = flags; 3666 } 3667 3668} 3669class ScopeHandler { 3670 constructor(raise, inModule) { 3671 this.scopeStack = []; 3672 this.undefinedExports = new Map(); 3673 this.raise = raise; 3674 this.inModule = inModule; 3675 } 3676 3677 get inFunction() { 3678 return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0; 3679 } 3680 3681 get inGenerator() { 3682 return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0; 3683 } 3684 3685 get inAsync() { 3686 return (this.currentVarScope().flags & SCOPE_ASYNC) > 0; 3687 } 3688 3689 get allowSuper() { 3690 return (this.currentThisScope().flags & SCOPE_SUPER) > 0; 3691 } 3692 3693 get allowDirectSuper() { 3694 return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0; 3695 } 3696 3697 get inNonArrowFunction() { 3698 return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0; 3699 } 3700 3701 get treatFunctionsAsVar() { 3702 return this.treatFunctionsAsVarInScope(this.currentScope()); 3703 } 3704 3705 createScope(flags) { 3706 return new Scope(flags); 3707 } 3708 3709 enter(flags) { 3710 this.scopeStack.push(this.createScope(flags)); 3711 } 3712 3713 exit() { 3714 this.scopeStack.pop(); 3715 } 3716 3717 treatFunctionsAsVarInScope(scope) { 3718 return !!(scope.flags & SCOPE_FUNCTION || !this.inModule && scope.flags & SCOPE_PROGRAM); 3719 } 3720 3721 declareName(name, bindingType, pos) { 3722 let scope = this.currentScope(); 3723 3724 if (bindingType & BIND_SCOPE_LEXICAL || bindingType & BIND_SCOPE_FUNCTION) { 3725 this.checkRedeclarationInScope(scope, name, bindingType, pos); 3726 3727 if (bindingType & BIND_SCOPE_FUNCTION) { 3728 scope.functions.push(name); 3729 } else { 3730 scope.lexical.push(name); 3731 } 3732 3733 if (bindingType & BIND_SCOPE_LEXICAL) { 3734 this.maybeExportDefined(scope, name); 3735 } 3736 } else if (bindingType & BIND_SCOPE_VAR) { 3737 for (let i = this.scopeStack.length - 1; i >= 0; --i) { 3738 scope = this.scopeStack[i]; 3739 this.checkRedeclarationInScope(scope, name, bindingType, pos); 3740 scope.var.push(name); 3741 this.maybeExportDefined(scope, name); 3742 if (scope.flags & SCOPE_VAR) break; 3743 } 3744 } 3745 3746 if (this.inModule && scope.flags & SCOPE_PROGRAM) { 3747 this.undefinedExports.delete(name); 3748 } 3749 } 3750 3751 maybeExportDefined(scope, name) { 3752 if (this.inModule && scope.flags & SCOPE_PROGRAM) { 3753 this.undefinedExports.delete(name); 3754 } 3755 } 3756 3757 checkRedeclarationInScope(scope, name, bindingType, pos) { 3758 if (this.isRedeclaredInScope(scope, name, bindingType)) { 3759 this.raise(pos, `Identifier '${name}' has already been declared`); 3760 } 3761 } 3762 3763 isRedeclaredInScope(scope, name, bindingType) { 3764 if (!(bindingType & BIND_KIND_VALUE)) return false; 3765 3766 if (bindingType & BIND_SCOPE_LEXICAL) { 3767 return scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; 3768 } 3769 3770 if (bindingType & BIND_SCOPE_FUNCTION) { 3771 return scope.lexical.indexOf(name) > -1 || !this.treatFunctionsAsVarInScope(scope) && scope.var.indexOf(name) > -1; 3772 } 3773 3774 return scope.lexical.indexOf(name) > -1 && !(scope.flags & SCOPE_SIMPLE_CATCH && scope.lexical[0] === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.indexOf(name) > -1; 3775 } 3776 3777 checkLocalExport(id) { 3778 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && this.scopeStack[0].var.indexOf(id.name) === -1 && this.scopeStack[0].functions.indexOf(id.name) === -1) { 3779 this.undefinedExports.set(id.name, id.start); 3780 } 3781 } 3782 3783 currentScope() { 3784 return this.scopeStack[this.scopeStack.length - 1]; 3785 } 3786 3787 currentVarScope() { 3788 for (let i = this.scopeStack.length - 1;; i--) { 3789 const scope = this.scopeStack[i]; 3790 3791 if (scope.flags & SCOPE_VAR) { 3792 return scope; 3793 } 3794 } 3795 } 3796 3797 currentThisScope() { 3798 for (let i = this.scopeStack.length - 1;; i--) { 3799 const scope = this.scopeStack[i]; 3800 3801 if ((scope.flags & SCOPE_VAR || scope.flags & SCOPE_CLASS) && !(scope.flags & SCOPE_ARROW)) { 3802 return scope; 3803 } 3804 } 3805 } 3806 3807} 3808 3809class TypeScriptScope extends Scope { 3810 constructor(...args) { 3811 super(...args); 3812 this.types = []; 3813 this.enums = []; 3814 this.constEnums = []; 3815 this.classes = []; 3816 this.exportOnlyBindings = []; 3817 } 3818 3819} 3820 3821class TypeScriptScopeHandler extends ScopeHandler { 3822 createScope(flags) { 3823 return new TypeScriptScope(flags); 3824 } 3825 3826 declareName(name, bindingType, pos) { 3827 const scope = this.currentScope(); 3828 3829 if (bindingType & BIND_FLAGS_TS_EXPORT_ONLY) { 3830 this.maybeExportDefined(scope, name); 3831 scope.exportOnlyBindings.push(name); 3832 return; 3833 } 3834 3835 super.declareName(...arguments); 3836 3837 if (bindingType & BIND_KIND_TYPE) { 3838 if (!(bindingType & BIND_KIND_VALUE)) { 3839 this.checkRedeclarationInScope(scope, name, bindingType, pos); 3840 this.maybeExportDefined(scope, name); 3841 } 3842 3843 scope.types.push(name); 3844 } 3845 3846 if (bindingType & BIND_FLAGS_TS_ENUM) scope.enums.push(name); 3847 if (bindingType & BIND_FLAGS_TS_CONST_ENUM) scope.constEnums.push(name); 3848 if (bindingType & BIND_FLAGS_CLASS) scope.classes.push(name); 3849 } 3850 3851 isRedeclaredInScope(scope, name, bindingType) { 3852 if (scope.enums.indexOf(name) > -1) { 3853 if (bindingType & BIND_FLAGS_TS_ENUM) { 3854 const isConst = !!(bindingType & BIND_FLAGS_TS_CONST_ENUM); 3855 const wasConst = scope.constEnums.indexOf(name) > -1; 3856 return isConst !== wasConst; 3857 } 3858 3859 return true; 3860 } 3861 3862 if (bindingType & BIND_FLAGS_CLASS && scope.classes.indexOf(name) > -1) { 3863 if (scope.lexical.indexOf(name) > -1) { 3864 return !!(bindingType & BIND_KIND_VALUE); 3865 } else { 3866 return false; 3867 } 3868 } 3869 3870 if (bindingType & BIND_KIND_TYPE && scope.types.indexOf(name) > -1) { 3871 return true; 3872 } 3873 3874 return super.isRedeclaredInScope(...arguments); 3875 } 3876 3877 checkLocalExport(id) { 3878 if (this.scopeStack[0].types.indexOf(id.name) === -1 && this.scopeStack[0].exportOnlyBindings.indexOf(id.name) === -1) { 3879 super.checkLocalExport(id); 3880 } 3881 } 3882 3883} 3884 3885function nonNull(x) { 3886 if (x == null) { 3887 throw new Error(`Unexpected ${x} value.`); 3888 } 3889 3890 return x; 3891} 3892 3893function assert(x) { 3894 if (!x) { 3895 throw new Error("Assert fail"); 3896 } 3897} 3898 3899function keywordTypeFromName(value) { 3900 switch (value) { 3901 case "any": 3902 return "TSAnyKeyword"; 3903 3904 case "boolean": 3905 return "TSBooleanKeyword"; 3906 3907 case "bigint": 3908 return "TSBigIntKeyword"; 3909 3910 case "never": 3911 return "TSNeverKeyword"; 3912 3913 case "number": 3914 return "TSNumberKeyword"; 3915 3916 case "object": 3917 return "TSObjectKeyword"; 3918 3919 case "string": 3920 return "TSStringKeyword"; 3921 3922 case "symbol": 3923 return "TSSymbolKeyword"; 3924 3925 case "undefined": 3926 return "TSUndefinedKeyword"; 3927 3928 case "unknown": 3929 return "TSUnknownKeyword"; 3930 3931 default: 3932 return undefined; 3933 } 3934} 3935 3936var typescript = (superClass => class extends superClass { 3937 getScopeHandler() { 3938 return TypeScriptScopeHandler; 3939 } 3940 3941 tsIsIdentifier() { 3942 return this.match(types.name); 3943 } 3944 3945 tsNextTokenCanFollowModifier() { 3946 this.next(); 3947 return !this.hasPrecedingLineBreak() && !this.match(types.parenL) && !this.match(types.parenR) && !this.match(types.colon) && !this.match(types.eq) && !this.match(types.question) && !this.match(types.bang); 3948 } 3949 3950 tsParseModifier(allowedModifiers) { 3951 if (!this.match(types.name)) { 3952 return undefined; 3953 } 3954 3955 const modifier = this.state.value; 3956 3957 if (allowedModifiers.indexOf(modifier) !== -1 && this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) { 3958 return modifier; 3959 } 3960 3961 return undefined; 3962 } 3963 3964 tsIsListTerminator(kind) { 3965 switch (kind) { 3966 case "EnumMembers": 3967 case "TypeMembers": 3968 return this.match(types.braceR); 3969 3970 case "HeritageClauseElement": 3971 return this.match(types.braceL); 3972 3973 case "TupleElementTypes": 3974 return this.match(types.bracketR); 3975 3976 case "TypeParametersOrArguments": 3977 return this.isRelational(">"); 3978 } 3979 3980 throw new Error("Unreachable"); 3981 } 3982 3983 tsParseList(kind, parseElement) { 3984 const result = []; 3985 3986 while (!this.tsIsListTerminator(kind)) { 3987 result.push(parseElement()); 3988 } 3989 3990 return result; 3991 } 3992 3993 tsParseDelimitedList(kind, parseElement) { 3994 return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true)); 3995 } 3996 3997 tsParseDelimitedListWorker(kind, parseElement, expectSuccess) { 3998 const result = []; 3999 4000 while (true) { 4001 if (this.tsIsListTerminator(kind)) { 4002 break; 4003 } 4004 4005 const element = parseElement(); 4006 4007 if (element == null) { 4008 return undefined; 4009 } 4010 4011 result.push(element); 4012 4013 if (this.eat(types.comma)) { 4014 continue; 4015 } 4016 4017 if (this.tsIsListTerminator(kind)) { 4018 break; 4019 } 4020 4021 if (expectSuccess) { 4022 this.expect(types.comma); 4023 } 4024 4025 return undefined; 4026 } 4027 4028 return result; 4029 } 4030 4031 tsParseBracketedList(kind, parseElement, bracket, skipFirstToken) { 4032 if (!skipFirstToken) { 4033 if (bracket) { 4034 this.expect(types.bracketL); 4035 } else { 4036 this.expectRelational("<"); 4037 } 4038 } 4039 4040 const result = this.tsParseDelimitedList(kind, parseElement); 4041 4042 if (bracket) { 4043 this.expect(types.bracketR); 4044 } else { 4045 this.expectRelational(">"); 4046 } 4047 4048 return result; 4049 } 4050 4051 tsParseImportType() { 4052 const node = this.startNode(); 4053 this.expect(types._import); 4054 this.expect(types.parenL); 4055 4056 if (!this.match(types.string)) { 4057 throw this.unexpected(null, "Argument in a type import must be a string literal"); 4058 } 4059 4060 node.argument = this.parseExprAtom(); 4061 this.expect(types.parenR); 4062 4063 if (this.eat(types.dot)) { 4064 node.qualifier = this.tsParseEntityName(true); 4065 } 4066 4067 if (this.isRelational("<")) { 4068 node.typeParameters = this.tsParseTypeArguments(); 4069 } 4070 4071 return this.finishNode(node, "TSImportType"); 4072 } 4073 4074 tsParseEntityName(allowReservedWords) { 4075 let entity = this.parseIdentifier(); 4076 4077 while (this.eat(types.dot)) { 4078 const node = this.startNodeAtNode(entity); 4079 node.left = entity; 4080 node.right = this.parseIdentifier(allowReservedWords); 4081 entity = this.finishNode(node, "TSQualifiedName"); 4082 } 4083 4084 return entity; 4085 } 4086 4087 tsParseTypeReference() { 4088 const node = this.startNode(); 4089 node.typeName = this.tsParseEntityName(false); 4090 4091 if (!this.hasPrecedingLineBreak() && this.isRelational("<")) { 4092 node.typeParameters = this.tsParseTypeArguments(); 4093 } 4094 4095 return this.finishNode(node, "TSTypeReference"); 4096 } 4097 4098 tsParseThisTypePredicate(lhs) { 4099 this.next(); 4100 const node = this.startNodeAtNode(lhs); 4101 node.parameterName = lhs; 4102 node.typeAnnotation = this.tsParseTypeAnnotation(false); 4103 return this.finishNode(node, "TSTypePredicate"); 4104 } 4105 4106 tsParseThisTypeNode() { 4107 const node = this.startNode(); 4108 this.next(); 4109 return this.finishNode(node, "TSThisType"); 4110 } 4111 4112 tsParseTypeQuery() { 4113 const node = this.startNode(); 4114 this.expect(types._typeof); 4115 4116 if (this.match(types._import)) { 4117 node.exprName = this.tsParseImportType(); 4118 } else { 4119 node.exprName = this.tsParseEntityName(true); 4120 } 4121 4122 return this.finishNode(node, "TSTypeQuery"); 4123 } 4124 4125 tsParseTypeParameter() { 4126 const node = this.startNode(); 4127 node.name = this.parseIdentifierName(node.start); 4128 node.constraint = this.tsEatThenParseType(types._extends); 4129 node.default = this.tsEatThenParseType(types.eq); 4130 return this.finishNode(node, "TSTypeParameter"); 4131 } 4132 4133 tsTryParseTypeParameters() { 4134 if (this.isRelational("<")) { 4135 return this.tsParseTypeParameters(); 4136 } 4137 } 4138 4139 tsParseTypeParameters() { 4140 const node = this.startNode(); 4141 4142 if (this.isRelational("<") || this.match(types.jsxTagStart)) { 4143 this.next(); 4144 } else { 4145 this.unexpected(); 4146 } 4147 4148 node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true); 4149 return this.finishNode(node, "TSTypeParameterDeclaration"); 4150 } 4151 4152 tsTryNextParseConstantContext() { 4153 if (this.lookahead().type === types._const) { 4154 this.next(); 4155 return this.tsParseTypeReference(); 4156 } 4157 4158 return null; 4159 } 4160 4161 tsFillSignature(returnToken, signature) { 4162 const returnTokenRequired = returnToken === types.arrow; 4163 signature.typeParameters = this.tsTryParseTypeParameters(); 4164 this.expect(types.parenL); 4165 signature.parameters = this.tsParseBindingListForSignature(); 4166 4167 if (returnTokenRequired) { 4168 signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); 4169 } else if (this.match(returnToken)) { 4170 signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); 4171 } 4172 } 4173 4174 tsParseBindingListForSignature() { 4175 return this.parseBindingList(types.parenR).map(pattern => { 4176 if (pattern.type !== "Identifier" && pattern.type !== "RestElement" && pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") { 4177 throw this.unexpected(pattern.start, `Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${pattern.type}`); 4178 } 4179 4180 return pattern; 4181 }); 4182 } 4183 4184 tsParseTypeMemberSemicolon() { 4185 if (!this.eat(types.comma)) { 4186 this.semicolon(); 4187 } 4188 } 4189 4190 tsParseSignatureMember(kind, node) { 4191 this.tsFillSignature(types.colon, node); 4192 this.tsParseTypeMemberSemicolon(); 4193 return this.finishNode(node, kind); 4194 } 4195 4196 tsIsUnambiguouslyIndexSignature() { 4197 this.next(); 4198 return this.eat(types.name) && this.match(types.colon); 4199 } 4200 4201 tsTryParseIndexSignature(node) { 4202 if (!(this.match(types.bracketL) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) { 4203 return undefined; 4204 } 4205 4206 this.expect(types.bracketL); 4207 const id = this.parseIdentifier(); 4208 id.typeAnnotation = this.tsParseTypeAnnotation(); 4209 this.resetEndLocation(id); 4210 this.expect(types.bracketR); 4211 node.parameters = [id]; 4212 const type = this.tsTryParseTypeAnnotation(); 4213 if (type) node.typeAnnotation = type; 4214 this.tsParseTypeMemberSemicolon(); 4215 return this.finishNode(node, "TSIndexSignature"); 4216 } 4217 4218 tsParsePropertyOrMethodSignature(node, readonly) { 4219 if (this.eat(types.question)) node.optional = true; 4220 const nodeAny = node; 4221 4222 if (!readonly && (this.match(types.parenL) || this.isRelational("<"))) { 4223 const method = nodeAny; 4224 this.tsFillSignature(types.colon, method); 4225 this.tsParseTypeMemberSemicolon(); 4226 return this.finishNode(method, "TSMethodSignature"); 4227 } else { 4228 const property = nodeAny; 4229 if (readonly) property.readonly = true; 4230 const type = this.tsTryParseTypeAnnotation(); 4231 if (type) property.typeAnnotation = type; 4232 this.tsParseTypeMemberSemicolon(); 4233 return this.finishNode(property, "TSPropertySignature"); 4234 } 4235 } 4236 4237 tsParseTypeMember() { 4238 const node = this.startNode(); 4239 4240 if (this.match(types.parenL) || this.isRelational("<")) { 4241 return this.tsParseSignatureMember("TSCallSignatureDeclaration", node); 4242 } 4243 4244 if (this.match(types._new)) { 4245 const id = this.startNode(); 4246 this.next(); 4247 4248 if (this.match(types.parenL) || this.isRelational("<")) { 4249 return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node); 4250 } else { 4251 node.key = this.createIdentifier(id, "new"); 4252 return this.tsParsePropertyOrMethodSignature(node, false); 4253 } 4254 } 4255 4256 const readonly = !!this.tsParseModifier(["readonly"]); 4257 const idx = this.tsTryParseIndexSignature(node); 4258 4259 if (idx) { 4260 if (readonly) node.readonly = true; 4261 return idx; 4262 } 4263 4264 this.parsePropertyName(node); 4265 return this.tsParsePropertyOrMethodSignature(node, readonly); 4266 } 4267 4268 tsParseTypeLiteral() { 4269 const node = this.startNode(); 4270 node.members = this.tsParseObjectTypeMembers(); 4271 return this.finishNode(node, "TSTypeLiteral"); 4272 } 4273 4274 tsParseObjectTypeMembers() { 4275 this.expect(types.braceL); 4276 const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this)); 4277 this.expect(types.braceR); 4278 return members; 4279 } 4280 4281 tsIsStartOfMappedType() { 4282 this.next(); 4283 4284 if (this.eat(types.plusMin)) { 4285 return this.isContextual("readonly"); 4286 } 4287 4288 if (this.isContextual("readonly")) { 4289 this.next(); 4290 } 4291 4292 if (!this.match(types.bracketL)) { 4293 return false; 4294 } 4295 4296 this.next(); 4297 4298 if (!this.tsIsIdentifier()) { 4299 return false; 4300 } 4301 4302 this.next(); 4303 return this.match(types._in); 4304 } 4305 4306 tsParseMappedTypeParameter() { 4307 const node = this.startNode(); 4308 node.name = this.parseIdentifierName(node.start); 4309 node.constraint = this.tsExpectThenParseType(types._in); 4310 return this.finishNode(node, "TSTypeParameter"); 4311 } 4312 4313 tsParseMappedType() { 4314 const node = this.startNode(); 4315 this.expect(types.braceL); 4316 4317 if (this.match(types.plusMin)) { 4318 node.readonly = this.state.value; 4319 this.next(); 4320 this.expectContextual("readonly"); 4321 } else if (this.eatContextual("readonly")) { 4322 node.readonly = true; 4323 } 4324 4325 this.expect(types.bracketL); 4326 node.typeParameter = this.tsParseMappedTypeParameter(); 4327 this.expect(types.bracketR); 4328 4329 if (this.match(types.plusMin)) { 4330 node.optional = this.state.value; 4331 this.next(); 4332 this.expect(types.question); 4333 } else if (this.eat(types.question)) { 4334 node.optional = true; 4335 } 4336 4337 node.typeAnnotation = this.tsTryParseType(); 4338 this.semicolon(); 4339 this.expect(types.braceR); 4340 return this.finishNode(node, "TSMappedType"); 4341 } 4342 4343 tsParseTupleType() { 4344 const node = this.startNode(); 4345 node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false); 4346 let seenOptionalElement = false; 4347 node.elementTypes.forEach(elementNode => { 4348 if (elementNode.type === "TSOptionalType") { 4349 seenOptionalElement = true; 4350 } else if (seenOptionalElement && elementNode.type !== "TSRestType") { 4351 this.raise(elementNode.start, "A required element cannot follow an optional element."); 4352 } 4353 }); 4354 return this.finishNode(node, "TSTupleType"); 4355 } 4356 4357 tsParseTupleElementType() { 4358 if (this.match(types.ellipsis)) { 4359 const restNode = this.startNode(); 4360 this.next(); 4361 restNode.typeAnnotation = this.tsParseType(); 4362 this.checkCommaAfterRest(); 4363 return this.finishNode(restNode, "TSRestType"); 4364 } 4365 4366 const type = this.tsParseType(); 4367 4368 if (this.eat(types.question)) { 4369 const optionalTypeNode = this.startNodeAtNode(type); 4370 optionalTypeNode.typeAnnotation = type; 4371 return this.finishNode(optionalTypeNode, "TSOptionalType"); 4372 } 4373 4374 return type; 4375 } 4376 4377 tsParseParenthesizedType() { 4378 const node = this.startNode(); 4379 this.expect(types.parenL); 4380 node.typeAnnotation = this.tsParseType(); 4381 this.expect(types.parenR); 4382 return this.finishNode(node, "TSParenthesizedType"); 4383 } 4384 4385 tsParseFunctionOrConstructorType(type) { 4386 const node = this.startNode(); 4387 4388 if (type === "TSConstructorType") { 4389 this.expect(types._new); 4390 } 4391 4392 this.tsFillSignature(types.arrow, node); 4393 return this.finishNode(node, type); 4394 } 4395 4396 tsParseLiteralTypeNode() { 4397 const node = this.startNode(); 4398 4399 node.literal = (() => { 4400 switch (this.state.type) { 4401 case types.num: 4402 case types.string: 4403 case types._true: 4404 case types._false: 4405 return this.parseExprAtom(); 4406 4407 default: 4408 throw this.unexpected(); 4409 } 4410 })(); 4411 4412 return this.finishNode(node, "TSLiteralType"); 4413 } 4414 4415 tsParseTemplateLiteralType() { 4416 const node = this.startNode(); 4417 const templateNode = this.parseTemplate(false); 4418 4419 if (templateNode.expressions.length > 0) { 4420 throw this.raise(templateNode.expressions[0].start, "Template literal types cannot have any substitution"); 4421 } 4422 4423 node.literal = templateNode; 4424 return this.finishNode(node, "TSLiteralType"); 4425 } 4426 4427 tsParseNonArrayType() { 4428 switch (this.state.type) { 4429 case types.name: 4430 case types._void: 4431 case types._null: 4432 { 4433 const type = this.match(types._void) ? "TSVoidKeyword" : this.match(types._null) ? "TSNullKeyword" : keywordTypeFromName(this.state.value); 4434 4435 if (type !== undefined && this.lookahead().type !== types.dot) { 4436 const node = this.startNode(); 4437 this.next(); 4438 return this.finishNode(node, type); 4439 } 4440 4441 return this.tsParseTypeReference(); 4442 } 4443 4444 case types.string: 4445 case types.num: 4446 case types._true: 4447 case types._false: 4448 return this.tsParseLiteralTypeNode(); 4449 4450 case types.plusMin: 4451 if (this.state.value === "-") { 4452 const node = this.startNode(); 4453 4454 if (this.lookahead().type !== types.num) { 4455 throw this.unexpected(); 4456 } 4457 4458 node.literal = this.parseMaybeUnary(); 4459 return this.finishNode(node, "TSLiteralType"); 4460 } 4461 4462 break; 4463 4464 case types._this: 4465 { 4466 const thisKeyword = this.tsParseThisTypeNode(); 4467 4468 if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { 4469 return this.tsParseThisTypePredicate(thisKeyword); 4470 } else { 4471 return thisKeyword; 4472 } 4473 } 4474 4475 case types._typeof: 4476 return this.tsParseTypeQuery(); 4477 4478 case types._import: 4479 return this.tsParseImportType(); 4480 4481 case types.braceL: 4482 return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral(); 4483 4484 case types.bracketL: 4485 return this.tsParseTupleType(); 4486 4487 case types.parenL: 4488 return this.tsParseParenthesizedType(); 4489 4490 case types.backQuote: 4491 return this.tsParseTemplateLiteralType(); 4492 } 4493 4494 throw this.unexpected(); 4495 } 4496 4497 tsParseArrayTypeOrHigher() { 4498 let type = this.tsParseNonArrayType(); 4499 4500 while (!this.hasPrecedingLineBreak() && this.eat(types.bracketL)) { 4501 if (this.match(types.bracketR)) { 4502 const node = this.startNodeAtNode(type); 4503 node.elementType = type; 4504 this.expect(types.bracketR); 4505 type = this.finishNode(node, "TSArrayType"); 4506 } else { 4507 const node = this.startNodeAtNode(type); 4508 node.objectType = type; 4509 node.indexType = this.tsParseType(); 4510 this.expect(types.bracketR); 4511 type = this.finishNode(node, "TSIndexedAccessType"); 4512 } 4513 } 4514 4515 return type; 4516 } 4517 4518 tsParseTypeOperator(operator) { 4519 const node = this.startNode(); 4520 this.expectContextual(operator); 4521 node.operator = operator; 4522 node.typeAnnotation = this.tsParseTypeOperatorOrHigher(); 4523 4524 if (operator === "readonly") { 4525 this.tsCheckTypeAnnotationForReadOnly(node); 4526 } 4527 4528 return this.finishNode(node, "TSTypeOperator"); 4529 } 4530 4531 tsCheckTypeAnnotationForReadOnly(node) { 4532 switch (node.typeAnnotation.type) { 4533 case "TSTupleType": 4534 case "TSArrayType": 4535 return; 4536 4537 default: 4538 this.raise(node.start, "'readonly' type modifier is only permitted on array and tuple literal types."); 4539 } 4540 } 4541 4542 tsParseInferType() { 4543 const node = this.startNode(); 4544 this.expectContextual("infer"); 4545 const typeParameter = this.startNode(); 4546 typeParameter.name = this.parseIdentifierName(typeParameter.start); 4547 node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter"); 4548 return this.finishNode(node, "TSInferType"); 4549 } 4550 4551 tsParseTypeOperatorOrHigher() { 4552 const operator = ["keyof", "unique", "readonly"].find(kw => this.isContextual(kw)); 4553 return operator ? this.tsParseTypeOperator(operator) : this.isContextual("infer") ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher(); 4554 } 4555 4556 tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) { 4557 this.eat(operator); 4558 let type = parseConstituentType(); 4559 4560 if (this.match(operator)) { 4561 const types = [type]; 4562 4563 while (this.eat(operator)) { 4564 types.push(parseConstituentType()); 4565 } 4566 4567 const node = this.startNodeAtNode(type); 4568 node.types = types; 4569 type = this.finishNode(node, kind); 4570 } 4571 4572 return type; 4573 } 4574 4575 tsParseIntersectionTypeOrHigher() { 4576 return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), types.bitwiseAND); 4577 } 4578 4579 tsParseUnionTypeOrHigher() { 4580 return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), types.bitwiseOR); 4581 } 4582 4583 tsIsStartOfFunctionType() { 4584 if (this.isRelational("<")) { 4585 return true; 4586 } 4587 4588 return this.match(types.parenL) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this)); 4589 } 4590 4591 tsSkipParameterStart() { 4592 if (this.match(types.name) || this.match(types._this)) { 4593 this.next(); 4594 return true; 4595 } 4596 4597 if (this.match(types.braceL)) { 4598 let braceStackCounter = 1; 4599 this.next(); 4600 4601 while (braceStackCounter > 0) { 4602 if (this.match(types.braceL)) { 4603 ++braceStackCounter; 4604 } else if (this.match(types.braceR)) { 4605 --braceStackCounter; 4606 } 4607 4608 this.next(); 4609 } 4610 4611 return true; 4612 } 4613 4614 if (this.match(types.bracketL)) { 4615 let braceStackCounter = 1; 4616 this.next(); 4617 4618 while (braceStackCounter > 0) { 4619 if (this.match(types.bracketL)) { 4620 ++braceStackCounter; 4621 } else if (this.match(types.bracketR)) { 4622 --braceStackCounter; 4623 } 4624 4625 this.next(); 4626 } 4627 4628 return true; 4629 } 4630 4631 return false; 4632 } 4633 4634 tsIsUnambiguouslyStartOfFunctionType() { 4635 this.next(); 4636 4637 if (this.match(types.parenR) || this.match(types.ellipsis)) { 4638 return true; 4639 } 4640 4641 if (this.tsSkipParameterStart()) { 4642 if (this.match(types.colon) || this.match(types.comma) || this.match(types.question) || this.match(types.eq)) { 4643 return true; 4644 } 4645 4646 if (this.match(types.parenR)) { 4647 this.next(); 4648 4649 if (this.match(types.arrow)) { 4650 return true; 4651 } 4652 } 4653 } 4654 4655 return false; 4656 } 4657 4658 tsParseTypeOrTypePredicateAnnotation(returnToken) { 4659 return this.tsInType(() => { 4660 const t = this.startNode(); 4661 this.expect(returnToken); 4662 const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this)); 4663 4664 if (!typePredicateVariable) { 4665 return this.tsParseTypeAnnotation(false, t); 4666 } 4667 4668 const type = this.tsParseTypeAnnotation(false); 4669 const node = this.startNodeAtNode(typePredicateVariable); 4670 node.parameterName = typePredicateVariable; 4671 node.typeAnnotation = type; 4672 t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); 4673 return this.finishNode(t, "TSTypeAnnotation"); 4674 }); 4675 } 4676 4677 tsTryParseTypeOrTypePredicateAnnotation() { 4678 return this.match(types.colon) ? this.tsParseTypeOrTypePredicateAnnotation(types.colon) : undefined; 4679 } 4680 4681 tsTryParseTypeAnnotation() { 4682 return this.match(types.colon) ? this.tsParseTypeAnnotation() : undefined; 4683 } 4684 4685 tsTryParseType() { 4686 return this.tsEatThenParseType(types.colon); 4687 } 4688 4689 tsParseTypePredicatePrefix() { 4690 const id = this.parseIdentifier(); 4691 4692 if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { 4693 this.next(); 4694 return id; 4695 } 4696 } 4697 4698 tsParseTypeAnnotation(eatColon = true, t = this.startNode()) { 4699 this.tsInType(() => { 4700 if (eatColon) this.expect(types.colon); 4701 t.typeAnnotation = this.tsParseType(); 4702 }); 4703 return this.finishNode(t, "TSTypeAnnotation"); 4704 } 4705 4706 tsParseType() { 4707 assert(this.state.inType); 4708 const type = this.tsParseNonConditionalType(); 4709 4710 if (this.hasPrecedingLineBreak() || !this.eat(types._extends)) { 4711 return type; 4712 } 4713 4714 const node = this.startNodeAtNode(type); 4715 node.checkType = type; 4716 node.extendsType = this.tsParseNonConditionalType(); 4717 this.expect(types.question); 4718 node.trueType = this.tsParseType(); 4719 this.expect(types.colon); 4720 node.falseType = this.tsParseType(); 4721 return this.finishNode(node, "TSConditionalType"); 4722 } 4723 4724 tsParseNonConditionalType() { 4725 if (this.tsIsStartOfFunctionType()) { 4726 return this.tsParseFunctionOrConstructorType("TSFunctionType"); 4727 } 4728 4729 if (this.match(types._new)) { 4730 return this.tsParseFunctionOrConstructorType("TSConstructorType"); 4731 } 4732 4733 return this.tsParseUnionTypeOrHigher(); 4734 } 4735 4736 tsParseTypeAssertion() { 4737 const node = this.startNode(); 4738 4739 const _const = this.tsTryNextParseConstantContext(); 4740 4741 node.typeAnnotation = _const || this.tsNextThenParseType(); 4742 this.expectRelational(">"); 4743 node.expression = this.parseMaybeUnary(); 4744 return this.finishNode(node, "TSTypeAssertion"); 4745 } 4746 4747 tsParseHeritageClause(descriptor) { 4748 const originalStart = this.state.start; 4749 const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", this.tsParseExpressionWithTypeArguments.bind(this)); 4750 4751 if (!delimitedList.length) { 4752 this.raise(originalStart, `'${descriptor}' list cannot be empty.`); 4753 } 4754 4755 return delimitedList; 4756 } 4757 4758 tsParseExpressionWithTypeArguments() { 4759 const node = this.startNode(); 4760 node.expression = this.tsParseEntityName(false); 4761 4762 if (this.isRelational("<")) { 4763 node.typeParameters = this.tsParseTypeArguments(); 4764 } 4765 4766 return this.finishNode(node, "TSExpressionWithTypeArguments"); 4767 } 4768 4769 tsParseInterfaceDeclaration(node) { 4770 node.id = this.parseIdentifier(); 4771 this.checkLVal(node.id, BIND_TS_INTERFACE, undefined, "typescript interface declaration"); 4772 node.typeParameters = this.tsTryParseTypeParameters(); 4773 4774 if (this.eat(types._extends)) { 4775 node.extends = this.tsParseHeritageClause("extends"); 4776 } 4777 4778 const body = this.startNode(); 4779 body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this)); 4780 node.body = this.finishNode(body, "TSInterfaceBody"); 4781 return this.finishNode(node, "TSInterfaceDeclaration"); 4782 } 4783 4784 tsParseTypeAliasDeclaration(node) { 4785 node.id = this.parseIdentifier(); 4786 this.checkLVal(node.id, BIND_TS_TYPE, undefined, "typescript type alias"); 4787 node.typeParameters = this.tsTryParseTypeParameters(); 4788 node.typeAnnotation = this.tsExpectThenParseType(types.eq); 4789 this.semicolon(); 4790 return this.finishNode(node, "TSTypeAliasDeclaration"); 4791 } 4792 4793 tsInNoContext(cb) { 4794 const oldContext = this.state.context; 4795 this.state.context = [oldContext[0]]; 4796 4797 try { 4798 return cb(); 4799 } finally { 4800 this.state.context = oldContext; 4801 } 4802 } 4803 4804 tsInType(cb) { 4805 const oldInType = this.state.inType; 4806 this.state.inType = true; 4807 4808 try { 4809 return cb(); 4810 } finally { 4811 this.state.inType = oldInType; 4812 } 4813 } 4814 4815 tsEatThenParseType(token) { 4816 return !this.match(token) ? undefined : this.tsNextThenParseType(); 4817 } 4818 4819 tsExpectThenParseType(token) { 4820 return this.tsDoThenParseType(() => this.expect(token)); 4821 } 4822 4823 tsNextThenParseType() { 4824 return this.tsDoThenParseType(() => this.next()); 4825 } 4826 4827 tsDoThenParseType(cb) { 4828 return this.tsInType(() => { 4829 cb(); 4830 return this.tsParseType(); 4831 }); 4832 } 4833 4834 tsParseEnumMember() { 4835 const node = this.startNode(); 4836 node.id = this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); 4837 4838 if (this.eat(types.eq)) { 4839 node.initializer = this.parseMaybeAssign(); 4840 } 4841 4842 return this.finishNode(node, "TSEnumMember"); 4843 } 4844 4845 tsParseEnumDeclaration(node, isConst) { 4846 if (isConst) node.const = true; 4847 node.id = this.parseIdentifier(); 4848 this.checkLVal(node.id, isConst ? BIND_TS_CONST_ENUM : BIND_TS_ENUM, undefined, "typescript enum declaration"); 4849 this.expect(types.braceL); 4850 node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this)); 4851 this.expect(types.braceR); 4852 return this.finishNode(node, "TSEnumDeclaration"); 4853 } 4854 4855 tsParseModuleBlock() { 4856 const node = this.startNode(); 4857 this.scope.enter(SCOPE_OTHER); 4858 this.expect(types.braceL); 4859 this.parseBlockOrModuleBlockBody(node.body = [], undefined, true, types.braceR); 4860 this.scope.exit(); 4861 return this.finishNode(node, "TSModuleBlock"); 4862 } 4863 4864 tsParseModuleOrNamespaceDeclaration(node, nested = false) { 4865 node.id = this.parseIdentifier(); 4866 4867 if (!nested) { 4868 this.checkLVal(node.id, BIND_TS_NAMESPACE, null, "module or namespace declaration"); 4869 } 4870 4871 if (this.eat(types.dot)) { 4872 const inner = this.startNode(); 4873 this.tsParseModuleOrNamespaceDeclaration(inner, true); 4874 node.body = inner; 4875 } else { 4876 node.body = this.tsParseModuleBlock(); 4877 } 4878 4879 return this.finishNode(node, "TSModuleDeclaration"); 4880 } 4881 4882 tsParseAmbientExternalModuleDeclaration(node) { 4883 if (this.isContextual("global")) { 4884 node.global = true; 4885 node.id = this.parseIdentifier(); 4886 } else if (this.match(types.string)) { 4887 node.id = this.parseExprAtom(); 4888 } else { 4889 this.unexpected(); 4890 } 4891 4892 if (this.match(types.braceL)) { 4893 node.body = this.tsParseModuleBlock(); 4894 } else { 4895 this.semicolon(); 4896 } 4897 4898 return this.finishNode(node, "TSModuleDeclaration"); 4899 } 4900 4901 tsParseImportEqualsDeclaration(node, isExport) { 4902 node.isExport = isExport || false; 4903 node.id = this.parseIdentifier(); 4904 this.expect(types.eq); 4905 node.moduleReference = this.tsParseModuleReference(); 4906 this.semicolon(); 4907 return this.finishNode(node, "TSImportEqualsDeclaration"); 4908 } 4909 4910 tsIsExternalModuleReference() { 4911 return this.isContextual("require") && this.lookahead().type === types.parenL; 4912 } 4913 4914 tsParseModuleReference() { 4915 return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(false); 4916 } 4917 4918 tsParseExternalModuleReference() { 4919 const node = this.startNode(); 4920 this.expectContextual("require"); 4921 this.expect(types.parenL); 4922 4923 if (!this.match(types.string)) { 4924 throw this.unexpected(); 4925 } 4926 4927 node.expression = this.parseExprAtom(); 4928 this.expect(types.parenR); 4929 return this.finishNode(node, "TSExternalModuleReference"); 4930 } 4931 4932 tsLookAhead(f) { 4933 const state = this.state.clone(); 4934 const res = f(); 4935 this.state = state; 4936 return res; 4937 } 4938 4939 tsTryParseAndCatch(f) { 4940 const state = this.state.clone(); 4941 4942 try { 4943 return f(); 4944 } catch (e) { 4945 if (e instanceof SyntaxError) { 4946 this.state = state; 4947 return undefined; 4948 } 4949 4950 throw e; 4951 } 4952 } 4953 4954 tsTryParse(f) { 4955 const state = this.state.clone(); 4956 const result = f(); 4957 4958 if (result !== undefined && result !== false) { 4959 return result; 4960 } else { 4961 this.state = state; 4962 return undefined; 4963 } 4964 } 4965 4966 tsTryParseDeclare(nany) { 4967 if (this.isLineTerminator()) { 4968 return; 4969 } 4970 4971 let starttype = this.state.type; 4972 let kind; 4973 4974 if (this.isContextual("let")) { 4975 starttype = types._var; 4976 kind = "let"; 4977 } 4978 4979 switch (starttype) { 4980 case types._function: 4981 return this.parseFunctionStatement(nany, false, true); 4982 4983 case types._class: 4984 return this.parseClass(nany, true, false); 4985 4986 case types._const: 4987 if (this.match(types._const) && this.isLookaheadContextual("enum")) { 4988 this.expect(types._const); 4989 this.expectContextual("enum"); 4990 return this.tsParseEnumDeclaration(nany, true); 4991 } 4992 4993 case types._var: 4994 kind = kind || this.state.value; 4995 return this.parseVarStatement(nany, kind); 4996 4997 case types.name: 4998 { 4999 const value = this.state.value; 5000 5001 if (value === "global") { 5002 return this.tsParseAmbientExternalModuleDeclaration(nany); 5003 } else { 5004 return this.tsParseDeclaration(nany, value, true); 5005 } 5006 } 5007 } 5008 } 5009 5010 tsTryParseExportDeclaration() { 5011 return this.tsParseDeclaration(this.startNode(), this.state.value, true); 5012 } 5013 5014 tsParseExpressionStatement(node, expr) { 5015 switch (expr.name) { 5016 case "declare": 5017 { 5018 const declaration = this.tsTryParseDeclare(node); 5019 5020 if (declaration) { 5021 declaration.declare = true; 5022 return declaration; 5023 } 5024 5025 break; 5026 } 5027 5028 case "global": 5029 if (this.match(types.braceL)) { 5030 const mod = node; 5031 mod.global = true; 5032 mod.id = expr; 5033 mod.body = this.tsParseModuleBlock(); 5034 return this.finishNode(mod, "TSModuleDeclaration"); 5035 } 5036 5037 break; 5038 5039 default: 5040 return this.tsParseDeclaration(node, expr.name, false); 5041 } 5042 } 5043 5044 tsParseDeclaration(node, value, next) { 5045 switch (value) { 5046 case "abstract": 5047 if (this.tsCheckLineTerminatorAndMatch(types._class, next)) { 5048 const cls = node; 5049 cls.abstract = true; 5050 5051 if (next) { 5052 this.next(); 5053 5054 if (!this.match(types._class)) { 5055 this.unexpected(null, types._class); 5056 } 5057 } 5058 5059 return this.parseClass(cls, true, false); 5060 } 5061 5062 break; 5063 5064 case "enum": 5065 if (next || this.match(types.name)) { 5066 if (next) this.next(); 5067 return this.tsParseEnumDeclaration(node, false); 5068 } 5069 5070 break; 5071 5072 case "interface": 5073 if (this.tsCheckLineTerminatorAndMatch(types.name, next)) { 5074 if (next) this.next(); 5075 return this.tsParseInterfaceDeclaration(node); 5076 } 5077 5078 break; 5079 5080 case "module": 5081 if (next) this.next(); 5082 5083 if (this.match(types.string)) { 5084 return this.tsParseAmbientExternalModuleDeclaration(node); 5085 } else if (this.tsCheckLineTerminatorAndMatch(types.name, next)) { 5086 return this.tsParseModuleOrNamespaceDeclaration(node); 5087 } 5088 5089 break; 5090 5091 case "namespace": 5092 if (this.tsCheckLineTerminatorAndMatch(types.name, next)) { 5093 if (next) this.next(); 5094 return this.tsParseModuleOrNamespaceDeclaration(node); 5095 } 5096 5097 break; 5098 5099 case "type": 5100 if (this.tsCheckLineTerminatorAndMatch(types.name, next)) { 5101 if (next) this.next(); 5102 return this.tsParseTypeAliasDeclaration(node); 5103 } 5104 5105 break; 5106 } 5107 } 5108 5109 tsCheckLineTerminatorAndMatch(tokenType, next) { 5110 return (next || this.match(tokenType)) && !this.isLineTerminator(); 5111 } 5112 5113 tsTryParseGenericAsyncArrowFunction(startPos, startLoc) { 5114 if (!this.isRelational("<")) { 5115 return undefined; 5116 } 5117 5118 const res = this.tsTryParseAndCatch(() => { 5119 const node = this.startNodeAt(startPos, startLoc); 5120 node.typeParameters = this.tsParseTypeParameters(); 5121 super.parseFunctionParams(node); 5122 node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation(); 5123 this.expect(types.arrow); 5124 return node; 5125 }); 5126 5127 if (!res) { 5128 return undefined; 5129 } 5130 5131 return this.parseArrowExpression(res, null, true); 5132 } 5133 5134 tsParseTypeArguments() { 5135 const node = this.startNode(); 5136 node.params = this.tsInType(() => this.tsInNoContext(() => { 5137 this.expectRelational("<"); 5138 return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this)); 5139 })); 5140 this.state.exprAllowed = false; 5141 this.expectRelational(">"); 5142 return this.finishNode(node, "TSTypeParameterInstantiation"); 5143 } 5144 5145 tsIsDeclarationStart() { 5146 if (this.match(types.name)) { 5147 switch (this.state.value) { 5148 case "abstract": 5149 case "declare": 5150 case "enum": 5151 case "interface": 5152 case "module": 5153 case "namespace": 5154 case "type": 5155 return true; 5156 } 5157 } 5158 5159 return false; 5160 } 5161 5162 isExportDefaultSpecifier() { 5163 if (this.tsIsDeclarationStart()) return false; 5164 return super.isExportDefaultSpecifier(); 5165 } 5166 5167 parseAssignableListItem(allowModifiers, decorators) { 5168 const startPos = this.state.start; 5169 const startLoc = this.state.startLoc; 5170 let accessibility; 5171 let readonly = false; 5172 5173 if (allowModifiers) { 5174 accessibility = this.parseAccessModifier(); 5175 readonly = !!this.tsParseModifier(["readonly"]); 5176 } 5177 5178 const left = this.parseMaybeDefault(); 5179 this.parseAssignableListItemTypes(left); 5180 const elt = this.parseMaybeDefault(left.start, left.loc.start, left); 5181 5182 if (accessibility || readonly) { 5183 const pp = this.startNodeAt(startPos, startLoc); 5184 5185 if (decorators.length) { 5186 pp.decorators = decorators; 5187 } 5188 5189 if (accessibility) pp.accessibility = accessibility; 5190 if (readonly) pp.readonly = readonly; 5191 5192 if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") { 5193 throw this.raise(pp.start, "A parameter property may not be declared using a binding pattern."); 5194 } 5195 5196 pp.parameter = elt; 5197 return this.finishNode(pp, "TSParameterProperty"); 5198 } 5199 5200 if (decorators.length) { 5201 left.decorators = decorators; 5202 } 5203 5204 return elt; 5205 } 5206 5207 parseFunctionBodyAndFinish(node, type, isMethod = false) { 5208 if (this.match(types.colon)) { 5209 node.returnType = this.tsParseTypeOrTypePredicateAnnotation(types.colon); 5210 } 5211 5212 const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" ? "TSDeclareMethod" : undefined; 5213 5214 if (bodilessType && !this.match(types.braceL) && this.isLineTerminator()) { 5215 this.finishNode(node, bodilessType); 5216 return; 5217 } 5218 5219 super.parseFunctionBodyAndFinish(node, type, isMethod); 5220 } 5221 5222 checkFunctionStatementId(node) { 5223 if (!node.body && node.id) { 5224 this.checkLVal(node.id, BIND_TS_FN_TYPE, null, "function name"); 5225 } else { 5226 super.checkFunctionStatementId(...arguments); 5227 } 5228 } 5229 5230 parseSubscript(base, startPos, startLoc, noCalls, state, maybeAsyncArrow) { 5231 if (!this.hasPrecedingLineBreak() && this.match(types.bang)) { 5232 this.state.exprAllowed = false; 5233 this.next(); 5234 const nonNullExpression = this.startNodeAt(startPos, startLoc); 5235 nonNullExpression.expression = base; 5236 return this.finishNode(nonNullExpression, "TSNonNullExpression"); 5237 } 5238 5239 if (this.isRelational("<")) { 5240 const result = this.tsTryParseAndCatch(() => { 5241 if (!noCalls && this.atPossibleAsync(base)) { 5242 const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startPos, startLoc); 5243 5244 if (asyncArrowFn) { 5245 return asyncArrowFn; 5246 } 5247 } 5248 5249 const node = this.startNodeAt(startPos, startLoc); 5250 node.callee = base; 5251 const typeArguments = this.tsParseTypeArguments(); 5252 5253 if (typeArguments) { 5254 if (!noCalls && this.eat(types.parenL)) { 5255 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 5256 node.typeParameters = typeArguments; 5257 return this.finishCallExpression(node); 5258 } else if (this.match(types.backQuote)) { 5259 return this.parseTaggedTemplateExpression(startPos, startLoc, base, state, typeArguments); 5260 } 5261 } 5262 5263 this.unexpected(); 5264 }); 5265 if (result) return result; 5266 } 5267 5268 return super.parseSubscript(base, startPos, startLoc, noCalls, state, maybeAsyncArrow); 5269 } 5270 5271 parseNewArguments(node) { 5272 if (this.isRelational("<")) { 5273 const typeParameters = this.tsTryParseAndCatch(() => { 5274 const args = this.tsParseTypeArguments(); 5275 if (!this.match(types.parenL)) this.unexpected(); 5276 return args; 5277 }); 5278 5279 if (typeParameters) { 5280 node.typeParameters = typeParameters; 5281 } 5282 } 5283 5284 super.parseNewArguments(node); 5285 } 5286 5287 parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { 5288 if (nonNull(types._in.binop) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual("as")) { 5289 const node = this.startNodeAt(leftStartPos, leftStartLoc); 5290 node.expression = left; 5291 5292 const _const = this.tsTryNextParseConstantContext(); 5293 5294 if (_const) { 5295 node.typeAnnotation = _const; 5296 } else { 5297 node.typeAnnotation = this.tsNextThenParseType(); 5298 } 5299 5300 this.finishNode(node, "TSAsExpression"); 5301 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); 5302 } 5303 5304 return super.parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn); 5305 } 5306 5307 checkReservedWord(word, startLoc, checkKeywords, isBinding) {} 5308 5309 checkDuplicateExports() {} 5310 5311 parseImport(node) { 5312 if (this.match(types.name) && this.lookahead().type === types.eq) { 5313 return this.tsParseImportEqualsDeclaration(node); 5314 } 5315 5316 return super.parseImport(node); 5317 } 5318 5319 parseExport(node) { 5320 if (this.match(types._import)) { 5321 this.expect(types._import); 5322 return this.tsParseImportEqualsDeclaration(node, true); 5323 } else if (this.eat(types.eq)) { 5324 const assign = node; 5325 assign.expression = this.parseExpression(); 5326 this.semicolon(); 5327 return this.finishNode(assign, "TSExportAssignment"); 5328 } else if (this.eatContextual("as")) { 5329 const decl = node; 5330 this.expectContextual("namespace"); 5331 decl.id = this.parseIdentifier(); 5332 this.semicolon(); 5333 return this.finishNode(decl, "TSNamespaceExportDeclaration"); 5334 } else { 5335 return super.parseExport(node); 5336 } 5337 } 5338 5339 isAbstractClass() { 5340 return this.isContextual("abstract") && this.lookahead().type === types._class; 5341 } 5342 5343 parseExportDefaultExpression() { 5344 if (this.isAbstractClass()) { 5345 const cls = this.startNode(); 5346 this.next(); 5347 this.parseClass(cls, true, true); 5348 cls.abstract = true; 5349 return cls; 5350 } 5351 5352 if (this.state.value === "interface") { 5353 const result = this.tsParseDeclaration(this.startNode(), this.state.value, true); 5354 if (result) return result; 5355 } 5356 5357 return super.parseExportDefaultExpression(); 5358 } 5359 5360 parseStatementContent(context, topLevel) { 5361 if (this.state.type === types._const) { 5362 const ahead = this.lookahead(); 5363 5364 if (ahead.type === types.name && ahead.value === "enum") { 5365 const node = this.startNode(); 5366 this.expect(types._const); 5367 this.expectContextual("enum"); 5368 return this.tsParseEnumDeclaration(node, true); 5369 } 5370 } 5371 5372 return super.parseStatementContent(context, topLevel); 5373 } 5374 5375 parseAccessModifier() { 5376 return this.tsParseModifier(["public", "protected", "private"]); 5377 } 5378 5379 parseClassMember(classBody, member, state, constructorAllowsSuper) { 5380 const accessibility = this.parseAccessModifier(); 5381 if (accessibility) member.accessibility = accessibility; 5382 super.parseClassMember(classBody, member, state, constructorAllowsSuper); 5383 } 5384 5385 parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) { 5386 const methodOrProp = member; 5387 const prop = member; 5388 const propOrIdx = member; 5389 let abstract = false, 5390 readonly = false; 5391 const mod = this.tsParseModifier(["abstract", "readonly"]); 5392 5393 switch (mod) { 5394 case "readonly": 5395 readonly = true; 5396 abstract = !!this.tsParseModifier(["abstract"]); 5397 break; 5398 5399 case "abstract": 5400 abstract = true; 5401 readonly = !!this.tsParseModifier(["readonly"]); 5402 break; 5403 } 5404 5405 if (abstract) methodOrProp.abstract = true; 5406 if (readonly) propOrIdx.readonly = true; 5407 5408 if (!abstract && !isStatic && !methodOrProp.accessibility) { 5409 const idx = this.tsTryParseIndexSignature(member); 5410 5411 if (idx) { 5412 classBody.body.push(idx); 5413 return; 5414 } 5415 } 5416 5417 if (readonly) { 5418 methodOrProp.static = isStatic; 5419 this.parseClassPropertyName(prop); 5420 this.parsePostMemberNameModifiers(methodOrProp); 5421 this.pushClassProperty(classBody, prop); 5422 return; 5423 } 5424 5425 super.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper); 5426 } 5427 5428 parsePostMemberNameModifiers(methodOrProp) { 5429 const optional = this.eat(types.question); 5430 if (optional) methodOrProp.optional = true; 5431 } 5432 5433 parseExpressionStatement(node, expr) { 5434 const decl = expr.type === "Identifier" ? this.tsParseExpressionStatement(node, expr) : undefined; 5435 return decl || super.parseExpressionStatement(node, expr); 5436 } 5437 5438 shouldParseExportDeclaration() { 5439 if (this.tsIsDeclarationStart()) return true; 5440 return super.shouldParseExportDeclaration(); 5441 } 5442 5443 parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { 5444 if (!refNeedsArrowPos || !this.match(types.question)) { 5445 return super.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); 5446 } 5447 5448 const state = this.state.clone(); 5449 5450 try { 5451 return super.parseConditional(expr, noIn, startPos, startLoc); 5452 } catch (err) { 5453 if (!(err instanceof SyntaxError)) { 5454 throw err; 5455 } 5456 5457 this.state = state; 5458 refNeedsArrowPos.start = err.pos || this.state.start; 5459 return expr; 5460 } 5461 } 5462 5463 parseParenItem(node, startPos, startLoc) { 5464 node = super.parseParenItem(node, startPos, startLoc); 5465 5466 if (this.eat(types.question)) { 5467 node.optional = true; 5468 this.resetEndLocation(node); 5469 } 5470 5471 if (this.match(types.colon)) { 5472 const typeCastNode = this.startNodeAt(startPos, startLoc); 5473 typeCastNode.expression = node; 5474 typeCastNode.typeAnnotation = this.tsParseTypeAnnotation(); 5475 return this.finishNode(typeCastNode, "TSTypeCastExpression"); 5476 } 5477 5478 return node; 5479 } 5480 5481 parseExportDeclaration(node) { 5482 const startPos = this.state.start; 5483 const startLoc = this.state.startLoc; 5484 const isDeclare = this.eatContextual("declare"); 5485 let declaration; 5486 5487 if (this.match(types.name)) { 5488 declaration = this.tsTryParseExportDeclaration(); 5489 } 5490 5491 if (!declaration) { 5492 declaration = super.parseExportDeclaration(node); 5493 } 5494 5495 if (declaration && isDeclare) { 5496 this.resetStartLocation(declaration, startPos, startLoc); 5497 declaration.declare = true; 5498 } 5499 5500 return declaration; 5501 } 5502 5503 parseClassId(node, isStatement, optionalId) { 5504 if ((!isStatement || optionalId) && this.isContextual("implements")) { 5505 return; 5506 } 5507 5508 super.parseClassId(...arguments); 5509 const typeParameters = this.tsTryParseTypeParameters(); 5510 if (typeParameters) node.typeParameters = typeParameters; 5511 } 5512 5513 parseClassProperty(node) { 5514 if (!node.optional && this.eat(types.bang)) { 5515 node.definite = true; 5516 } 5517 5518 const type = this.tsTryParseTypeAnnotation(); 5519 if (type) node.typeAnnotation = type; 5520 return super.parseClassProperty(node); 5521 } 5522 5523 pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { 5524 const typeParameters = this.tsTryParseTypeParameters(); 5525 if (typeParameters) method.typeParameters = typeParameters; 5526 super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); 5527 } 5528 5529 pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { 5530 const typeParameters = this.tsTryParseTypeParameters(); 5531 if (typeParameters) method.typeParameters = typeParameters; 5532 super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); 5533 } 5534 5535 parseClassSuper(node) { 5536 super.parseClassSuper(node); 5537 5538 if (node.superClass && this.isRelational("<")) { 5539 node.superTypeParameters = this.tsParseTypeArguments(); 5540 } 5541 5542 if (this.eatContextual("implements")) { 5543 node.implements = this.tsParseHeritageClause("implements"); 5544 } 5545 } 5546 5547 parseObjPropValue(prop, ...args) { 5548 const typeParameters = this.tsTryParseTypeParameters(); 5549 if (typeParameters) prop.typeParameters = typeParameters; 5550 super.parseObjPropValue(prop, ...args); 5551 } 5552 5553 parseFunctionParams(node, allowModifiers) { 5554 const typeParameters = this.tsTryParseTypeParameters(); 5555 if (typeParameters) node.typeParameters = typeParameters; 5556 super.parseFunctionParams(node, allowModifiers); 5557 } 5558 5559 parseVarId(decl, kind) { 5560 super.parseVarId(decl, kind); 5561 5562 if (decl.id.type === "Identifier" && this.eat(types.bang)) { 5563 decl.definite = true; 5564 } 5565 5566 const type = this.tsTryParseTypeAnnotation(); 5567 5568 if (type) { 5569 decl.id.typeAnnotation = type; 5570 this.resetEndLocation(decl.id); 5571 } 5572 } 5573 5574 parseAsyncArrowFromCallExpression(node, call) { 5575 if (this.match(types.colon)) { 5576 node.returnType = this.tsParseTypeAnnotation(); 5577 } 5578 5579 return super.parseAsyncArrowFromCallExpression(node, call); 5580 } 5581 5582 parseMaybeAssign(...args) { 5583 let jsxError; 5584 5585 if (this.match(types.jsxTagStart)) { 5586 const context = this.curContext(); 5587 assert(context === types$1.j_oTag); 5588 assert(this.state.context[this.state.context.length - 2] === types$1.j_expr); 5589 const state = this.state.clone(); 5590 5591 try { 5592 return super.parseMaybeAssign(...args); 5593 } catch (err) { 5594 if (!(err instanceof SyntaxError)) { 5595 throw err; 5596 } 5597 5598 this.state = state; 5599 assert(this.curContext() === types$1.j_oTag); 5600 this.state.context.pop(); 5601 assert(this.curContext() === types$1.j_expr); 5602 this.state.context.pop(); 5603 jsxError = err; 5604 } 5605 } 5606 5607 if (jsxError === undefined && !this.isRelational("<")) { 5608 return super.parseMaybeAssign(...args); 5609 } 5610 5611 let arrowExpression; 5612 let typeParameters; 5613 const state = this.state.clone(); 5614 5615 try { 5616 typeParameters = this.tsParseTypeParameters(); 5617 arrowExpression = super.parseMaybeAssign(...args); 5618 5619 if (arrowExpression.type !== "ArrowFunctionExpression" || arrowExpression.extra && arrowExpression.extra.parenthesized) { 5620 this.unexpected(); 5621 } 5622 } catch (err) { 5623 if (!(err instanceof SyntaxError)) { 5624 throw err; 5625 } 5626 5627 if (jsxError) { 5628 throw jsxError; 5629 } 5630 5631 assert(!this.hasPlugin("jsx")); 5632 this.state = state; 5633 return super.parseMaybeAssign(...args); 5634 } 5635 5636 if (typeParameters && typeParameters.params.length !== 0) { 5637 this.resetStartLocationFromNode(arrowExpression, typeParameters); 5638 } 5639 5640 arrowExpression.typeParameters = typeParameters; 5641 return arrowExpression; 5642 } 5643 5644 parseMaybeUnary(refShorthandDefaultPos) { 5645 if (!this.hasPlugin("jsx") && this.isRelational("<")) { 5646 return this.tsParseTypeAssertion(); 5647 } else { 5648 return super.parseMaybeUnary(refShorthandDefaultPos); 5649 } 5650 } 5651 5652 parseArrow(node) { 5653 if (this.match(types.colon)) { 5654 const state = this.state.clone(); 5655 5656 try { 5657 const returnType = this.tsParseTypeOrTypePredicateAnnotation(types.colon); 5658 5659 if (this.canInsertSemicolon() || !this.match(types.arrow)) { 5660 this.state = state; 5661 return undefined; 5662 } 5663 5664 node.returnType = returnType; 5665 } catch (err) { 5666 if (err instanceof SyntaxError) { 5667 this.state = state; 5668 } else { 5669 throw err; 5670 } 5671 } 5672 } 5673 5674 return super.parseArrow(node); 5675 } 5676 5677 parseAssignableListItemTypes(param) { 5678 if (this.eat(types.question)) { 5679 if (param.type !== "Identifier") { 5680 throw this.raise(param.start, "A binding pattern parameter cannot be optional in an implementation signature."); 5681 } 5682 5683 param.optional = true; 5684 } 5685 5686 const type = this.tsTryParseTypeAnnotation(); 5687 if (type) param.typeAnnotation = type; 5688 this.resetEndLocation(param); 5689 return param; 5690 } 5691 5692 toAssignable(node, isBinding, contextDescription) { 5693 switch (node.type) { 5694 case "TSTypeCastExpression": 5695 return super.toAssignable(this.typeCastToParameter(node), isBinding, contextDescription); 5696 5697 case "TSParameterProperty": 5698 return super.toAssignable(node, isBinding, contextDescription); 5699 5700 case "TSAsExpression": 5701 case "TSNonNullExpression": 5702 case "TSTypeAssertion": 5703 node.expression = this.toAssignable(node.expression, isBinding, contextDescription); 5704 return node; 5705 5706 default: 5707 return super.toAssignable(node, isBinding, contextDescription); 5708 } 5709 } 5710 5711 checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) { 5712 switch (expr.type) { 5713 case "TSTypeCastExpression": 5714 return; 5715 5716 case "TSParameterProperty": 5717 this.checkLVal(expr.parameter, bindingType, checkClashes, "parameter property"); 5718 return; 5719 5720 case "TSAsExpression": 5721 case "TSNonNullExpression": 5722 case "TSTypeAssertion": 5723 this.checkLVal(expr.expression, bindingType, checkClashes, contextDescription); 5724 return; 5725 5726 default: 5727 super.checkLVal(expr, bindingType, checkClashes, contextDescription); 5728 return; 5729 } 5730 } 5731 5732 parseBindingAtom() { 5733 switch (this.state.type) { 5734 case types._this: 5735 return this.parseIdentifier(true); 5736 5737 default: 5738 return super.parseBindingAtom(); 5739 } 5740 } 5741 5742 parseMaybeDecoratorArguments(expr) { 5743 if (this.isRelational("<")) { 5744 const typeArguments = this.tsParseTypeArguments(); 5745 5746 if (this.match(types.parenL)) { 5747 const call = super.parseMaybeDecoratorArguments(expr); 5748 call.typeParameters = typeArguments; 5749 return call; 5750 } 5751 5752 this.unexpected(this.state.start, types.parenL); 5753 } 5754 5755 return super.parseMaybeDecoratorArguments(expr); 5756 } 5757 5758 isClassMethod() { 5759 return this.isRelational("<") || super.isClassMethod(); 5760 } 5761 5762 isClassProperty() { 5763 return this.match(types.bang) || this.match(types.colon) || super.isClassProperty(); 5764 } 5765 5766 parseMaybeDefault(...args) { 5767 const node = super.parseMaybeDefault(...args); 5768 5769 if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { 5770 this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, " + "e.g. instead of `age = 25: number` use `age: number = 25`"); 5771 } 5772 5773 return node; 5774 } 5775 5776 getTokenFromCode(code) { 5777 if (this.state.inType && (code === 62 || code === 60)) { 5778 return this.finishOp(types.relational, 1); 5779 } else { 5780 return super.getTokenFromCode(code); 5781 } 5782 } 5783 5784 toAssignableList(exprList, isBinding, contextDescription) { 5785 for (let i = 0; i < exprList.length; i++) { 5786 const expr = exprList[i]; 5787 if (!expr) continue; 5788 5789 switch (expr.type) { 5790 case "TSTypeCastExpression": 5791 exprList[i] = this.typeCastToParameter(expr); 5792 break; 5793 5794 case "TSAsExpression": 5795 case "TSTypeAssertion": 5796 this.raise(expr.start, "Unexpected type cast in parameter position."); 5797 break; 5798 } 5799 } 5800 5801 return super.toAssignableList(exprList, isBinding, contextDescription); 5802 } 5803 5804 typeCastToParameter(node) { 5805 node.expression.typeAnnotation = node.typeAnnotation; 5806 this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); 5807 return node.expression; 5808 } 5809 5810 toReferencedList(exprList, isInParens) { 5811 for (let i = 0; i < exprList.length; i++) { 5812 const expr = exprList[i]; 5813 5814 if (expr && expr._exprListItem && expr.type === "TsTypeCastExpression") { 5815 this.raise(expr.start, "Did not expect a type annotation here."); 5816 } 5817 } 5818 5819 return exprList; 5820 } 5821 5822 shouldParseArrow() { 5823 return this.match(types.colon) || super.shouldParseArrow(); 5824 } 5825 5826 shouldParseAsyncArrow() { 5827 return this.match(types.colon) || super.shouldParseAsyncArrow(); 5828 } 5829 5830 canHaveLeadingDecorator() { 5831 return super.canHaveLeadingDecorator() || this.isAbstractClass(); 5832 } 5833 5834 jsxParseOpeningElementAfterName(node) { 5835 if (this.isRelational("<")) { 5836 const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArguments()); 5837 if (typeArguments) node.typeParameters = typeArguments; 5838 } 5839 5840 return super.jsxParseOpeningElementAfterName(node); 5841 } 5842 5843 getGetterSetterExpectedParamCount(method) { 5844 const baseCount = super.getGetterSetterExpectedParamCount(method); 5845 const firstParam = method.params[0]; 5846 const hasContextParam = firstParam && firstParam.type === "Identifier" && firstParam.name === "this"; 5847 return hasContextParam ? baseCount + 1 : baseCount; 5848 } 5849 5850}); 5851 5852types.placeholder = new TokenType("%%", { 5853 startsExpr: true 5854}); 5855var placeholders = (superClass => class extends superClass { 5856 parsePlaceholder(expectedNode) { 5857 if (this.match(types.placeholder)) { 5858 const node = this.startNode(); 5859 this.next(); 5860 this.assertNoSpace("Unexpected space in placeholder."); 5861 node.name = super.parseIdentifier(true); 5862 this.assertNoSpace("Unexpected space in placeholder."); 5863 this.expect(types.placeholder); 5864 return this.finishPlaceholder(node, expectedNode); 5865 } 5866 } 5867 5868 finishPlaceholder(node, expectedNode) { 5869 const isFinished = !!(node.expectedNode && node.type === "Placeholder"); 5870 node.expectedNode = expectedNode; 5871 return isFinished ? node : this.finishNode(node, "Placeholder"); 5872 } 5873 5874 getTokenFromCode(code) { 5875 if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) { 5876 return this.finishOp(types.placeholder, 2); 5877 } 5878 5879 return super.getTokenFromCode(...arguments); 5880 } 5881 5882 parseExprAtom() { 5883 return this.parsePlaceholder("Expression") || super.parseExprAtom(...arguments); 5884 } 5885 5886 parseIdentifier() { 5887 return this.parsePlaceholder("Identifier") || super.parseIdentifier(...arguments); 5888 } 5889 5890 checkReservedWord(word) { 5891 if (word !== undefined) super.checkReservedWord(...arguments); 5892 } 5893 5894 parseBindingAtom() { 5895 return this.parsePlaceholder("Pattern") || super.parseBindingAtom(...arguments); 5896 } 5897 5898 checkLVal(expr) { 5899 if (expr.type !== "Placeholder") super.checkLVal(...arguments); 5900 } 5901 5902 toAssignable(node) { 5903 if (node && node.type === "Placeholder" && node.expectedNode === "Expression") { 5904 node.expectedNode = "Pattern"; 5905 return node; 5906 } 5907 5908 return super.toAssignable(...arguments); 5909 } 5910 5911 verifyBreakContinue(node) { 5912 if (node.label && node.label.type === "Placeholder") return; 5913 super.verifyBreakContinue(...arguments); 5914 } 5915 5916 parseExpressionStatement(node, expr) { 5917 if (expr.type !== "Placeholder" || expr.extra && expr.extra.parenthesized) { 5918 return super.parseExpressionStatement(...arguments); 5919 } 5920 5921 if (this.match(types.colon)) { 5922 const stmt = node; 5923 stmt.label = this.finishPlaceholder(expr, "Identifier"); 5924 this.next(); 5925 stmt.body = this.parseStatement("label"); 5926 return this.finishNode(stmt, "LabeledStatement"); 5927 } 5928 5929 this.semicolon(); 5930 node.name = expr.name; 5931 return this.finishPlaceholder(node, "Statement"); 5932 } 5933 5934 parseBlock() { 5935 return this.parsePlaceholder("BlockStatement") || super.parseBlock(...arguments); 5936 } 5937 5938 parseFunctionId() { 5939 return this.parsePlaceholder("Identifier") || super.parseFunctionId(...arguments); 5940 } 5941 5942 parseClass(node, isStatement, optionalId) { 5943 const type = isStatement ? "ClassDeclaration" : "ClassExpression"; 5944 this.next(); 5945 this.takeDecorators(node); 5946 const placeholder = this.parsePlaceholder("Identifier"); 5947 5948 if (placeholder) { 5949 if (this.match(types._extends) || this.match(types.placeholder) || this.match(types.braceL)) { 5950 node.id = placeholder; 5951 } else if (optionalId || !isStatement) { 5952 node.id = null; 5953 node.body = this.finishPlaceholder(placeholder, "ClassBody"); 5954 return this.finishNode(node, type); 5955 } else { 5956 this.unexpected(null, "A class name is required"); 5957 } 5958 } else { 5959 this.parseClassId(node, isStatement, optionalId); 5960 } 5961 5962 this.parseClassSuper(node); 5963 node.body = this.parsePlaceholder("ClassBody") || this.parseClassBody(!!node.superClass); 5964 return this.finishNode(node, type); 5965 } 5966 5967 parseExport(node) { 5968 const placeholder = this.parsePlaceholder("Identifier"); 5969 if (!placeholder) return super.parseExport(...arguments); 5970 5971 if (!this.isContextual("from") && !this.match(types.comma)) { 5972 node.specifiers = []; 5973 node.source = null; 5974 node.declaration = this.finishPlaceholder(placeholder, "Declaration"); 5975 return this.finishNode(node, "ExportNamedDeclaration"); 5976 } 5977 5978 this.expectPlugin("exportDefaultFrom"); 5979 const specifier = this.startNode(); 5980 specifier.exported = placeholder; 5981 node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; 5982 return super.parseExport(node); 5983 } 5984 5985 maybeParseExportDefaultSpecifier(node) { 5986 if (node.specifiers && node.specifiers.length > 0) { 5987 return true; 5988 } 5989 5990 return super.maybeParseExportDefaultSpecifier(...arguments); 5991 } 5992 5993 checkExport(node) { 5994 const { 5995 specifiers 5996 } = node; 5997 5998 if (specifiers && specifiers.length) { 5999 node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder"); 6000 } 6001 6002 super.checkExport(node); 6003 node.specifiers = specifiers; 6004 } 6005 6006 parseImport(node) { 6007 const placeholder = this.parsePlaceholder("Identifier"); 6008 if (!placeholder) return super.parseImport(...arguments); 6009 node.specifiers = []; 6010 6011 if (!this.isContextual("from") && !this.match(types.comma)) { 6012 node.source = this.finishPlaceholder(placeholder, "StringLiteral"); 6013 this.semicolon(); 6014 return this.finishNode(node, "ImportDeclaration"); 6015 } 6016 6017 const specifier = this.startNodeAtNode(placeholder); 6018 specifier.local = placeholder; 6019 this.finishNode(specifier, "ImportDefaultSpecifier"); 6020 node.specifiers.push(specifier); 6021 6022 if (this.eat(types.comma)) { 6023 const hasStarImport = this.maybeParseStarImportSpecifier(node); 6024 if (!hasStarImport) this.parseNamedImportSpecifiers(node); 6025 } 6026 6027 this.expectContextual("from"); 6028 node.source = this.parseImportSource(); 6029 this.semicolon(); 6030 return this.finishNode(node, "ImportDeclaration"); 6031 } 6032 6033 parseImportSource() { 6034 return this.parsePlaceholder("StringLiteral") || super.parseImportSource(...arguments); 6035 } 6036 6037}); 6038 6039function hasPlugin(plugins, name) { 6040 return plugins.some(plugin => { 6041 if (Array.isArray(plugin)) { 6042 return plugin[0] === name; 6043 } else { 6044 return plugin === name; 6045 } 6046 }); 6047} 6048function getPluginOption(plugins, name, option) { 6049 const plugin = plugins.find(plugin => { 6050 if (Array.isArray(plugin)) { 6051 return plugin[0] === name; 6052 } else { 6053 return plugin === name; 6054 } 6055 }); 6056 6057 if (plugin && Array.isArray(plugin)) { 6058 return plugin[1][option]; 6059 } 6060 6061 return null; 6062} 6063const PIPELINE_PROPOSALS = ["minimal", "smart", "fsharp"]; 6064function validatePlugins(plugins) { 6065 if (hasPlugin(plugins, "decorators")) { 6066 if (hasPlugin(plugins, "decorators-legacy")) { 6067 throw new Error("Cannot use the decorators and decorators-legacy plugin together"); 6068 } 6069 6070 const decoratorsBeforeExport = getPluginOption(plugins, "decorators", "decoratorsBeforeExport"); 6071 6072 if (decoratorsBeforeExport == null) { 6073 throw new Error("The 'decorators' plugin requires a 'decoratorsBeforeExport' option," + " whose value must be a boolean. If you are migrating from" + " Babylon/Babel 6 or want to use the old decorators proposal, you" + " should use the 'decorators-legacy' plugin instead of 'decorators'."); 6074 } else if (typeof decoratorsBeforeExport !== "boolean") { 6075 throw new Error("'decoratorsBeforeExport' must be a boolean."); 6076 } 6077 } 6078 6079 if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) { 6080 throw new Error("Cannot combine flow and typescript plugins."); 6081 } 6082 6083 if (hasPlugin(plugins, "pipelineOperator") && !PIPELINE_PROPOSALS.includes(getPluginOption(plugins, "pipelineOperator", "proposal"))) { 6084 throw new Error("'pipelineOperator' requires 'proposal' option whose value should be one of: " + PIPELINE_PROPOSALS.map(p => `'${p}'`).join(", ")); 6085 } 6086} 6087const mixinPlugins = { 6088 estree, 6089 jsx, 6090 flow, 6091 typescript, 6092 placeholders 6093}; 6094const mixinPluginNames = Object.keys(mixinPlugins); 6095 6096const defaultOptions = { 6097 sourceType: "script", 6098 sourceFilename: undefined, 6099 startLine: 1, 6100 allowAwaitOutsideFunction: false, 6101 allowReturnOutsideFunction: false, 6102 allowImportExportEverywhere: false, 6103 allowSuperOutsideMethod: false, 6104 allowUndeclaredExports: false, 6105 plugins: [], 6106 strictMode: null, 6107 ranges: false, 6108 tokens: false, 6109 createParenthesizedExpressions: false 6110}; 6111function getOptions(opts) { 6112 const options = {}; 6113 6114 for (let _i = 0, _Object$keys = Object.keys(defaultOptions); _i < _Object$keys.length; _i++) { 6115 const key = _Object$keys[_i]; 6116 options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key]; 6117 } 6118 6119 return options; 6120} 6121 6122class Position { 6123 constructor(line, col) { 6124 this.line = line; 6125 this.column = col; 6126 } 6127 6128} 6129class SourceLocation { 6130 constructor(start, end) { 6131 this.start = start; 6132 this.end = end; 6133 } 6134 6135} 6136function getLineInfo(input, offset) { 6137 let line = 1; 6138 let lineStart = 0; 6139 let match; 6140 lineBreakG.lastIndex = 0; 6141 6142 while ((match = lineBreakG.exec(input)) && match.index < offset) { 6143 line++; 6144 lineStart = lineBreakG.lastIndex; 6145 } 6146 6147 return new Position(line, offset - lineStart); 6148} 6149 6150class BaseParser { 6151 constructor() { 6152 this.sawUnambiguousESM = false; 6153 } 6154 6155 hasPlugin(name) { 6156 return this.plugins.has(name); 6157 } 6158 6159 getPluginOption(plugin, name) { 6160 if (this.hasPlugin(plugin)) return this.plugins.get(plugin)[name]; 6161 } 6162 6163} 6164 6165function last(stack) { 6166 return stack[stack.length - 1]; 6167} 6168 6169class CommentsParser extends BaseParser { 6170 addComment(comment) { 6171 if (this.filename) comment.loc.filename = this.filename; 6172 this.state.trailingComments.push(comment); 6173 this.state.leadingComments.push(comment); 6174 } 6175 6176 processComment(node) { 6177 if (node.type === "Program" && node.body.length > 0) return; 6178 const stack = this.state.commentStack; 6179 let firstChild, lastChild, trailingComments, i, j; 6180 6181 if (this.state.trailingComments.length > 0) { 6182 if (this.state.trailingComments[0].start >= node.end) { 6183 trailingComments = this.state.trailingComments; 6184 this.state.trailingComments = []; 6185 } else { 6186 this.state.trailingComments.length = 0; 6187 } 6188 } else if (stack.length > 0) { 6189 const lastInStack = last(stack); 6190 6191 if (lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) { 6192 trailingComments = lastInStack.trailingComments; 6193 delete lastInStack.trailingComments; 6194 } 6195 } 6196 6197 if (stack.length > 0 && last(stack).start >= node.start) { 6198 firstChild = stack.pop(); 6199 } 6200 6201 while (stack.length > 0 && last(stack).start >= node.start) { 6202 lastChild = stack.pop(); 6203 } 6204 6205 if (!lastChild && firstChild) lastChild = firstChild; 6206 6207 if (firstChild && this.state.leadingComments.length > 0) { 6208 const lastComment = last(this.state.leadingComments); 6209 6210 if (firstChild.type === "ObjectProperty") { 6211 if (lastComment.start >= node.start) { 6212 if (this.state.commentPreviousNode) { 6213 for (j = 0; j < this.state.leadingComments.length; j++) { 6214 if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { 6215 this.state.leadingComments.splice(j, 1); 6216 j--; 6217 } 6218 } 6219 6220 if (this.state.leadingComments.length > 0) { 6221 firstChild.trailingComments = this.state.leadingComments; 6222 this.state.leadingComments = []; 6223 } 6224 } 6225 } 6226 } else if (node.type === "CallExpression" && node.arguments && node.arguments.length) { 6227 const lastArg = last(node.arguments); 6228 6229 if (lastArg && lastComment.start >= lastArg.start && lastComment.end <= node.end) { 6230 if (this.state.commentPreviousNode) { 6231 for (j = 0; j < this.state.leadingComments.length; j++) { 6232 if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { 6233 this.state.leadingComments.splice(j, 1); 6234 j--; 6235 } 6236 } 6237 6238 if (this.state.leadingComments.length > 0) { 6239 lastArg.trailingComments = this.state.leadingComments; 6240 this.state.leadingComments = []; 6241 } 6242 } 6243 } 6244 } 6245 } 6246 6247 if (lastChild) { 6248 if (lastChild.leadingComments) { 6249 if (lastChild !== node && lastChild.leadingComments.length > 0 && last(lastChild.leadingComments).end <= node.start) { 6250 node.leadingComments = lastChild.leadingComments; 6251 delete lastChild.leadingComments; 6252 } else { 6253 for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { 6254 if (lastChild.leadingComments[i].end <= node.start) { 6255 node.leadingComments = lastChild.leadingComments.splice(0, i + 1); 6256 break; 6257 } 6258 } 6259 } 6260 } 6261 } else if (this.state.leadingComments.length > 0) { 6262 if (last(this.state.leadingComments).end <= node.start) { 6263 if (this.state.commentPreviousNode) { 6264 for (j = 0; j < this.state.leadingComments.length; j++) { 6265 if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { 6266 this.state.leadingComments.splice(j, 1); 6267 j--; 6268 } 6269 } 6270 } 6271 6272 if (this.state.leadingComments.length > 0) { 6273 node.leadingComments = this.state.leadingComments; 6274 this.state.leadingComments = []; 6275 } 6276 } else { 6277 for (i = 0; i < this.state.leadingComments.length; i++) { 6278 if (this.state.leadingComments[i].end > node.start) { 6279 break; 6280 } 6281 } 6282 6283 const leadingComments = this.state.leadingComments.slice(0, i); 6284 6285 if (leadingComments.length) { 6286 node.leadingComments = leadingComments; 6287 } 6288 6289 trailingComments = this.state.leadingComments.slice(i); 6290 6291 if (trailingComments.length === 0) { 6292 trailingComments = null; 6293 } 6294 } 6295 } 6296 6297 this.state.commentPreviousNode = node; 6298 6299 if (trailingComments) { 6300 if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) { 6301 node.innerComments = trailingComments; 6302 } else { 6303 node.trailingComments = trailingComments; 6304 } 6305 } 6306 6307 stack.push(node); 6308 } 6309 6310} 6311 6312class LocationParser extends CommentsParser { 6313 getLocationForPosition(pos) { 6314 let loc; 6315 if (pos === this.state.start) loc = this.state.startLoc;else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc;else if (pos === this.state.end) loc = this.state.endLoc;else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc;else loc = getLineInfo(this.input, pos); 6316 return loc; 6317 } 6318 6319 raise(pos, message, { 6320 missingPluginNames, 6321 code 6322 } = {}) { 6323 const loc = this.getLocationForPosition(pos); 6324 message += ` (${loc.line}:${loc.column})`; 6325 const err = new SyntaxError(message); 6326 err.pos = pos; 6327 err.loc = loc; 6328 6329 if (missingPluginNames) { 6330 err.missingPlugin = missingPluginNames; 6331 } 6332 6333 if (code !== undefined) { 6334 err.code = code; 6335 } 6336 6337 throw err; 6338 } 6339 6340} 6341 6342class State { 6343 constructor() { 6344 this.potentialArrowAt = -1; 6345 this.noArrowAt = []; 6346 this.noArrowParamsConversionAt = []; 6347 this.commaAfterSpreadAt = -1; 6348 this.inParameters = false; 6349 this.maybeInArrowParameters = false; 6350 this.inPipeline = false; 6351 this.inType = false; 6352 this.noAnonFunctionType = false; 6353 this.inPropertyName = false; 6354 this.inClassProperty = false; 6355 this.hasFlowComment = false; 6356 this.isIterator = false; 6357 this.topicContext = { 6358 maxNumOfResolvableTopics: 0, 6359 maxTopicIndex: null 6360 }; 6361 this.soloAwait = false; 6362 this.inFSharpPipelineDirectBody = false; 6363 this.classLevel = 0; 6364 this.labels = []; 6365 this.decoratorStack = [[]]; 6366 this.yieldPos = 0; 6367 this.awaitPos = 0; 6368 this.tokens = []; 6369 this.comments = []; 6370 this.trailingComments = []; 6371 this.leadingComments = []; 6372 this.commentStack = []; 6373 this.commentPreviousNode = null; 6374 this.pos = 0; 6375 this.lineStart = 0; 6376 this.type = types.eof; 6377 this.value = null; 6378 this.start = 0; 6379 this.end = 0; 6380 this.lastTokEndLoc = null; 6381 this.lastTokStartLoc = null; 6382 this.lastTokStart = 0; 6383 this.lastTokEnd = 0; 6384 this.context = [types$1.braceStatement]; 6385 this.exprAllowed = true; 6386 this.containsEsc = false; 6387 this.containsOctal = false; 6388 this.octalPosition = null; 6389 this.exportedIdentifiers = []; 6390 this.invalidTemplateEscapePosition = null; 6391 } 6392 6393 init(options) { 6394 this.strict = options.strictMode === false ? false : options.sourceType === "module"; 6395 this.curLine = options.startLine; 6396 this.startLoc = this.endLoc = this.curPosition(); 6397 } 6398 6399 curPosition() { 6400 return new Position(this.curLine, this.pos - this.lineStart); 6401 } 6402 6403 clone(skipArrays) { 6404 const state = new State(); 6405 const keys = Object.keys(this); 6406 6407 for (let i = 0, length = keys.length; i < length; i++) { 6408 const key = keys[i]; 6409 let val = this[key]; 6410 6411 if (!skipArrays && Array.isArray(val)) { 6412 val = val.slice(); 6413 } 6414 6415 state[key] = val; 6416 } 6417 6418 return state; 6419 } 6420 6421} 6422 6423var _isDigit = function isDigit(code) { 6424 return code >= 48 && code <= 57; 6425}; 6426const VALID_REGEX_FLAGS = new Set(["g", "m", "s", "i", "y", "u"]); 6427const forbiddenNumericSeparatorSiblings = { 6428 decBinOct: [46, 66, 69, 79, 95, 98, 101, 111], 6429 hex: [46, 88, 95, 120] 6430}; 6431const allowedNumericSeparatorSiblings = {}; 6432allowedNumericSeparatorSiblings.bin = [48, 49]; 6433allowedNumericSeparatorSiblings.oct = [...allowedNumericSeparatorSiblings.bin, 50, 51, 52, 53, 54, 55]; 6434allowedNumericSeparatorSiblings.dec = [...allowedNumericSeparatorSiblings.oct, 56, 57]; 6435allowedNumericSeparatorSiblings.hex = [...allowedNumericSeparatorSiblings.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102]; 6436class Token { 6437 constructor(state) { 6438 this.type = state.type; 6439 this.value = state.value; 6440 this.start = state.start; 6441 this.end = state.end; 6442 this.loc = new SourceLocation(state.startLoc, state.endLoc); 6443 } 6444 6445} 6446class Tokenizer extends LocationParser { 6447 constructor(options, input) { 6448 super(); 6449 this.state = new State(); 6450 this.state.init(options); 6451 this.input = input; 6452 this.length = input.length; 6453 this.isLookahead = false; 6454 } 6455 6456 next() { 6457 if (this.options.tokens && !this.isLookahead) { 6458 this.state.tokens.push(new Token(this.state)); 6459 } 6460 6461 this.state.lastTokEnd = this.state.end; 6462 this.state.lastTokStart = this.state.start; 6463 this.state.lastTokEndLoc = this.state.endLoc; 6464 this.state.lastTokStartLoc = this.state.startLoc; 6465 this.nextToken(); 6466 } 6467 6468 eat(type) { 6469 if (this.match(type)) { 6470 this.next(); 6471 return true; 6472 } else { 6473 return false; 6474 } 6475 } 6476 6477 match(type) { 6478 return this.state.type === type; 6479 } 6480 6481 lookahead() { 6482 const old = this.state; 6483 this.state = old.clone(true); 6484 this.isLookahead = true; 6485 this.next(); 6486 this.isLookahead = false; 6487 const curr = this.state; 6488 this.state = old; 6489 return curr; 6490 } 6491 6492 setStrict(strict) { 6493 this.state.strict = strict; 6494 if (!this.match(types.num) && !this.match(types.string)) return; 6495 this.state.pos = this.state.start; 6496 6497 while (this.state.pos < this.state.lineStart) { 6498 this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1; 6499 --this.state.curLine; 6500 } 6501 6502 this.nextToken(); 6503 } 6504 6505 curContext() { 6506 return this.state.context[this.state.context.length - 1]; 6507 } 6508 6509 nextToken() { 6510 const curContext = this.curContext(); 6511 if (!curContext || !curContext.preserveSpace) this.skipSpace(); 6512 this.state.containsOctal = false; 6513 this.state.octalPosition = null; 6514 this.state.start = this.state.pos; 6515 this.state.startLoc = this.state.curPosition(); 6516 6517 if (this.state.pos >= this.length) { 6518 this.finishToken(types.eof); 6519 return; 6520 } 6521 6522 if (curContext.override) { 6523 curContext.override(this); 6524 } else { 6525 this.getTokenFromCode(this.input.codePointAt(this.state.pos)); 6526 } 6527 } 6528 6529 pushComment(block, text, start, end, startLoc, endLoc) { 6530 const comment = { 6531 type: block ? "CommentBlock" : "CommentLine", 6532 value: text, 6533 start: start, 6534 end: end, 6535 loc: new SourceLocation(startLoc, endLoc) 6536 }; 6537 if (this.options.tokens) this.state.tokens.push(comment); 6538 this.state.comments.push(comment); 6539 this.addComment(comment); 6540 } 6541 6542 skipBlockComment() { 6543 const startLoc = this.state.curPosition(); 6544 const start = this.state.pos; 6545 const end = this.input.indexOf("*/", this.state.pos += 2); 6546 if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment"); 6547 this.state.pos = end + 2; 6548 lineBreakG.lastIndex = start; 6549 let match; 6550 6551 while ((match = lineBreakG.exec(this.input)) && match.index < this.state.pos) { 6552 ++this.state.curLine; 6553 this.state.lineStart = match.index + match[0].length; 6554 } 6555 6556 if (this.isLookahead) return; 6557 this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition()); 6558 } 6559 6560 skipLineComment(startSkip) { 6561 const start = this.state.pos; 6562 const startLoc = this.state.curPosition(); 6563 let ch = this.input.charCodeAt(this.state.pos += startSkip); 6564 6565 if (this.state.pos < this.length) { 6566 while (ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233 && ++this.state.pos < this.length) { 6567 ch = this.input.charCodeAt(this.state.pos); 6568 } 6569 } 6570 6571 if (this.isLookahead) return; 6572 this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition()); 6573 } 6574 6575 skipSpace() { 6576 loop: while (this.state.pos < this.length) { 6577 const ch = this.input.charCodeAt(this.state.pos); 6578 6579 switch (ch) { 6580 case 32: 6581 case 160: 6582 case 9: 6583 ++this.state.pos; 6584 break; 6585 6586 case 13: 6587 if (this.input.charCodeAt(this.state.pos + 1) === 10) { 6588 ++this.state.pos; 6589 } 6590 6591 case 10: 6592 case 8232: 6593 case 8233: 6594 ++this.state.pos; 6595 ++this.state.curLine; 6596 this.state.lineStart = this.state.pos; 6597 break; 6598 6599 case 47: 6600 switch (this.input.charCodeAt(this.state.pos + 1)) { 6601 case 42: 6602 this.skipBlockComment(); 6603 break; 6604 6605 case 47: 6606 this.skipLineComment(2); 6607 break; 6608 6609 default: 6610 break loop; 6611 } 6612 6613 break; 6614 6615 default: 6616 if (isWhitespace(ch)) { 6617 ++this.state.pos; 6618 } else { 6619 break loop; 6620 } 6621 6622 } 6623 } 6624 } 6625 6626 finishToken(type, val) { 6627 this.state.end = this.state.pos; 6628 this.state.endLoc = this.state.curPosition(); 6629 const prevType = this.state.type; 6630 this.state.type = type; 6631 this.state.value = val; 6632 if (!this.isLookahead) this.updateContext(prevType); 6633 } 6634 6635 readToken_numberSign() { 6636 if (this.state.pos === 0 && this.readToken_interpreter()) { 6637 return; 6638 } 6639 6640 const nextPos = this.state.pos + 1; 6641 const next = this.input.charCodeAt(nextPos); 6642 6643 if (next >= 48 && next <= 57) { 6644 this.raise(this.state.pos, "Unexpected digit after hash token"); 6645 } 6646 6647 if ((this.hasPlugin("classPrivateProperties") || this.hasPlugin("classPrivateMethods")) && this.state.classLevel > 0) { 6648 ++this.state.pos; 6649 this.finishToken(types.hash); 6650 return; 6651 } else if (this.getPluginOption("pipelineOperator", "proposal") === "smart") { 6652 this.finishOp(types.hash, 1); 6653 } else { 6654 this.raise(this.state.pos, "Unexpected character '#'"); 6655 } 6656 } 6657 6658 readToken_dot() { 6659 const next = this.input.charCodeAt(this.state.pos + 1); 6660 6661 if (next >= 48 && next <= 57) { 6662 this.readNumber(true); 6663 return; 6664 } 6665 6666 const next2 = this.input.charCodeAt(this.state.pos + 2); 6667 6668 if (next === 46 && next2 === 46) { 6669 this.state.pos += 3; 6670 this.finishToken(types.ellipsis); 6671 } else { 6672 ++this.state.pos; 6673 this.finishToken(types.dot); 6674 } 6675 } 6676 6677 readToken_slash() { 6678 if (this.state.exprAllowed && !this.state.inType) { 6679 ++this.state.pos; 6680 this.readRegexp(); 6681 return; 6682 } 6683 6684 const next = this.input.charCodeAt(this.state.pos + 1); 6685 6686 if (next === 61) { 6687 this.finishOp(types.assign, 2); 6688 } else { 6689 this.finishOp(types.slash, 1); 6690 } 6691 } 6692 6693 readToken_interpreter() { 6694 if (this.state.pos !== 0 || this.length < 2) return false; 6695 const start = this.state.pos; 6696 this.state.pos += 1; 6697 let ch = this.input.charCodeAt(this.state.pos); 6698 if (ch !== 33) return false; 6699 6700 while (ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233 && ++this.state.pos < this.length) { 6701 ch = this.input.charCodeAt(this.state.pos); 6702 } 6703 6704 const value = this.input.slice(start + 2, this.state.pos); 6705 this.finishToken(types.interpreterDirective, value); 6706 return true; 6707 } 6708 6709 readToken_mult_modulo(code) { 6710 let type = code === 42 ? types.star : types.modulo; 6711 let width = 1; 6712 let next = this.input.charCodeAt(this.state.pos + 1); 6713 const exprAllowed = this.state.exprAllowed; 6714 6715 if (code === 42 && next === 42) { 6716 width++; 6717 next = this.input.charCodeAt(this.state.pos + 2); 6718 type = types.exponent; 6719 } 6720 6721 if (next === 61 && !exprAllowed) { 6722 width++; 6723 type = types.assign; 6724 } 6725 6726 this.finishOp(type, width); 6727 } 6728 6729 readToken_pipe_amp(code) { 6730 const next = this.input.charCodeAt(this.state.pos + 1); 6731 6732 if (next === code) { 6733 if (this.input.charCodeAt(this.state.pos + 2) === 61) { 6734 this.finishOp(types.assign, 3); 6735 } else { 6736 this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2); 6737 } 6738 6739 return; 6740 } 6741 6742 if (code === 124) { 6743 if (next === 62) { 6744 this.finishOp(types.pipeline, 2); 6745 return; 6746 } 6747 } 6748 6749 if (next === 61) { 6750 this.finishOp(types.assign, 2); 6751 return; 6752 } 6753 6754 this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1); 6755 } 6756 6757 readToken_caret() { 6758 const next = this.input.charCodeAt(this.state.pos + 1); 6759 6760 if (next === 61) { 6761 this.finishOp(types.assign, 2); 6762 } else { 6763 this.finishOp(types.bitwiseXOR, 1); 6764 } 6765 } 6766 6767 readToken_plus_min(code) { 6768 const next = this.input.charCodeAt(this.state.pos + 1); 6769 6770 if (next === code) { 6771 if (next === 45 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 62 && (this.state.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos)))) { 6772 this.skipLineComment(3); 6773 this.skipSpace(); 6774 this.nextToken(); 6775 return; 6776 } 6777 6778 this.finishOp(types.incDec, 2); 6779 return; 6780 } 6781 6782 if (next === 61) { 6783 this.finishOp(types.assign, 2); 6784 } else { 6785 this.finishOp(types.plusMin, 1); 6786 } 6787 } 6788 6789 readToken_lt_gt(code) { 6790 const next = this.input.charCodeAt(this.state.pos + 1); 6791 let size = 1; 6792 6793 if (next === code) { 6794 size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; 6795 6796 if (this.input.charCodeAt(this.state.pos + size) === 61) { 6797 this.finishOp(types.assign, size + 1); 6798 return; 6799 } 6800 6801 this.finishOp(types.bitShift, size); 6802 return; 6803 } 6804 6805 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) { 6806 this.skipLineComment(4); 6807 this.skipSpace(); 6808 this.nextToken(); 6809 return; 6810 } 6811 6812 if (next === 61) { 6813 size = 2; 6814 } 6815 6816 this.finishOp(types.relational, size); 6817 } 6818 6819 readToken_eq_excl(code) { 6820 const next = this.input.charCodeAt(this.state.pos + 1); 6821 6822 if (next === 61) { 6823 this.finishOp(types.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); 6824 return; 6825 } 6826 6827 if (code === 61 && next === 62) { 6828 this.state.pos += 2; 6829 this.finishToken(types.arrow); 6830 return; 6831 } 6832 6833 this.finishOp(code === 61 ? types.eq : types.bang, 1); 6834 } 6835 6836 readToken_question() { 6837 const next = this.input.charCodeAt(this.state.pos + 1); 6838 const next2 = this.input.charCodeAt(this.state.pos + 2); 6839 6840 if (next === 63 && !this.state.inType) { 6841 if (next2 === 61) { 6842 this.finishOp(types.assign, 3); 6843 } else { 6844 this.finishOp(types.nullishCoalescing, 2); 6845 } 6846 } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) { 6847 this.state.pos += 2; 6848 this.finishToken(types.questionDot); 6849 } else { 6850 ++this.state.pos; 6851 this.finishToken(types.question); 6852 } 6853 } 6854 6855 getTokenFromCode(code) { 6856 switch (code) { 6857 case 46: 6858 this.readToken_dot(); 6859 return; 6860 6861 case 40: 6862 ++this.state.pos; 6863 this.finishToken(types.parenL); 6864 return; 6865 6866 case 41: 6867 ++this.state.pos; 6868 this.finishToken(types.parenR); 6869 return; 6870 6871 case 59: 6872 ++this.state.pos; 6873 this.finishToken(types.semi); 6874 return; 6875 6876 case 44: 6877 ++this.state.pos; 6878 this.finishToken(types.comma); 6879 return; 6880 6881 case 91: 6882 ++this.state.pos; 6883 this.finishToken(types.bracketL); 6884 return; 6885 6886 case 93: 6887 ++this.state.pos; 6888 this.finishToken(types.bracketR); 6889 return; 6890 6891 case 123: 6892 ++this.state.pos; 6893 this.finishToken(types.braceL); 6894 return; 6895 6896 case 125: 6897 ++this.state.pos; 6898 this.finishToken(types.braceR); 6899 return; 6900 6901 case 58: 6902 if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) { 6903 this.finishOp(types.doubleColon, 2); 6904 } else { 6905 ++this.state.pos; 6906 this.finishToken(types.colon); 6907 } 6908 6909 return; 6910 6911 case 63: 6912 this.readToken_question(); 6913 return; 6914 6915 case 96: 6916 ++this.state.pos; 6917 this.finishToken(types.backQuote); 6918 return; 6919 6920 case 48: 6921 { 6922 const next = this.input.charCodeAt(this.state.pos + 1); 6923 6924 if (next === 120 || next === 88) { 6925 this.readRadixNumber(16); 6926 return; 6927 } 6928 6929 if (next === 111 || next === 79) { 6930 this.readRadixNumber(8); 6931 return; 6932 } 6933 6934 if (next === 98 || next === 66) { 6935 this.readRadixNumber(2); 6936 return; 6937 } 6938 } 6939 6940 case 49: 6941 case 50: 6942 case 51: 6943 case 52: 6944 case 53: 6945 case 54: 6946 case 55: 6947 case 56: 6948 case 57: 6949 this.readNumber(false); 6950 return; 6951 6952 case 34: 6953 case 39: 6954 this.readString(code); 6955 return; 6956 6957 case 47: 6958 this.readToken_slash(); 6959 return; 6960 6961 case 37: 6962 case 42: 6963 this.readToken_mult_modulo(code); 6964 return; 6965 6966 case 124: 6967 case 38: 6968 this.readToken_pipe_amp(code); 6969 return; 6970 6971 case 94: 6972 this.readToken_caret(); 6973 return; 6974 6975 case 43: 6976 case 45: 6977 this.readToken_plus_min(code); 6978 return; 6979 6980 case 60: 6981 case 62: 6982 this.readToken_lt_gt(code); 6983 return; 6984 6985 case 61: 6986 case 33: 6987 this.readToken_eq_excl(code); 6988 return; 6989 6990 case 126: 6991 this.finishOp(types.tilde, 1); 6992 return; 6993 6994 case 64: 6995 ++this.state.pos; 6996 this.finishToken(types.at); 6997 return; 6998 6999 case 35: 7000 this.readToken_numberSign(); 7001 return; 7002 7003 case 92: 7004 this.readWord(); 7005 return; 7006 7007 default: 7008 if (isIdentifierStart(code)) { 7009 this.readWord(); 7010 return; 7011 } 7012 7013 } 7014 7015 this.raise(this.state.pos, `Unexpected character '${String.fromCodePoint(code)}'`); 7016 } 7017 7018 finishOp(type, size) { 7019 const str = this.input.slice(this.state.pos, this.state.pos + size); 7020 this.state.pos += size; 7021 this.finishToken(type, str); 7022 } 7023 7024 readRegexp() { 7025 const start = this.state.pos; 7026 let escaped, inClass; 7027 7028 for (;;) { 7029 if (this.state.pos >= this.length) { 7030 this.raise(start, "Unterminated regular expression"); 7031 } 7032 7033 const ch = this.input.charAt(this.state.pos); 7034 7035 if (lineBreak.test(ch)) { 7036 this.raise(start, "Unterminated regular expression"); 7037 } 7038 7039 if (escaped) { 7040 escaped = false; 7041 } else { 7042 if (ch === "[") { 7043 inClass = true; 7044 } else if (ch === "]" && inClass) { 7045 inClass = false; 7046 } else if (ch === "/" && !inClass) { 7047 break; 7048 } 7049 7050 escaped = ch === "\\"; 7051 } 7052 7053 ++this.state.pos; 7054 } 7055 7056 const content = this.input.slice(start, this.state.pos); 7057 ++this.state.pos; 7058 let mods = ""; 7059 7060 while (this.state.pos < this.length) { 7061 const char = this.input[this.state.pos]; 7062 const charCode = this.input.codePointAt(this.state.pos); 7063 7064 if (VALID_REGEX_FLAGS.has(char)) { 7065 if (mods.indexOf(char) > -1) { 7066 this.raise(this.state.pos + 1, "Duplicate regular expression flag"); 7067 } 7068 7069 ++this.state.pos; 7070 mods += char; 7071 } else if (isIdentifierChar(charCode) || charCode === 92) { 7072 this.raise(this.state.pos + 1, "Invalid regular expression flag"); 7073 } else { 7074 break; 7075 } 7076 } 7077 7078 this.finishToken(types.regexp, { 7079 pattern: content, 7080 flags: mods 7081 }); 7082 } 7083 7084 readInt(radix, len) { 7085 const start = this.state.pos; 7086 const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct; 7087 const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings.hex : radix === 10 ? allowedNumericSeparatorSiblings.dec : radix === 8 ? allowedNumericSeparatorSiblings.oct : allowedNumericSeparatorSiblings.bin; 7088 let total = 0; 7089 7090 for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) { 7091 const code = this.input.charCodeAt(this.state.pos); 7092 let val; 7093 7094 if (this.hasPlugin("numericSeparator")) { 7095 const prev = this.input.charCodeAt(this.state.pos - 1); 7096 const next = this.input.charCodeAt(this.state.pos + 1); 7097 7098 if (code === 95) { 7099 if (allowedSiblings.indexOf(next) === -1) { 7100 this.raise(this.state.pos, "Invalid or unexpected token"); 7101 } 7102 7103 if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) { 7104 this.raise(this.state.pos, "Invalid or unexpected token"); 7105 } 7106 7107 ++this.state.pos; 7108 continue; 7109 } 7110 } 7111 7112 if (code >= 97) { 7113 val = code - 97 + 10; 7114 } else if (code >= 65) { 7115 val = code - 65 + 10; 7116 } else if (_isDigit(code)) { 7117 val = code - 48; 7118 } else { 7119 val = Infinity; 7120 } 7121 7122 if (val >= radix) break; 7123 ++this.state.pos; 7124 total = total * radix + val; 7125 } 7126 7127 if (this.state.pos === start || len != null && this.state.pos - start !== len) { 7128 return null; 7129 } 7130 7131 return total; 7132 } 7133 7134 readRadixNumber(radix) { 7135 const start = this.state.pos; 7136 let isBigInt = false; 7137 this.state.pos += 2; 7138 const val = this.readInt(radix); 7139 7140 if (val == null) { 7141 this.raise(this.state.start + 2, "Expected number in radix " + radix); 7142 } 7143 7144 if (this.hasPlugin("bigInt")) { 7145 if (this.input.charCodeAt(this.state.pos) === 110) { 7146 ++this.state.pos; 7147 isBigInt = true; 7148 } 7149 } 7150 7151 if (isIdentifierStart(this.input.codePointAt(this.state.pos))) { 7152 this.raise(this.state.pos, "Identifier directly after number"); 7153 } 7154 7155 if (isBigInt) { 7156 const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); 7157 this.finishToken(types.bigint, str); 7158 return; 7159 } 7160 7161 this.finishToken(types.num, val); 7162 } 7163 7164 readNumber(startsWithDot) { 7165 const start = this.state.pos; 7166 let isFloat = false; 7167 let isBigInt = false; 7168 7169 if (!startsWithDot && this.readInt(10) === null) { 7170 this.raise(start, "Invalid number"); 7171 } 7172 7173 let octal = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48; 7174 7175 if (octal) { 7176 if (this.state.strict) { 7177 this.raise(start, "Legacy octal literals are not allowed in strict mode"); 7178 } 7179 7180 if (/[89]/.test(this.input.slice(start, this.state.pos))) { 7181 octal = false; 7182 } 7183 } 7184 7185 let next = this.input.charCodeAt(this.state.pos); 7186 7187 if (next === 46 && !octal) { 7188 ++this.state.pos; 7189 this.readInt(10); 7190 isFloat = true; 7191 next = this.input.charCodeAt(this.state.pos); 7192 } 7193 7194 if ((next === 69 || next === 101) && !octal) { 7195 next = this.input.charCodeAt(++this.state.pos); 7196 7197 if (next === 43 || next === 45) { 7198 ++this.state.pos; 7199 } 7200 7201 if (this.readInt(10) === null) this.raise(start, "Invalid number"); 7202 isFloat = true; 7203 next = this.input.charCodeAt(this.state.pos); 7204 } 7205 7206 if (this.hasPlugin("bigInt")) { 7207 if (next === 110) { 7208 if (isFloat || octal) this.raise(start, "Invalid BigIntLiteral"); 7209 ++this.state.pos; 7210 isBigInt = true; 7211 } 7212 } 7213 7214 if (isIdentifierStart(this.input.codePointAt(this.state.pos))) { 7215 this.raise(this.state.pos, "Identifier directly after number"); 7216 } 7217 7218 const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); 7219 7220 if (isBigInt) { 7221 this.finishToken(types.bigint, str); 7222 return; 7223 } 7224 7225 const val = octal ? parseInt(str, 8) : parseFloat(str); 7226 this.finishToken(types.num, val); 7227 } 7228 7229 readCodePoint(throwOnInvalid) { 7230 const ch = this.input.charCodeAt(this.state.pos); 7231 let code; 7232 7233 if (ch === 123) { 7234 const codePos = ++this.state.pos; 7235 code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, throwOnInvalid); 7236 ++this.state.pos; 7237 7238 if (code === null) { 7239 --this.state.invalidTemplateEscapePosition; 7240 } else if (code > 0x10ffff) { 7241 if (throwOnInvalid) { 7242 this.raise(codePos, "Code point out of bounds"); 7243 } else { 7244 this.state.invalidTemplateEscapePosition = codePos - 2; 7245 return null; 7246 } 7247 } 7248 } else { 7249 code = this.readHexChar(4, throwOnInvalid); 7250 } 7251 7252 return code; 7253 } 7254 7255 readString(quote) { 7256 let out = "", 7257 chunkStart = ++this.state.pos; 7258 7259 for (;;) { 7260 if (this.state.pos >= this.length) { 7261 this.raise(this.state.start, "Unterminated string constant"); 7262 } 7263 7264 const ch = this.input.charCodeAt(this.state.pos); 7265 if (ch === quote) break; 7266 7267 if (ch === 92) { 7268 out += this.input.slice(chunkStart, this.state.pos); 7269 out += this.readEscapedChar(false); 7270 chunkStart = this.state.pos; 7271 } else if (ch === 8232 || ch === 8233) { 7272 ++this.state.pos; 7273 ++this.state.curLine; 7274 } else if (isNewLine(ch)) { 7275 this.raise(this.state.start, "Unterminated string constant"); 7276 } else { 7277 ++this.state.pos; 7278 } 7279 } 7280 7281 out += this.input.slice(chunkStart, this.state.pos++); 7282 this.finishToken(types.string, out); 7283 } 7284 7285 readTmplToken() { 7286 let out = "", 7287 chunkStart = this.state.pos, 7288 containsInvalid = false; 7289 7290 for (;;) { 7291 if (this.state.pos >= this.length) { 7292 this.raise(this.state.start, "Unterminated template"); 7293 } 7294 7295 const ch = this.input.charCodeAt(this.state.pos); 7296 7297 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { 7298 if (this.state.pos === this.state.start && this.match(types.template)) { 7299 if (ch === 36) { 7300 this.state.pos += 2; 7301 this.finishToken(types.dollarBraceL); 7302 return; 7303 } else { 7304 ++this.state.pos; 7305 this.finishToken(types.backQuote); 7306 return; 7307 } 7308 } 7309 7310 out += this.input.slice(chunkStart, this.state.pos); 7311 this.finishToken(types.template, containsInvalid ? null : out); 7312 return; 7313 } 7314 7315 if (ch === 92) { 7316 out += this.input.slice(chunkStart, this.state.pos); 7317 const escaped = this.readEscapedChar(true); 7318 7319 if (escaped === null) { 7320 containsInvalid = true; 7321 } else { 7322 out += escaped; 7323 } 7324 7325 chunkStart = this.state.pos; 7326 } else if (isNewLine(ch)) { 7327 out += this.input.slice(chunkStart, this.state.pos); 7328 ++this.state.pos; 7329 7330 switch (ch) { 7331 case 13: 7332 if (this.input.charCodeAt(this.state.pos) === 10) { 7333 ++this.state.pos; 7334 } 7335 7336 case 10: 7337 out += "\n"; 7338 break; 7339 7340 default: 7341 out += String.fromCharCode(ch); 7342 break; 7343 } 7344 7345 ++this.state.curLine; 7346 this.state.lineStart = this.state.pos; 7347 chunkStart = this.state.pos; 7348 } else { 7349 ++this.state.pos; 7350 } 7351 } 7352 } 7353 7354 readEscapedChar(inTemplate) { 7355 const throwOnInvalid = !inTemplate; 7356 const ch = this.input.charCodeAt(++this.state.pos); 7357 ++this.state.pos; 7358 7359 switch (ch) { 7360 case 110: 7361 return "\n"; 7362 7363 case 114: 7364 return "\r"; 7365 7366 case 120: 7367 { 7368 const code = this.readHexChar(2, throwOnInvalid); 7369 return code === null ? null : String.fromCharCode(code); 7370 } 7371 7372 case 117: 7373 { 7374 const code = this.readCodePoint(throwOnInvalid); 7375 return code === null ? null : String.fromCodePoint(code); 7376 } 7377 7378 case 116: 7379 return "\t"; 7380 7381 case 98: 7382 return "\b"; 7383 7384 case 118: 7385 return "\u000b"; 7386 7387 case 102: 7388 return "\f"; 7389 7390 case 13: 7391 if (this.input.charCodeAt(this.state.pos) === 10) { 7392 ++this.state.pos; 7393 } 7394 7395 case 10: 7396 this.state.lineStart = this.state.pos; 7397 ++this.state.curLine; 7398 7399 case 8232: 7400 case 8233: 7401 return ""; 7402 7403 default: 7404 if (ch >= 48 && ch <= 55) { 7405 const codePos = this.state.pos - 1; 7406 let octalStr = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/)[0]; 7407 let octal = parseInt(octalStr, 8); 7408 7409 if (octal > 255) { 7410 octalStr = octalStr.slice(0, -1); 7411 octal = parseInt(octalStr, 8); 7412 } 7413 7414 this.state.pos += octalStr.length - 1; 7415 const next = this.input.charCodeAt(this.state.pos); 7416 7417 if (octalStr !== "0" || next === 56 || next === 57) { 7418 if (inTemplate) { 7419 this.state.invalidTemplateEscapePosition = codePos; 7420 return null; 7421 } else if (this.state.strict) { 7422 this.raise(codePos, "Octal literal in strict mode"); 7423 } else if (!this.state.containsOctal) { 7424 this.state.containsOctal = true; 7425 this.state.octalPosition = codePos; 7426 } 7427 } 7428 7429 return String.fromCharCode(octal); 7430 } 7431 7432 return String.fromCharCode(ch); 7433 } 7434 } 7435 7436 readHexChar(len, throwOnInvalid) { 7437 const codePos = this.state.pos; 7438 const n = this.readInt(16, len); 7439 7440 if (n === null) { 7441 if (throwOnInvalid) { 7442 this.raise(codePos, "Bad character escape sequence"); 7443 } else { 7444 this.state.pos = codePos - 1; 7445 this.state.invalidTemplateEscapePosition = codePos - 1; 7446 } 7447 } 7448 7449 return n; 7450 } 7451 7452 readWord1() { 7453 let word = ""; 7454 this.state.containsEsc = false; 7455 const start = this.state.pos; 7456 let chunkStart = this.state.pos; 7457 7458 while (this.state.pos < this.length) { 7459 const ch = this.input.codePointAt(this.state.pos); 7460 7461 if (isIdentifierChar(ch)) { 7462 this.state.pos += ch <= 0xffff ? 1 : 2; 7463 } else if (this.state.isIterator && ch === 64) { 7464 ++this.state.pos; 7465 } else if (ch === 92) { 7466 this.state.containsEsc = true; 7467 word += this.input.slice(chunkStart, this.state.pos); 7468 const escStart = this.state.pos; 7469 const identifierCheck = this.state.pos === start ? isIdentifierStart : isIdentifierChar; 7470 7471 if (this.input.charCodeAt(++this.state.pos) !== 117) { 7472 this.raise(this.state.pos, "Expecting Unicode escape sequence \\uXXXX"); 7473 } 7474 7475 ++this.state.pos; 7476 const esc = this.readCodePoint(true); 7477 7478 if (!identifierCheck(esc, true)) { 7479 this.raise(escStart, "Invalid Unicode escape"); 7480 } 7481 7482 word += String.fromCodePoint(esc); 7483 chunkStart = this.state.pos; 7484 } else { 7485 break; 7486 } 7487 } 7488 7489 return word + this.input.slice(chunkStart, this.state.pos); 7490 } 7491 7492 isIterator(word) { 7493 return word === "@@iterator" || word === "@@asyncIterator"; 7494 } 7495 7496 readWord() { 7497 const word = this.readWord1(); 7498 const type = keywords.get(word) || types.name; 7499 7500 if (type.keyword && this.state.containsEsc) { 7501 this.raise(this.state.pos, `Escape sequence in keyword ${word}`); 7502 } 7503 7504 if (this.state.isIterator && (!this.isIterator(word) || !this.state.inType)) { 7505 this.raise(this.state.pos, `Invalid identifier ${word}`); 7506 } 7507 7508 this.finishToken(type, word); 7509 } 7510 7511 braceIsBlock(prevType) { 7512 const parent = this.curContext(); 7513 7514 if (parent === types$1.functionExpression || parent === types$1.functionStatement) { 7515 return true; 7516 } 7517 7518 if (prevType === types.colon && (parent === types$1.braceStatement || parent === types$1.braceExpression)) { 7519 return !parent.isExpr; 7520 } 7521 7522 if (prevType === types._return || prevType === types.name && this.state.exprAllowed) { 7523 return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); 7524 } 7525 7526 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) { 7527 return true; 7528 } 7529 7530 if (prevType === types.braceL) { 7531 return parent === types$1.braceStatement; 7532 } 7533 7534 if (prevType === types._var || prevType === types._const || prevType === types.name) { 7535 return false; 7536 } 7537 7538 if (prevType === types.relational) { 7539 return true; 7540 } 7541 7542 return !this.state.exprAllowed; 7543 } 7544 7545 updateContext(prevType) { 7546 const type = this.state.type; 7547 let update; 7548 7549 if (type.keyword && (prevType === types.dot || prevType === types.questionDot)) { 7550 this.state.exprAllowed = false; 7551 } else if (update = type.updateContext) { 7552 update.call(this, prevType); 7553 } else { 7554 this.state.exprAllowed = type.beforeExpr; 7555 } 7556 } 7557 7558} 7559 7560const literal = /^('|")((?:\\?.)*?)\1/; 7561class UtilParser extends Tokenizer { 7562 addExtra(node, key, val) { 7563 if (!node) return; 7564 const extra = node.extra = node.extra || {}; 7565 extra[key] = val; 7566 } 7567 7568 isRelational(op) { 7569 return this.match(types.relational) && this.state.value === op; 7570 } 7571 7572 isLookaheadRelational(op) { 7573 const l = this.lookahead(); 7574 return l.type === types.relational && l.value === op; 7575 } 7576 7577 expectRelational(op) { 7578 if (this.isRelational(op)) { 7579 this.next(); 7580 } else { 7581 this.unexpected(null, types.relational); 7582 } 7583 } 7584 7585 eatRelational(op) { 7586 if (this.isRelational(op)) { 7587 this.next(); 7588 return true; 7589 } 7590 7591 return false; 7592 } 7593 7594 isContextual(name) { 7595 return this.match(types.name) && this.state.value === name && !this.state.containsEsc; 7596 } 7597 7598 isLookaheadContextual(name) { 7599 const l = this.lookahead(); 7600 return l.type === types.name && l.value === name; 7601 } 7602 7603 eatContextual(name) { 7604 return this.isContextual(name) && this.eat(types.name); 7605 } 7606 7607 expectContextual(name, message) { 7608 if (!this.eatContextual(name)) this.unexpected(null, message); 7609 } 7610 7611 canInsertSemicolon() { 7612 return this.match(types.eof) || this.match(types.braceR) || this.hasPrecedingLineBreak(); 7613 } 7614 7615 hasPrecedingLineBreak() { 7616 return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); 7617 } 7618 7619 isLineTerminator() { 7620 return this.eat(types.semi) || this.canInsertSemicolon(); 7621 } 7622 7623 semicolon() { 7624 if (!this.isLineTerminator()) this.unexpected(null, types.semi); 7625 } 7626 7627 expect(type, pos) { 7628 this.eat(type) || this.unexpected(pos, type); 7629 } 7630 7631 assertNoSpace(message = "Unexpected space.") { 7632 if (this.state.start > this.state.lastTokEnd) { 7633 this.raise(this.state.lastTokEnd, message); 7634 } 7635 } 7636 7637 unexpected(pos, messageOrType = "Unexpected token") { 7638 if (typeof messageOrType !== "string") { 7639 messageOrType = `Unexpected token, expected "${messageOrType.label}"`; 7640 } 7641 7642 throw this.raise(pos != null ? pos : this.state.start, messageOrType); 7643 } 7644 7645 expectPlugin(name, pos) { 7646 if (!this.hasPlugin(name)) { 7647 throw this.raise(pos != null ? pos : this.state.start, `This experimental syntax requires enabling the parser plugin: '${name}'`, { 7648 missingPluginNames: [name] 7649 }); 7650 } 7651 7652 return true; 7653 } 7654 7655 expectOnePlugin(names, pos) { 7656 if (!names.some(n => this.hasPlugin(n))) { 7657 throw this.raise(pos != null ? pos : this.state.start, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`, { 7658 missingPluginNames: names 7659 }); 7660 } 7661 } 7662 7663 checkYieldAwaitInDefaultParams() { 7664 if (this.state.yieldPos && (!this.state.awaitPos || this.state.yieldPos < this.state.awaitPos)) { 7665 this.raise(this.state.yieldPos, "Yield cannot be used as name inside a generator function"); 7666 } 7667 7668 if (this.state.awaitPos) { 7669 this.raise(this.state.awaitPos, "Await cannot be used as name inside an async function"); 7670 } 7671 } 7672 7673 strictDirective(start) { 7674 for (;;) { 7675 skipWhiteSpace.lastIndex = start; 7676 start += skipWhiteSpace.exec(this.input)[0].length; 7677 const match = literal.exec(this.input.slice(start)); 7678 if (!match) break; 7679 if (match[2] === "use strict") return true; 7680 start += match[0].length; 7681 skipWhiteSpace.lastIndex = start; 7682 start += skipWhiteSpace.exec(this.input)[0].length; 7683 7684 if (this.input[start] === ";") { 7685 start++; 7686 } 7687 } 7688 7689 return false; 7690 } 7691 7692} 7693 7694class Node { 7695 constructor(parser, pos, loc) { 7696 this.type = ""; 7697 this.start = pos; 7698 this.end = 0; 7699 this.loc = new SourceLocation(loc); 7700 if (parser && parser.options.ranges) this.range = [pos, 0]; 7701 if (parser && parser.filename) this.loc.filename = parser.filename; 7702 } 7703 7704 __clone() { 7705 const newNode = new Node(); 7706 const keys = Object.keys(this); 7707 7708 for (let i = 0, length = keys.length; i < length; i++) { 7709 const key = keys[i]; 7710 7711 if (key !== "leadingComments" && key !== "trailingComments" && key !== "innerComments") { 7712 newNode[key] = this[key]; 7713 } 7714 } 7715 7716 return newNode; 7717 } 7718 7719} 7720 7721class NodeUtils extends UtilParser { 7722 startNode() { 7723 return new Node(this, this.state.start, this.state.startLoc); 7724 } 7725 7726 startNodeAt(pos, loc) { 7727 return new Node(this, pos, loc); 7728 } 7729 7730 startNodeAtNode(type) { 7731 return this.startNodeAt(type.start, type.loc.start); 7732 } 7733 7734 finishNode(node, type) { 7735 return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); 7736 } 7737 7738 finishNodeAt(node, type, pos, loc) { 7739 7740 node.type = type; 7741 node.end = pos; 7742 node.loc.end = loc; 7743 if (this.options.ranges) node.range[1] = pos; 7744 this.processComment(node); 7745 return node; 7746 } 7747 7748 resetStartLocation(node, start, startLoc) { 7749 node.start = start; 7750 node.loc.start = startLoc; 7751 if (this.options.ranges) node.range[0] = start; 7752 } 7753 7754 resetEndLocation(node, end = this.state.lastTokEnd, endLoc = this.state.lastTokEndLoc) { 7755 node.end = end; 7756 node.loc.end = endLoc; 7757 if (this.options.ranges) node.range[1] = end; 7758 } 7759 7760 resetStartLocationFromNode(node, locationNode) { 7761 this.resetStartLocation(node, locationNode.start, locationNode.loc.start); 7762 } 7763 7764} 7765 7766class LValParser extends NodeUtils { 7767 toAssignable(node, isBinding, contextDescription) { 7768 if (node) { 7769 switch (node.type) { 7770 case "Identifier": 7771 case "ObjectPattern": 7772 case "ArrayPattern": 7773 case "AssignmentPattern": 7774 break; 7775 7776 case "ObjectExpression": 7777 node.type = "ObjectPattern"; 7778 7779 for (let i = 0, length = node.properties.length, last = length - 1; i < length; i++) { 7780 const prop = node.properties[i]; 7781 const isLast = i === last; 7782 this.toAssignableObjectExpressionProp(prop, isBinding, isLast); 7783 } 7784 7785 break; 7786 7787 case "ObjectProperty": 7788 this.toAssignable(node.value, isBinding, contextDescription); 7789 break; 7790 7791 case "SpreadElement": 7792 { 7793 this.checkToRestConversion(node); 7794 node.type = "RestElement"; 7795 const arg = node.argument; 7796 this.toAssignable(arg, isBinding, contextDescription); 7797 break; 7798 } 7799 7800 case "ArrayExpression": 7801 node.type = "ArrayPattern"; 7802 this.toAssignableList(node.elements, isBinding, contextDescription); 7803 break; 7804 7805 case "AssignmentExpression": 7806 if (node.operator === "=") { 7807 node.type = "AssignmentPattern"; 7808 delete node.operator; 7809 } else { 7810 this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); 7811 } 7812 7813 break; 7814 7815 case "ParenthesizedExpression": 7816 node.expression = this.toAssignable(node.expression, isBinding, contextDescription); 7817 break; 7818 7819 case "MemberExpression": 7820 if (!isBinding) break; 7821 7822 default: 7823 { 7824 const message = "Invalid left-hand side" + (contextDescription ? " in " + contextDescription : "expression"); 7825 this.raise(node.start, message); 7826 } 7827 } 7828 } 7829 7830 return node; 7831 } 7832 7833 toAssignableObjectExpressionProp(prop, isBinding, isLast) { 7834 if (prop.type === "ObjectMethod") { 7835 const error = prop.kind === "get" || prop.kind === "set" ? "Object pattern can't contain getter or setter" : "Object pattern can't contain methods"; 7836 this.raise(prop.key.start, error); 7837 } else if (prop.type === "SpreadElement" && !isLast) { 7838 this.raiseRestNotLast(prop.start); 7839 } else { 7840 this.toAssignable(prop, isBinding, "object destructuring pattern"); 7841 } 7842 } 7843 7844 toAssignableList(exprList, isBinding, contextDescription) { 7845 let end = exprList.length; 7846 7847 if (end) { 7848 const last = exprList[end - 1]; 7849 7850 if (last && last.type === "RestElement") { 7851 --end; 7852 } else if (last && last.type === "SpreadElement") { 7853 last.type = "RestElement"; 7854 const arg = last.argument; 7855 this.toAssignable(arg, isBinding, contextDescription); 7856 7857 if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern" && arg.type !== "ObjectPattern") { 7858 this.unexpected(arg.start); 7859 } 7860 7861 --end; 7862 } 7863 } 7864 7865 for (let i = 0; i < end; i++) { 7866 const elt = exprList[i]; 7867 7868 if (elt) { 7869 this.toAssignable(elt, isBinding, contextDescription); 7870 7871 if (elt.type === "RestElement") { 7872 this.raiseRestNotLast(elt.start); 7873 } 7874 } 7875 } 7876 7877 return exprList; 7878 } 7879 7880 toReferencedList(exprList, isParenthesizedExpr) { 7881 return exprList; 7882 } 7883 7884 toReferencedListDeep(exprList, isParenthesizedExpr) { 7885 this.toReferencedList(exprList, isParenthesizedExpr); 7886 7887 for (let _i = 0; _i < exprList.length; _i++) { 7888 const expr = exprList[_i]; 7889 7890 if (expr && expr.type === "ArrayExpression") { 7891 this.toReferencedListDeep(expr.elements); 7892 } 7893 } 7894 7895 return exprList; 7896 } 7897 7898 parseSpread(refShorthandDefaultPos, refNeedsArrowPos) { 7899 const node = this.startNode(); 7900 this.next(); 7901 node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos, undefined, refNeedsArrowPos); 7902 7903 if (this.state.commaAfterSpreadAt === -1 && this.match(types.comma)) { 7904 this.state.commaAfterSpreadAt = this.state.start; 7905 } 7906 7907 return this.finishNode(node, "SpreadElement"); 7908 } 7909 7910 parseRestBinding() { 7911 const node = this.startNode(); 7912 this.next(); 7913 node.argument = this.parseBindingAtom(); 7914 return this.finishNode(node, "RestElement"); 7915 } 7916 7917 parseBindingAtom() { 7918 switch (this.state.type) { 7919 case types.bracketL: 7920 { 7921 const node = this.startNode(); 7922 this.next(); 7923 node.elements = this.parseBindingList(types.bracketR, true); 7924 return this.finishNode(node, "ArrayPattern"); 7925 } 7926 7927 case types.braceL: 7928 return this.parseObj(true); 7929 } 7930 7931 return this.parseIdentifier(); 7932 } 7933 7934 parseBindingList(close, allowEmpty, allowModifiers) { 7935 const elts = []; 7936 let first = true; 7937 7938 while (!this.eat(close)) { 7939 if (first) { 7940 first = false; 7941 } else { 7942 this.expect(types.comma); 7943 } 7944 7945 if (allowEmpty && this.match(types.comma)) { 7946 elts.push(null); 7947 } else if (this.eat(close)) { 7948 break; 7949 } else if (this.match(types.ellipsis)) { 7950 elts.push(this.parseAssignableListItemTypes(this.parseRestBinding())); 7951 this.checkCommaAfterRest(); 7952 this.expect(close); 7953 break; 7954 } else { 7955 const decorators = []; 7956 7957 if (this.match(types.at) && this.hasPlugin("decorators")) { 7958 this.raise(this.state.start, "Stage 2 decorators cannot be used to decorate parameters"); 7959 } 7960 7961 while (this.match(types.at)) { 7962 decorators.push(this.parseDecorator()); 7963 } 7964 7965 elts.push(this.parseAssignableListItem(allowModifiers, decorators)); 7966 } 7967 } 7968 7969 return elts; 7970 } 7971 7972 parseAssignableListItem(allowModifiers, decorators) { 7973 const left = this.parseMaybeDefault(); 7974 this.parseAssignableListItemTypes(left); 7975 const elt = this.parseMaybeDefault(left.start, left.loc.start, left); 7976 7977 if (decorators.length) { 7978 left.decorators = decorators; 7979 } 7980 7981 return elt; 7982 } 7983 7984 parseAssignableListItemTypes(param) { 7985 return param; 7986 } 7987 7988 parseMaybeDefault(startPos, startLoc, left) { 7989 startLoc = startLoc || this.state.startLoc; 7990 startPos = startPos || this.state.start; 7991 left = left || this.parseBindingAtom(); 7992 if (!this.eat(types.eq)) return left; 7993 const node = this.startNodeAt(startPos, startLoc); 7994 node.left = left; 7995 node.right = this.parseMaybeAssign(); 7996 return this.finishNode(node, "AssignmentPattern"); 7997 } 7998 7999 checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) { 8000 switch (expr.type) { 8001 case "Identifier": 8002 if (this.state.strict && isStrictBindReservedWord(expr.name, this.inModule)) { 8003 this.raise(expr.start, `${bindingType === BIND_NONE ? "Assigning to" : "Binding"} '${expr.name}' in strict mode`); 8004 } 8005 8006 if (checkClashes) { 8007 const key = `_${expr.name}`; 8008 8009 if (checkClashes[key]) { 8010 this.raise(expr.start, "Argument name clash"); 8011 } else { 8012 checkClashes[key] = true; 8013 } 8014 } 8015 8016 if (bindingType === BIND_LEXICAL && expr.name === "let") { 8017 this.raise(expr.start, "'let' is not allowed to be used as a name in 'let' or 'const' declarations."); 8018 } 8019 8020 if (!(bindingType & BIND_NONE)) { 8021 this.scope.declareName(expr.name, bindingType, expr.start); 8022 } 8023 8024 break; 8025 8026 case "MemberExpression": 8027 if (bindingType !== BIND_NONE) { 8028 this.raise(expr.start, "Binding member expression"); 8029 } 8030 8031 break; 8032 8033 case "ObjectPattern": 8034 for (let _i2 = 0, _expr$properties = expr.properties; _i2 < _expr$properties.length; _i2++) { 8035 let prop = _expr$properties[_i2]; 8036 if (prop.type === "ObjectProperty") prop = prop.value; 8037 this.checkLVal(prop, bindingType, checkClashes, "object destructuring pattern"); 8038 } 8039 8040 break; 8041 8042 case "ArrayPattern": 8043 for (let _i3 = 0, _expr$elements = expr.elements; _i3 < _expr$elements.length; _i3++) { 8044 const elem = _expr$elements[_i3]; 8045 8046 if (elem) { 8047 this.checkLVal(elem, bindingType, checkClashes, "array destructuring pattern"); 8048 } 8049 } 8050 8051 break; 8052 8053 case "AssignmentPattern": 8054 this.checkLVal(expr.left, bindingType, checkClashes, "assignment pattern"); 8055 break; 8056 8057 case "RestElement": 8058 this.checkLVal(expr.argument, bindingType, checkClashes, "rest element"); 8059 break; 8060 8061 case "ParenthesizedExpression": 8062 this.checkLVal(expr.expression, bindingType, checkClashes, "parenthesized expression"); 8063 break; 8064 8065 default: 8066 { 8067 const message = (bindingType === BIND_NONE ? "Invalid" : "Binding invalid") + " left-hand side" + (contextDescription ? " in " + contextDescription : "expression"); 8068 this.raise(expr.start, message); 8069 } 8070 } 8071 } 8072 8073 checkToRestConversion(node) { 8074 if (node.argument.type !== "Identifier" && node.argument.type !== "MemberExpression") { 8075 this.raise(node.argument.start, "Invalid rest operator's argument"); 8076 } 8077 } 8078 8079 checkCommaAfterRest() { 8080 if (this.match(types.comma)) { 8081 this.raiseRestNotLast(this.state.start); 8082 } 8083 } 8084 8085 checkCommaAfterRestFromSpread() { 8086 if (this.state.commaAfterSpreadAt > -1) { 8087 this.raiseRestNotLast(this.state.commaAfterSpreadAt); 8088 } 8089 } 8090 8091 raiseRestNotLast(pos) { 8092 this.raise(pos, `Rest element must be last element`); 8093 } 8094 8095} 8096 8097const unwrapParenthesizedExpression = node => { 8098 return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression(node.expression) : node; 8099}; 8100 8101class ExpressionParser extends LValParser { 8102 checkPropClash(prop, propHash) { 8103 if (prop.type === "SpreadElement" || prop.computed || prop.kind || prop.shorthand) { 8104 return; 8105 } 8106 8107 const key = prop.key; 8108 const name = key.type === "Identifier" ? key.name : String(key.value); 8109 8110 if (name === "__proto__") { 8111 if (propHash.proto) { 8112 this.raise(key.start, "Redefinition of __proto__ property"); 8113 } 8114 8115 propHash.proto = true; 8116 } 8117 } 8118 8119 getExpression() { 8120 this.scope.enter(SCOPE_PROGRAM); 8121 this.nextToken(); 8122 const expr = this.parseExpression(); 8123 8124 if (!this.match(types.eof)) { 8125 this.unexpected(); 8126 } 8127 8128 expr.comments = this.state.comments; 8129 return expr; 8130 } 8131 8132 parseExpression(noIn, refShorthandDefaultPos) { 8133 const startPos = this.state.start; 8134 const startLoc = this.state.startLoc; 8135 const expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); 8136 8137 if (this.match(types.comma)) { 8138 const node = this.startNodeAt(startPos, startLoc); 8139 node.expressions = [expr]; 8140 8141 while (this.eat(types.comma)) { 8142 node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos)); 8143 } 8144 8145 this.toReferencedList(node.expressions); 8146 return this.finishNode(node, "SequenceExpression"); 8147 } 8148 8149 return expr; 8150 } 8151 8152 parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) { 8153 const startPos = this.state.start; 8154 const startLoc = this.state.startLoc; 8155 8156 if (this.isContextual("yield")) { 8157 if (this.scope.inGenerator) { 8158 let left = this.parseYield(noIn); 8159 8160 if (afterLeftParse) { 8161 left = afterLeftParse.call(this, left, startPos, startLoc); 8162 } 8163 8164 return left; 8165 } else { 8166 this.state.exprAllowed = false; 8167 } 8168 } 8169 8170 const oldCommaAfterSpreadAt = this.state.commaAfterSpreadAt; 8171 this.state.commaAfterSpreadAt = -1; 8172 let failOnShorthandAssign; 8173 8174 if (refShorthandDefaultPos) { 8175 failOnShorthandAssign = false; 8176 } else { 8177 refShorthandDefaultPos = { 8178 start: 0 8179 }; 8180 failOnShorthandAssign = true; 8181 } 8182 8183 if (this.match(types.parenL) || this.match(types.name)) { 8184 this.state.potentialArrowAt = this.state.start; 8185 } 8186 8187 let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos); 8188 8189 if (afterLeftParse) { 8190 left = afterLeftParse.call(this, left, startPos, startLoc); 8191 } 8192 8193 if (this.state.type.isAssign) { 8194 const node = this.startNodeAt(startPos, startLoc); 8195 const operator = this.state.value; 8196 node.operator = operator; 8197 8198 if (operator === "??=") { 8199 this.expectPlugin("nullishCoalescingOperator"); 8200 this.expectPlugin("logicalAssignment"); 8201 } 8202 8203 if (operator === "||=" || operator === "&&=") { 8204 this.expectPlugin("logicalAssignment"); 8205 } 8206 8207 node.left = this.match(types.eq) ? this.toAssignable(left, undefined, "assignment expression") : left; 8208 refShorthandDefaultPos.start = 0; 8209 this.checkLVal(left, undefined, undefined, "assignment expression"); 8210 const maybePattern = unwrapParenthesizedExpression(left); 8211 let patternErrorMsg; 8212 8213 if (maybePattern.type === "ObjectPattern") { 8214 patternErrorMsg = "`({a}) = 0` use `({a} = 0)`"; 8215 } else if (maybePattern.type === "ArrayPattern") { 8216 patternErrorMsg = "`([a]) = 0` use `([a] = 0)`"; 8217 } 8218 8219 if (patternErrorMsg && (left.extra && left.extra.parenthesized || left.type === "ParenthesizedExpression")) { 8220 this.raise(maybePattern.start, `You're trying to assign to a parenthesized expression, eg. instead of ${patternErrorMsg}`); 8221 } 8222 8223 if (patternErrorMsg) this.checkCommaAfterRestFromSpread(); 8224 this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt; 8225 this.next(); 8226 node.right = this.parseMaybeAssign(noIn); 8227 return this.finishNode(node, "AssignmentExpression"); 8228 } else if (failOnShorthandAssign && refShorthandDefaultPos.start) { 8229 this.unexpected(refShorthandDefaultPos.start); 8230 } 8231 8232 this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt; 8233 return left; 8234 } 8235 8236 parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos) { 8237 const startPos = this.state.start; 8238 const startLoc = this.state.startLoc; 8239 const potentialArrowAt = this.state.potentialArrowAt; 8240 const expr = this.parseExprOps(noIn, refShorthandDefaultPos); 8241 8242 if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { 8243 return expr; 8244 } 8245 8246 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; 8247 return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); 8248 } 8249 8250 parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { 8251 if (this.eat(types.question)) { 8252 const node = this.startNodeAt(startPos, startLoc); 8253 node.test = expr; 8254 node.consequent = this.parseMaybeAssign(); 8255 this.expect(types.colon); 8256 node.alternate = this.parseMaybeAssign(noIn); 8257 return this.finishNode(node, "ConditionalExpression"); 8258 } 8259 8260 return expr; 8261 } 8262 8263 parseExprOps(noIn, refShorthandDefaultPos) { 8264 const startPos = this.state.start; 8265 const startLoc = this.state.startLoc; 8266 const potentialArrowAt = this.state.potentialArrowAt; 8267 const expr = this.parseMaybeUnary(refShorthandDefaultPos); 8268 8269 if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { 8270 return expr; 8271 } 8272 8273 if (refShorthandDefaultPos && refShorthandDefaultPos.start) { 8274 return expr; 8275 } 8276 8277 return this.parseExprOp(expr, startPos, startLoc, -1, noIn); 8278 } 8279 8280 parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { 8281 const prec = this.state.type.binop; 8282 8283 if (prec != null && (!noIn || !this.match(types._in))) { 8284 if (prec > minPrec) { 8285 const operator = this.state.value; 8286 8287 if (operator === "|>" && this.state.inFSharpPipelineDirectBody) { 8288 return left; 8289 } 8290 8291 const node = this.startNodeAt(leftStartPos, leftStartLoc); 8292 node.left = left; 8293 node.operator = operator; 8294 8295 if (operator === "**" && left.type === "UnaryExpression" && (this.options.createParenthesizedExpressions || !(left.extra && left.extra.parenthesized))) { 8296 this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses."); 8297 } 8298 8299 const op = this.state.type; 8300 8301 if (op === types.pipeline) { 8302 this.expectPlugin("pipelineOperator"); 8303 this.state.inPipeline = true; 8304 this.checkPipelineAtInfixOperator(left, leftStartPos); 8305 } else if (op === types.nullishCoalescing) { 8306 this.expectPlugin("nullishCoalescingOperator"); 8307 } 8308 8309 this.next(); 8310 8311 if (op === types.pipeline && this.getPluginOption("pipelineOperator", "proposal") === "minimal") { 8312 if (this.match(types.name) && this.state.value === "await" && this.scope.inAsync) { 8313 throw this.raise(this.state.start, `Unexpected "await" after pipeline body; await must have parentheses in minimal proposal`); 8314 } 8315 } 8316 8317 node.right = this.parseExprOpRightExpr(op, prec, noIn); 8318 this.finishNode(node, op === types.logicalOR || op === types.logicalAND || op === types.nullishCoalescing ? "LogicalExpression" : "BinaryExpression"); 8319 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); 8320 } 8321 } 8322 8323 return left; 8324 } 8325 8326 parseExprOpRightExpr(op, prec, noIn) { 8327 const startPos = this.state.start; 8328 const startLoc = this.state.startLoc; 8329 8330 switch (op) { 8331 case types.pipeline: 8332 switch (this.getPluginOption("pipelineOperator", "proposal")) { 8333 case "smart": 8334 return this.withTopicPermittingContext(() => { 8335 return this.parseSmartPipelineBody(this.parseExprOpBaseRightExpr(op, prec, noIn), startPos, startLoc); 8336 }); 8337 8338 case "fsharp": 8339 return this.withSoloAwaitPermittingContext(() => { 8340 return this.parseFSharpPipelineBody(prec, noIn); 8341 }); 8342 } 8343 8344 default: 8345 return this.parseExprOpBaseRightExpr(op, prec, noIn); 8346 } 8347 } 8348 8349 parseExprOpBaseRightExpr(op, prec, noIn) { 8350 const startPos = this.state.start; 8351 const startLoc = this.state.startLoc; 8352 return this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn); 8353 } 8354 8355 parseMaybeUnary(refShorthandDefaultPos) { 8356 if (this.isContextual("await") && (this.scope.inAsync || !this.scope.inFunction && this.options.allowAwaitOutsideFunction)) { 8357 return this.parseAwait(); 8358 } else if (this.state.type.prefix) { 8359 const node = this.startNode(); 8360 const update = this.match(types.incDec); 8361 node.operator = this.state.value; 8362 node.prefix = true; 8363 8364 if (node.operator === "throw") { 8365 this.expectPlugin("throwExpressions"); 8366 } 8367 8368 this.next(); 8369 node.argument = this.parseMaybeUnary(); 8370 8371 if (refShorthandDefaultPos && refShorthandDefaultPos.start) { 8372 this.unexpected(refShorthandDefaultPos.start); 8373 } 8374 8375 if (update) { 8376 this.checkLVal(node.argument, undefined, undefined, "prefix operation"); 8377 } else if (this.state.strict && node.operator === "delete") { 8378 const arg = node.argument; 8379 8380 if (arg.type === "Identifier") { 8381 this.raise(node.start, "Deleting local variable in strict mode"); 8382 } else if (arg.type === "MemberExpression" && arg.property.type === "PrivateName") { 8383 this.raise(node.start, "Deleting a private field is not allowed"); 8384 } 8385 } 8386 8387 return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); 8388 } 8389 8390 const startPos = this.state.start; 8391 const startLoc = this.state.startLoc; 8392 let expr = this.parseExprSubscripts(refShorthandDefaultPos); 8393 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; 8394 8395 while (this.state.type.postfix && !this.canInsertSemicolon()) { 8396 const node = this.startNodeAt(startPos, startLoc); 8397 node.operator = this.state.value; 8398 node.prefix = false; 8399 node.argument = expr; 8400 this.checkLVal(expr, undefined, undefined, "postfix operation"); 8401 this.next(); 8402 expr = this.finishNode(node, "UpdateExpression"); 8403 } 8404 8405 return expr; 8406 } 8407 8408 parseExprSubscripts(refShorthandDefaultPos) { 8409 const startPos = this.state.start; 8410 const startLoc = this.state.startLoc; 8411 const potentialArrowAt = this.state.potentialArrowAt; 8412 const expr = this.parseExprAtom(refShorthandDefaultPos); 8413 8414 if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { 8415 return expr; 8416 } 8417 8418 if (refShorthandDefaultPos && refShorthandDefaultPos.start) { 8419 return expr; 8420 } 8421 8422 return this.parseSubscripts(expr, startPos, startLoc); 8423 } 8424 8425 parseSubscripts(base, startPos, startLoc, noCalls) { 8426 const maybeAsyncArrow = this.atPossibleAsync(base); 8427 const state = { 8428 optionalChainMember: false, 8429 stop: false 8430 }; 8431 8432 do { 8433 base = this.parseSubscript(base, startPos, startLoc, noCalls, state, maybeAsyncArrow); 8434 } while (!state.stop); 8435 8436 return base; 8437 } 8438 8439 parseSubscript(base, startPos, startLoc, noCalls, state, maybeAsyncArrow) { 8440 if (!noCalls && this.eat(types.doubleColon)) { 8441 const node = this.startNodeAt(startPos, startLoc); 8442 node.object = base; 8443 node.callee = this.parseNoCallExpr(); 8444 state.stop = true; 8445 return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); 8446 } else if (this.match(types.questionDot)) { 8447 this.expectPlugin("optionalChaining"); 8448 state.optionalChainMember = true; 8449 8450 if (noCalls && this.lookahead().type === types.parenL) { 8451 state.stop = true; 8452 return base; 8453 } 8454 8455 this.next(); 8456 const node = this.startNodeAt(startPos, startLoc); 8457 8458 if (this.eat(types.bracketL)) { 8459 node.object = base; 8460 node.property = this.parseExpression(); 8461 node.computed = true; 8462 node.optional = true; 8463 this.expect(types.bracketR); 8464 return this.finishNode(node, "OptionalMemberExpression"); 8465 } else if (this.eat(types.parenL)) { 8466 node.callee = base; 8467 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 8468 node.optional = true; 8469 return this.finishNode(node, "OptionalCallExpression"); 8470 } else { 8471 node.object = base; 8472 node.property = this.parseIdentifier(true); 8473 node.computed = false; 8474 node.optional = true; 8475 return this.finishNode(node, "OptionalMemberExpression"); 8476 } 8477 } else if (this.eat(types.dot)) { 8478 const node = this.startNodeAt(startPos, startLoc); 8479 node.object = base; 8480 node.property = this.parseMaybePrivateName(); 8481 node.computed = false; 8482 8483 if (state.optionalChainMember) { 8484 node.optional = false; 8485 return this.finishNode(node, "OptionalMemberExpression"); 8486 } 8487 8488 return this.finishNode(node, "MemberExpression"); 8489 } else if (this.eat(types.bracketL)) { 8490 const node = this.startNodeAt(startPos, startLoc); 8491 node.object = base; 8492 node.property = this.parseExpression(); 8493 node.computed = true; 8494 this.expect(types.bracketR); 8495 8496 if (state.optionalChainMember) { 8497 node.optional = false; 8498 return this.finishNode(node, "OptionalMemberExpression"); 8499 } 8500 8501 return this.finishNode(node, "MemberExpression"); 8502 } else if (!noCalls && this.match(types.parenL)) { 8503 const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; 8504 const oldYieldPos = this.state.yieldPos; 8505 const oldAwaitPos = this.state.awaitPos; 8506 this.state.maybeInArrowParameters = true; 8507 this.state.yieldPos = 0; 8508 this.state.awaitPos = 0; 8509 this.next(); 8510 let node = this.startNodeAt(startPos, startLoc); 8511 node.callee = base; 8512 const oldCommaAfterSpreadAt = this.state.commaAfterSpreadAt; 8513 this.state.commaAfterSpreadAt = -1; 8514 node.arguments = this.parseCallExpressionArguments(types.parenR, maybeAsyncArrow, base.type === "Import", base.type !== "Super"); 8515 8516 if (!state.optionalChainMember) { 8517 this.finishCallExpression(node); 8518 } else { 8519 this.finishOptionalCallExpression(node); 8520 } 8521 8522 if (maybeAsyncArrow && this.shouldParseAsyncArrow()) { 8523 state.stop = true; 8524 this.checkCommaAfterRestFromSpread(); 8525 node = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); 8526 this.checkYieldAwaitInDefaultParams(); 8527 this.state.yieldPos = oldYieldPos; 8528 this.state.awaitPos = oldAwaitPos; 8529 } else { 8530 this.toReferencedListDeep(node.arguments); 8531 this.state.yieldPos = oldYieldPos || this.state.yieldPos; 8532 this.state.awaitPos = oldAwaitPos || this.state.awaitPos; 8533 } 8534 8535 this.state.maybeInArrowParameters = oldMaybeInArrowParameters; 8536 this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt; 8537 return node; 8538 } else if (this.match(types.backQuote)) { 8539 return this.parseTaggedTemplateExpression(startPos, startLoc, base, state); 8540 } else { 8541 state.stop = true; 8542 return base; 8543 } 8544 } 8545 8546 parseTaggedTemplateExpression(startPos, startLoc, base, state, typeArguments) { 8547 const node = this.startNodeAt(startPos, startLoc); 8548 node.tag = base; 8549 node.quasi = this.parseTemplate(true); 8550 if (typeArguments) node.typeParameters = typeArguments; 8551 8552 if (state.optionalChainMember) { 8553 this.raise(startPos, "Tagged Template Literals are not allowed in optionalChain"); 8554 } 8555 8556 return this.finishNode(node, "TaggedTemplateExpression"); 8557 } 8558 8559 atPossibleAsync(base) { 8560 return base.type === "Identifier" && base.name === "async" && this.state.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; 8561 } 8562 8563 finishCallExpression(node) { 8564 if (node.callee.type === "Import") { 8565 if (node.arguments.length !== 1) { 8566 this.raise(node.start, "import() requires exactly one argument"); 8567 } 8568 8569 const importArg = node.arguments[0]; 8570 8571 if (importArg && importArg.type === "SpreadElement") { 8572 this.raise(importArg.start, "... is not allowed in import()"); 8573 } 8574 } 8575 8576 return this.finishNode(node, "CallExpression"); 8577 } 8578 8579 finishOptionalCallExpression(node) { 8580 if (node.callee.type === "Import") { 8581 if (node.arguments.length !== 1) { 8582 this.raise(node.start, "import() requires exactly one argument"); 8583 } 8584 8585 const importArg = node.arguments[0]; 8586 8587 if (importArg && importArg.type === "SpreadElement") { 8588 this.raise(importArg.start, "... is not allowed in import()"); 8589 } 8590 } 8591 8592 return this.finishNode(node, "OptionalCallExpression"); 8593 } 8594 8595 parseCallExpressionArguments(close, possibleAsyncArrow, dynamicImport, allowPlaceholder) { 8596 const elts = []; 8597 let innerParenStart; 8598 let first = true; 8599 const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; 8600 this.state.inFSharpPipelineDirectBody = false; 8601 8602 while (!this.eat(close)) { 8603 if (first) { 8604 first = false; 8605 } else { 8606 this.expect(types.comma); 8607 8608 if (this.eat(close)) { 8609 if (dynamicImport) { 8610 this.raise(this.state.lastTokStart, "Trailing comma is disallowed inside import(...) arguments"); 8611 } 8612 8613 break; 8614 } 8615 } 8616 8617 if (this.match(types.parenL) && !innerParenStart) { 8618 innerParenStart = this.state.start; 8619 } 8620 8621 elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { 8622 start: 0 8623 } : undefined, possibleAsyncArrow ? { 8624 start: 0 8625 } : undefined, allowPlaceholder)); 8626 } 8627 8628 if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) { 8629 this.unexpected(); 8630 } 8631 8632 this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; 8633 return elts; 8634 } 8635 8636 shouldParseAsyncArrow() { 8637 return this.match(types.arrow) && !this.canInsertSemicolon(); 8638 } 8639 8640 parseAsyncArrowFromCallExpression(node, call) { 8641 this.expect(types.arrow); 8642 this.parseArrowExpression(node, call.arguments, true); 8643 return node; 8644 } 8645 8646 parseNoCallExpr() { 8647 const startPos = this.state.start; 8648 const startLoc = this.state.startLoc; 8649 return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); 8650 } 8651 8652 parseExprAtom(refShorthandDefaultPos) { 8653 if (this.state.type === types.slash) this.readRegexp(); 8654 const canBeArrow = this.state.potentialArrowAt === this.state.start; 8655 let node; 8656 8657 switch (this.state.type) { 8658 case types._super: 8659 if (!this.scope.allowSuper && !this.options.allowSuperOutsideMethod) { 8660 this.raise(this.state.start, "super is only allowed in object methods and classes"); 8661 } 8662 8663 node = this.startNode(); 8664 this.next(); 8665 8666 if (this.match(types.parenL) && !this.scope.allowDirectSuper && !this.options.allowSuperOutsideMethod) { 8667 this.raise(node.start, "super() is only valid inside a class constructor of a subclass. " + "Maybe a typo in the method name ('constructor') or not extending another class?"); 8668 } 8669 8670 if (!this.match(types.parenL) && !this.match(types.bracketL) && !this.match(types.dot)) { 8671 this.unexpected(); 8672 } 8673 8674 return this.finishNode(node, "Super"); 8675 8676 case types._import: 8677 node = this.startNode(); 8678 this.next(); 8679 8680 if (this.match(types.dot)) { 8681 return this.parseImportMetaProperty(node); 8682 } 8683 8684 this.expectPlugin("dynamicImport", node.start); 8685 8686 if (!this.match(types.parenL)) { 8687 this.unexpected(null, types.parenL); 8688 } 8689 8690 return this.finishNode(node, "Import"); 8691 8692 case types._this: 8693 node = this.startNode(); 8694 this.next(); 8695 return this.finishNode(node, "ThisExpression"); 8696 8697 case types.name: 8698 { 8699 node = this.startNode(); 8700 const containsEsc = this.state.containsEsc; 8701 const id = this.parseIdentifier(); 8702 8703 if (!containsEsc && id.name === "async" && this.match(types._function) && !this.canInsertSemicolon()) { 8704 this.next(); 8705 return this.parseFunction(node, undefined, true); 8706 } else if (canBeArrow && !containsEsc && id.name === "async" && this.match(types.name) && !this.canInsertSemicolon()) { 8707 const params = [this.parseIdentifier()]; 8708 this.expect(types.arrow); 8709 this.parseArrowExpression(node, params, true); 8710 return node; 8711 } 8712 8713 if (canBeArrow && this.match(types.arrow) && !this.canInsertSemicolon()) { 8714 this.next(); 8715 this.parseArrowExpression(node, [id], false); 8716 return node; 8717 } 8718 8719 return id; 8720 } 8721 8722 case types._do: 8723 { 8724 this.expectPlugin("doExpressions"); 8725 const node = this.startNode(); 8726 this.next(); 8727 const oldLabels = this.state.labels; 8728 this.state.labels = []; 8729 node.body = this.parseBlock(); 8730 this.state.labels = oldLabels; 8731 return this.finishNode(node, "DoExpression"); 8732 } 8733 8734 case types.regexp: 8735 { 8736 const value = this.state.value; 8737 node = this.parseLiteral(value.value, "RegExpLiteral"); 8738 node.pattern = value.pattern; 8739 node.flags = value.flags; 8740 return node; 8741 } 8742 8743 case types.num: 8744 return this.parseLiteral(this.state.value, "NumericLiteral"); 8745 8746 case types.bigint: 8747 return this.parseLiteral(this.state.value, "BigIntLiteral"); 8748 8749 case types.string: 8750 return this.parseLiteral(this.state.value, "StringLiteral"); 8751 8752 case types._null: 8753 node = this.startNode(); 8754 this.next(); 8755 return this.finishNode(node, "NullLiteral"); 8756 8757 case types._true: 8758 case types._false: 8759 return this.parseBooleanLiteral(); 8760 8761 case types.parenL: 8762 return this.parseParenAndDistinguishExpression(canBeArrow); 8763 8764 case types.bracketL: 8765 { 8766 const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; 8767 this.state.inFSharpPipelineDirectBody = false; 8768 node = this.startNode(); 8769 this.next(); 8770 node.elements = this.parseExprList(types.bracketR, true, refShorthandDefaultPos); 8771 8772 if (!this.state.maybeInArrowParameters) { 8773 this.toReferencedList(node.elements); 8774 } 8775 8776 this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; 8777 return this.finishNode(node, "ArrayExpression"); 8778 } 8779 8780 case types.braceL: 8781 { 8782 const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; 8783 this.state.inFSharpPipelineDirectBody = false; 8784 const ret = this.parseObj(false, refShorthandDefaultPos); 8785 this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; 8786 return ret; 8787 } 8788 8789 case types._function: 8790 return this.parseFunctionExpression(); 8791 8792 case types.at: 8793 this.parseDecorators(); 8794 8795 case types._class: 8796 node = this.startNode(); 8797 this.takeDecorators(node); 8798 return this.parseClass(node, false); 8799 8800 case types._new: 8801 return this.parseNew(); 8802 8803 case types.backQuote: 8804 return this.parseTemplate(false); 8805 8806 case types.doubleColon: 8807 { 8808 node = this.startNode(); 8809 this.next(); 8810 node.object = null; 8811 const callee = node.callee = this.parseNoCallExpr(); 8812 8813 if (callee.type === "MemberExpression") { 8814 return this.finishNode(node, "BindExpression"); 8815 } else { 8816 throw this.raise(callee.start, "Binding should be performed on object property."); 8817 } 8818 } 8819 8820 case types.hash: 8821 { 8822 if (this.state.inPipeline) { 8823 node = this.startNode(); 8824 8825 if (this.getPluginOption("pipelineOperator", "proposal") !== "smart") { 8826 this.raise(node.start, "Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option."); 8827 } 8828 8829 this.next(); 8830 8831 if (this.primaryTopicReferenceIsAllowedInCurrentTopicContext()) { 8832 this.registerTopicReference(); 8833 return this.finishNode(node, "PipelinePrimaryTopicReference"); 8834 } else { 8835 throw this.raise(node.start, `Topic reference was used in a lexical context without topic binding`); 8836 } 8837 } 8838 } 8839 8840 default: 8841 throw this.unexpected(); 8842 } 8843 } 8844 8845 parseBooleanLiteral() { 8846 const node = this.startNode(); 8847 node.value = this.match(types._true); 8848 this.next(); 8849 return this.finishNode(node, "BooleanLiteral"); 8850 } 8851 8852 parseMaybePrivateName() { 8853 const isPrivate = this.match(types.hash); 8854 8855 if (isPrivate) { 8856 this.expectOnePlugin(["classPrivateProperties", "classPrivateMethods"]); 8857 const node = this.startNode(); 8858 this.next(); 8859 this.assertNoSpace("Unexpected space between # and identifier"); 8860 node.id = this.parseIdentifier(true); 8861 return this.finishNode(node, "PrivateName"); 8862 } else { 8863 return this.parseIdentifier(true); 8864 } 8865 } 8866 8867 parseFunctionExpression() { 8868 const node = this.startNode(); 8869 let meta = this.startNode(); 8870 this.next(); 8871 meta = this.createIdentifier(meta, "function"); 8872 8873 if (this.scope.inGenerator && this.eat(types.dot)) { 8874 return this.parseMetaProperty(node, meta, "sent"); 8875 } 8876 8877 return this.parseFunction(node); 8878 } 8879 8880 parseMetaProperty(node, meta, propertyName) { 8881 node.meta = meta; 8882 8883 if (meta.name === "function" && propertyName === "sent") { 8884 if (this.isContextual(propertyName)) { 8885 this.expectPlugin("functionSent"); 8886 } else if (!this.hasPlugin("functionSent")) { 8887 this.unexpected(); 8888 } 8889 } 8890 8891 const containsEsc = this.state.containsEsc; 8892 node.property = this.parseIdentifier(true); 8893 8894 if (node.property.name !== propertyName || containsEsc) { 8895 this.raise(node.property.start, `The only valid meta property for ${meta.name} is ${meta.name}.${propertyName}`); 8896 } 8897 8898 return this.finishNode(node, "MetaProperty"); 8899 } 8900 8901 parseImportMetaProperty(node) { 8902 const id = this.createIdentifier(this.startNodeAtNode(node), "import"); 8903 this.expect(types.dot); 8904 8905 if (this.isContextual("meta")) { 8906 this.expectPlugin("importMeta"); 8907 } else if (!this.hasPlugin("importMeta")) { 8908 this.raise(id.start, `Dynamic imports require a parameter: import('a.js')`); 8909 } 8910 8911 if (!this.inModule) { 8912 this.raise(id.start, `import.meta may appear only with 'sourceType: "module"'`, { 8913 code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" 8914 }); 8915 } 8916 8917 this.sawUnambiguousESM = true; 8918 return this.parseMetaProperty(node, id, "meta"); 8919 } 8920 8921 parseLiteral(value, type, startPos, startLoc) { 8922 startPos = startPos || this.state.start; 8923 startLoc = startLoc || this.state.startLoc; 8924 const node = this.startNodeAt(startPos, startLoc); 8925 this.addExtra(node, "rawValue", value); 8926 this.addExtra(node, "raw", this.input.slice(startPos, this.state.end)); 8927 node.value = value; 8928 this.next(); 8929 return this.finishNode(node, type); 8930 } 8931 8932 parseParenAndDistinguishExpression(canBeArrow) { 8933 const startPos = this.state.start; 8934 const startLoc = this.state.startLoc; 8935 let val; 8936 this.expect(types.parenL); 8937 const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; 8938 const oldYieldPos = this.state.yieldPos; 8939 const oldAwaitPos = this.state.awaitPos; 8940 const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; 8941 this.state.maybeInArrowParameters = true; 8942 this.state.yieldPos = 0; 8943 this.state.awaitPos = 0; 8944 this.state.inFSharpPipelineDirectBody = false; 8945 const innerStartPos = this.state.start; 8946 const innerStartLoc = this.state.startLoc; 8947 const exprList = []; 8948 const refShorthandDefaultPos = { 8949 start: 0 8950 }; 8951 const refNeedsArrowPos = { 8952 start: 0 8953 }; 8954 let first = true; 8955 let spreadStart; 8956 let optionalCommaStart; 8957 8958 while (!this.match(types.parenR)) { 8959 if (first) { 8960 first = false; 8961 } else { 8962 this.expect(types.comma, refNeedsArrowPos.start || null); 8963 8964 if (this.match(types.parenR)) { 8965 optionalCommaStart = this.state.start; 8966 break; 8967 } 8968 } 8969 8970 if (this.match(types.ellipsis)) { 8971 const spreadNodeStartPos = this.state.start; 8972 const spreadNodeStartLoc = this.state.startLoc; 8973 spreadStart = this.state.start; 8974 exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartPos, spreadNodeStartLoc)); 8975 this.checkCommaAfterRest(); 8976 break; 8977 } else { 8978 exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos)); 8979 } 8980 } 8981 8982 const innerEndPos = this.state.start; 8983 const innerEndLoc = this.state.startLoc; 8984 this.expect(types.parenR); 8985 this.state.maybeInArrowParameters = oldMaybeInArrowParameters; 8986 this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; 8987 let arrowNode = this.startNodeAt(startPos, startLoc); 8988 8989 if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) { 8990 this.checkYieldAwaitInDefaultParams(); 8991 this.state.yieldPos = oldYieldPos; 8992 this.state.awaitPos = oldAwaitPos; 8993 8994 for (let _i = 0; _i < exprList.length; _i++) { 8995 const param = exprList[_i]; 8996 8997 if (param.extra && param.extra.parenthesized) { 8998 this.unexpected(param.extra.parenStart); 8999 } 9000 } 9001 9002 this.parseArrowExpression(arrowNode, exprList, false); 9003 return arrowNode; 9004 } 9005 9006 this.state.yieldPos = oldYieldPos || this.state.yieldPos; 9007 this.state.awaitPos = oldAwaitPos || this.state.awaitPos; 9008 9009 if (!exprList.length) { 9010 this.unexpected(this.state.lastTokStart); 9011 } 9012 9013 if (optionalCommaStart) this.unexpected(optionalCommaStart); 9014 if (spreadStart) this.unexpected(spreadStart); 9015 9016 if (refShorthandDefaultPos.start) { 9017 this.unexpected(refShorthandDefaultPos.start); 9018 } 9019 9020 if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start); 9021 this.toReferencedListDeep(exprList, true); 9022 9023 if (exprList.length > 1) { 9024 val = this.startNodeAt(innerStartPos, innerStartLoc); 9025 val.expressions = exprList; 9026 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); 9027 } else { 9028 val = exprList[0]; 9029 } 9030 9031 if (!this.options.createParenthesizedExpressions) { 9032 this.addExtra(val, "parenthesized", true); 9033 this.addExtra(val, "parenStart", startPos); 9034 return val; 9035 } 9036 9037 const parenExpression = this.startNodeAt(startPos, startLoc); 9038 parenExpression.expression = val; 9039 this.finishNode(parenExpression, "ParenthesizedExpression"); 9040 return parenExpression; 9041 } 9042 9043 shouldParseArrow() { 9044 return !this.canInsertSemicolon(); 9045 } 9046 9047 parseArrow(node) { 9048 if (this.eat(types.arrow)) { 9049 return node; 9050 } 9051 } 9052 9053 parseParenItem(node, startPos, startLoc) { 9054 return node; 9055 } 9056 9057 parseNew() { 9058 const node = this.startNode(); 9059 const meta = this.parseIdentifier(true); 9060 9061 if (this.eat(types.dot)) { 9062 const metaProp = this.parseMetaProperty(node, meta, "target"); 9063 9064 if (!this.scope.inNonArrowFunction && !this.state.inClassProperty) { 9065 let error = "new.target can only be used in functions"; 9066 9067 if (this.hasPlugin("classProperties")) { 9068 error += " or class properties"; 9069 } 9070 9071 this.raise(metaProp.start, error); 9072 } 9073 9074 return metaProp; 9075 } 9076 9077 node.callee = this.parseNoCallExpr(); 9078 9079 if (node.callee.type === "Import") { 9080 this.raise(node.callee.start, "Cannot use new with import(...)"); 9081 } else if (node.callee.type === "OptionalMemberExpression" || node.callee.type === "OptionalCallExpression") { 9082 this.raise(this.state.lastTokEnd, "constructors in/after an Optional Chain are not allowed"); 9083 } else if (this.eat(types.questionDot)) { 9084 this.raise(this.state.start, "constructors in/after an Optional Chain are not allowed"); 9085 } 9086 9087 this.parseNewArguments(node); 9088 return this.finishNode(node, "NewExpression"); 9089 } 9090 9091 parseNewArguments(node) { 9092 if (this.eat(types.parenL)) { 9093 const args = this.parseExprList(types.parenR); 9094 this.toReferencedList(args); 9095 node.arguments = args; 9096 } else { 9097 node.arguments = []; 9098 } 9099 } 9100 9101 parseTemplateElement(isTagged) { 9102 const elem = this.startNode(); 9103 9104 if (this.state.value === null) { 9105 if (!isTagged) { 9106 this.raise(this.state.invalidTemplateEscapePosition || 0, "Invalid escape sequence in template"); 9107 } else { 9108 this.state.invalidTemplateEscapePosition = null; 9109 } 9110 } 9111 9112 elem.value = { 9113 raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), 9114 cooked: this.state.value 9115 }; 9116 this.next(); 9117 elem.tail = this.match(types.backQuote); 9118 return this.finishNode(elem, "TemplateElement"); 9119 } 9120 9121 parseTemplate(isTagged) { 9122 const node = this.startNode(); 9123 this.next(); 9124 node.expressions = []; 9125 let curElt = this.parseTemplateElement(isTagged); 9126 node.quasis = [curElt]; 9127 9128 while (!curElt.tail) { 9129 this.expect(types.dollarBraceL); 9130 node.expressions.push(this.parseExpression()); 9131 this.expect(types.braceR); 9132 node.quasis.push(curElt = this.parseTemplateElement(isTagged)); 9133 } 9134 9135 this.next(); 9136 return this.finishNode(node, "TemplateLiteral"); 9137 } 9138 9139 parseObj(isPattern, refShorthandDefaultPos) { 9140 const propHash = Object.create(null); 9141 let first = true; 9142 const node = this.startNode(); 9143 node.properties = []; 9144 this.next(); 9145 9146 while (!this.eat(types.braceR)) { 9147 if (first) { 9148 first = false; 9149 } else { 9150 this.expect(types.comma); 9151 if (this.eat(types.braceR)) break; 9152 } 9153 9154 const prop = this.parseObjectMember(isPattern, refShorthandDefaultPos); 9155 if (!isPattern) this.checkPropClash(prop, propHash); 9156 9157 if (prop.shorthand) { 9158 this.addExtra(prop, "shorthand", true); 9159 } 9160 9161 node.properties.push(prop); 9162 } 9163 9164 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); 9165 } 9166 9167 isAsyncProp(prop) { 9168 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && (this.match(types.name) || this.match(types.num) || this.match(types.string) || this.match(types.bracketL) || this.state.type.keyword || this.match(types.star)) && !this.hasPrecedingLineBreak(); 9169 } 9170 9171 parseObjectMember(isPattern, refShorthandDefaultPos) { 9172 let decorators = []; 9173 9174 if (this.match(types.at)) { 9175 if (this.hasPlugin("decorators")) { 9176 this.raise(this.state.start, "Stage 2 decorators disallow object literal property decorators"); 9177 } else { 9178 while (this.match(types.at)) { 9179 decorators.push(this.parseDecorator()); 9180 } 9181 } 9182 } 9183 9184 const prop = this.startNode(); 9185 let isGenerator = false; 9186 let isAsync = false; 9187 let startPos; 9188 let startLoc; 9189 9190 if (this.match(types.ellipsis)) { 9191 if (decorators.length) this.unexpected(); 9192 9193 if (isPattern) { 9194 this.next(); 9195 prop.argument = this.parseIdentifier(); 9196 this.checkCommaAfterRest(); 9197 return this.finishNode(prop, "RestElement"); 9198 } 9199 9200 return this.parseSpread(); 9201 } 9202 9203 if (decorators.length) { 9204 prop.decorators = decorators; 9205 decorators = []; 9206 } 9207 9208 prop.method = false; 9209 9210 if (isPattern || refShorthandDefaultPos) { 9211 startPos = this.state.start; 9212 startLoc = this.state.startLoc; 9213 } 9214 9215 if (!isPattern) { 9216 isGenerator = this.eat(types.star); 9217 } 9218 9219 const containsEsc = this.state.containsEsc; 9220 this.parsePropertyName(prop); 9221 9222 if (!isPattern && !containsEsc && !isGenerator && this.isAsyncProp(prop)) { 9223 isAsync = true; 9224 isGenerator = this.eat(types.star); 9225 this.parsePropertyName(prop); 9226 } else { 9227 isAsync = false; 9228 } 9229 9230 this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos, containsEsc); 9231 return prop; 9232 } 9233 9234 isGetterOrSetterMethod(prop, isPattern) { 9235 return !isPattern && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.match(types.string) || this.match(types.num) || this.match(types.bracketL) || this.match(types.name) || !!this.state.type.keyword); 9236 } 9237 9238 getGetterSetterExpectedParamCount(method) { 9239 return method.kind === "get" ? 0 : 1; 9240 } 9241 9242 checkGetterSetterParams(method) { 9243 const paramCount = this.getGetterSetterExpectedParamCount(method); 9244 const start = method.start; 9245 9246 if (method.params.length !== paramCount) { 9247 if (method.kind === "get") { 9248 this.raise(start, "getter must not have any formal parameters"); 9249 } else { 9250 this.raise(start, "setter must have exactly one formal parameter"); 9251 } 9252 } 9253 9254 if (method.kind === "set" && method.params[method.params.length - 1].type === "RestElement") { 9255 this.raise(start, "setter function argument must not be a rest parameter"); 9256 } 9257 } 9258 9259 parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) { 9260 if (isAsync || isGenerator || this.match(types.parenL)) { 9261 if (isPattern) this.unexpected(); 9262 prop.kind = "method"; 9263 prop.method = true; 9264 return this.parseMethod(prop, isGenerator, isAsync, false, false, "ObjectMethod"); 9265 } 9266 9267 if (!containsEsc && this.isGetterOrSetterMethod(prop, isPattern)) { 9268 if (isGenerator || isAsync) this.unexpected(); 9269 prop.kind = prop.key.name; 9270 this.parsePropertyName(prop); 9271 this.parseMethod(prop, false, false, false, false, "ObjectMethod"); 9272 this.checkGetterSetterParams(prop); 9273 return prop; 9274 } 9275 } 9276 9277 parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { 9278 prop.shorthand = false; 9279 9280 if (this.eat(types.colon)) { 9281 prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); 9282 return this.finishNode(prop, "ObjectProperty"); 9283 } 9284 9285 if (!prop.computed && prop.key.type === "Identifier") { 9286 this.checkReservedWord(prop.key.name, prop.key.start, true, true); 9287 9288 if (isPattern) { 9289 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); 9290 } else if (this.match(types.eq) && refShorthandDefaultPos) { 9291 if (!refShorthandDefaultPos.start) { 9292 refShorthandDefaultPos.start = this.state.start; 9293 } 9294 9295 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); 9296 } else { 9297 prop.value = prop.key.__clone(); 9298 } 9299 9300 prop.shorthand = true; 9301 return this.finishNode(prop, "ObjectProperty"); 9302 } 9303 } 9304 9305 parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos, containsEsc) { 9306 const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); 9307 if (!node) this.unexpected(); 9308 return node; 9309 } 9310 9311 parsePropertyName(prop) { 9312 if (this.eat(types.bracketL)) { 9313 prop.computed = true; 9314 prop.key = this.parseMaybeAssign(); 9315 this.expect(types.bracketR); 9316 } else { 9317 const oldInPropertyName = this.state.inPropertyName; 9318 this.state.inPropertyName = true; 9319 prop.key = this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseMaybePrivateName(); 9320 9321 if (prop.key.type !== "PrivateName") { 9322 prop.computed = false; 9323 } 9324 9325 this.state.inPropertyName = oldInPropertyName; 9326 } 9327 9328 return prop.key; 9329 } 9330 9331 initFunction(node, isAsync) { 9332 node.id = null; 9333 node.generator = false; 9334 node.async = !!isAsync; 9335 } 9336 9337 parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { 9338 const oldYieldPos = this.state.yieldPos; 9339 const oldAwaitPos = this.state.awaitPos; 9340 this.state.yieldPos = 0; 9341 this.state.awaitPos = 0; 9342 this.initFunction(node, isAsync); 9343 node.generator = !!isGenerator; 9344 const allowModifiers = isConstructor; 9345 this.scope.enter(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (inClassScope ? SCOPE_CLASS : 0) | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); 9346 this.parseFunctionParams(node, allowModifiers); 9347 this.checkYieldAwaitInDefaultParams(); 9348 this.parseFunctionBodyAndFinish(node, type, true); 9349 this.scope.exit(); 9350 this.state.yieldPos = oldYieldPos; 9351 this.state.awaitPos = oldAwaitPos; 9352 return node; 9353 } 9354 9355 parseArrowExpression(node, params, isAsync) { 9356 this.scope.enter(functionFlags(isAsync, false) | SCOPE_ARROW); 9357 this.initFunction(node, isAsync); 9358 const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; 9359 const oldYieldPos = this.state.yieldPos; 9360 const oldAwaitPos = this.state.awaitPos; 9361 this.state.maybeInArrowParameters = false; 9362 this.state.yieldPos = 0; 9363 this.state.awaitPos = 0; 9364 if (params) this.setArrowFunctionParameters(node, params); 9365 this.parseFunctionBody(node, true); 9366 this.scope.exit(); 9367 this.state.maybeInArrowParameters = oldMaybeInArrowParameters; 9368 this.state.yieldPos = oldYieldPos; 9369 this.state.awaitPos = oldAwaitPos; 9370 return this.finishNode(node, "ArrowFunctionExpression"); 9371 } 9372 9373 setArrowFunctionParameters(node, params) { 9374 node.params = this.toAssignableList(params, true, "arrow function parameters"); 9375 } 9376 9377 isStrictBody(node) { 9378 const isBlockStatement = node.body.type === "BlockStatement"; 9379 9380 if (isBlockStatement && node.body.directives.length) { 9381 for (let _i2 = 0, _node$body$directives = node.body.directives; _i2 < _node$body$directives.length; _i2++) { 9382 const directive = _node$body$directives[_i2]; 9383 9384 if (directive.value.value === "use strict") { 9385 return true; 9386 } 9387 } 9388 } 9389 9390 return false; 9391 } 9392 9393 parseFunctionBodyAndFinish(node, type, isMethod = false) { 9394 this.parseFunctionBody(node, false, isMethod); 9395 this.finishNode(node, type); 9396 } 9397 9398 parseFunctionBody(node, allowExpression, isMethod = false) { 9399 const isExpression = allowExpression && !this.match(types.braceL); 9400 const oldStrict = this.state.strict; 9401 let useStrict = false; 9402 const oldInParameters = this.state.inParameters; 9403 this.state.inParameters = false; 9404 9405 if (isExpression) { 9406 node.body = this.parseMaybeAssign(); 9407 this.checkParams(node, false, allowExpression); 9408 } else { 9409 const nonSimple = !this.isSimpleParamList(node.params); 9410 9411 if (!oldStrict || nonSimple) { 9412 useStrict = this.strictDirective(this.state.end); 9413 9414 if (useStrict && nonSimple) { 9415 const errorPos = (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.end : node.start; 9416 this.raise(errorPos, "Illegal 'use strict' directive in function with non-simple parameter list"); 9417 } 9418 } 9419 9420 const oldLabels = this.state.labels; 9421 this.state.labels = []; 9422 if (useStrict) this.state.strict = true; 9423 this.checkParams(node, !oldStrict && !useStrict && !allowExpression && !isMethod && !nonSimple, allowExpression); 9424 node.body = this.parseBlock(true, false); 9425 this.state.labels = oldLabels; 9426 } 9427 9428 this.state.inParameters = oldInParameters; 9429 9430 if (this.state.strict && node.id) { 9431 this.checkLVal(node.id, BIND_OUTSIDE, undefined, "function name"); 9432 } 9433 9434 this.state.strict = oldStrict; 9435 } 9436 9437 isSimpleParamList(params) { 9438 for (let i = 0, len = params.length; i < len; i++) { 9439 if (params[i].type !== "Identifier") return false; 9440 } 9441 9442 return true; 9443 } 9444 9445 checkParams(node, allowDuplicates, isArrowFunction) { 9446 const nameHash = Object.create(null); 9447 9448 for (let i = 0; i < node.params.length; i++) { 9449 this.checkLVal(node.params[i], BIND_VAR, allowDuplicates ? null : nameHash, "function paramter list"); 9450 } 9451 } 9452 9453 parseExprList(close, allowEmpty, refShorthandDefaultPos) { 9454 const elts = []; 9455 let first = true; 9456 9457 while (!this.eat(close)) { 9458 if (first) { 9459 first = false; 9460 } else { 9461 this.expect(types.comma); 9462 if (this.eat(close)) break; 9463 } 9464 9465 elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos)); 9466 } 9467 9468 return elts; 9469 } 9470 9471 parseExprListItem(allowEmpty, refShorthandDefaultPos, refNeedsArrowPos, allowPlaceholder) { 9472 let elt; 9473 9474 if (allowEmpty && this.match(types.comma)) { 9475 elt = null; 9476 } else if (this.match(types.ellipsis)) { 9477 const spreadNodeStartPos = this.state.start; 9478 const spreadNodeStartLoc = this.state.startLoc; 9479 elt = this.parseParenItem(this.parseSpread(refShorthandDefaultPos, refNeedsArrowPos), spreadNodeStartPos, spreadNodeStartLoc); 9480 } else if (this.match(types.question)) { 9481 this.expectPlugin("partialApplication"); 9482 9483 if (!allowPlaceholder) { 9484 this.raise(this.state.start, "Unexpected argument placeholder"); 9485 } 9486 9487 const node = this.startNode(); 9488 this.next(); 9489 elt = this.finishNode(node, "ArgumentPlaceholder"); 9490 } else { 9491 elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos); 9492 } 9493 9494 return elt; 9495 } 9496 9497 parseIdentifier(liberal) { 9498 const node = this.startNode(); 9499 const name = this.parseIdentifierName(node.start, liberal); 9500 return this.createIdentifier(node, name); 9501 } 9502 9503 createIdentifier(node, name) { 9504 node.name = name; 9505 node.loc.identifierName = name; 9506 return this.finishNode(node, "Identifier"); 9507 } 9508 9509 parseIdentifierName(pos, liberal) { 9510 let name; 9511 9512 if (this.match(types.name)) { 9513 name = this.state.value; 9514 } else if (this.state.type.keyword) { 9515 name = this.state.type.keyword; 9516 9517 if ((name === "class" || name === "function") && (this.state.lastTokEnd !== this.state.lastTokStart + 1 || this.input.charCodeAt(this.state.lastTokStart) !== 46)) { 9518 this.state.context.pop(); 9519 } 9520 } else { 9521 throw this.unexpected(); 9522 } 9523 9524 if (!liberal) { 9525 this.checkReservedWord(name, this.state.start, !!this.state.type.keyword, false); 9526 } 9527 9528 this.next(); 9529 return name; 9530 } 9531 9532 checkReservedWord(word, startLoc, checkKeywords, isBinding) { 9533 if (this.scope.inGenerator && word === "yield") { 9534 this.raise(startLoc, "Can not use 'yield' as identifier inside a generator"); 9535 } 9536 9537 if (this.scope.inAsync && word === "await") { 9538 this.raise(startLoc, "Can not use 'await' as identifier inside an async function"); 9539 } 9540 9541 if (this.state.inClassProperty && word === "arguments") { 9542 this.raise(startLoc, "'arguments' is not allowed in class field initializer"); 9543 } 9544 9545 if (checkKeywords && isKeyword(word)) { 9546 this.raise(startLoc, `Unexpected keyword '${word}'`); 9547 } 9548 9549 const reservedTest = !this.state.strict ? isReservedWord : isBinding ? isStrictBindReservedWord : isStrictReservedWord; 9550 9551 if (reservedTest(word, this.inModule)) { 9552 if (!this.scope.inAsync && word === "await") { 9553 this.raise(startLoc, "Can not use keyword 'await' outside an async function"); 9554 } 9555 9556 this.raise(startLoc, `Unexpected reserved word '${word}'`); 9557 } 9558 } 9559 9560 parseAwait() { 9561 if (!this.state.awaitPos) { 9562 this.state.awaitPos = this.state.start; 9563 } 9564 9565 const node = this.startNode(); 9566 this.next(); 9567 9568 if (this.state.inParameters) { 9569 this.raise(node.start, "await is not allowed in async function parameters"); 9570 } 9571 9572 if (this.match(types.star)) { 9573 this.raise(node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead."); 9574 } 9575 9576 if (!this.state.soloAwait) { 9577 node.argument = this.parseMaybeUnary(); 9578 } 9579 9580 return this.finishNode(node, "AwaitExpression"); 9581 } 9582 9583 parseYield(noIn) { 9584 if (!this.state.yieldPos) { 9585 this.state.yieldPos = this.state.start; 9586 } 9587 9588 const node = this.startNode(); 9589 9590 if (this.state.inParameters) { 9591 this.raise(node.start, "yield is not allowed in generator parameters"); 9592 } 9593 9594 this.next(); 9595 9596 if (this.match(types.semi) || !this.match(types.star) && !this.state.type.startsExpr || this.canInsertSemicolon()) { 9597 node.delegate = false; 9598 node.argument = null; 9599 } else { 9600 node.delegate = this.eat(types.star); 9601 node.argument = this.parseMaybeAssign(noIn); 9602 } 9603 9604 return this.finishNode(node, "YieldExpression"); 9605 } 9606 9607 checkPipelineAtInfixOperator(left, leftStartPos) { 9608 if (this.getPluginOption("pipelineOperator", "proposal") === "smart") { 9609 if (left.type === "SequenceExpression") { 9610 throw this.raise(leftStartPos, `Pipeline head should not be a comma-separated sequence expression`); 9611 } 9612 } 9613 } 9614 9615 parseSmartPipelineBody(childExpression, startPos, startLoc) { 9616 const pipelineStyle = this.checkSmartPipelineBodyStyle(childExpression); 9617 this.checkSmartPipelineBodyEarlyErrors(childExpression, pipelineStyle, startPos); 9618 return this.parseSmartPipelineBodyInStyle(childExpression, pipelineStyle, startPos, startLoc); 9619 } 9620 9621 checkSmartPipelineBodyEarlyErrors(childExpression, pipelineStyle, startPos) { 9622 if (this.match(types.arrow)) { 9623 throw this.raise(this.state.start, `Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized`); 9624 } else if (pipelineStyle === "PipelineTopicExpression" && childExpression.type === "SequenceExpression") { 9625 throw this.raise(startPos, `Pipeline body may not be a comma-separated sequence expression`); 9626 } 9627 } 9628 9629 parseSmartPipelineBodyInStyle(childExpression, pipelineStyle, startPos, startLoc) { 9630 const bodyNode = this.startNodeAt(startPos, startLoc); 9631 9632 switch (pipelineStyle) { 9633 case "PipelineBareFunction": 9634 bodyNode.callee = childExpression; 9635 break; 9636 9637 case "PipelineBareConstructor": 9638 bodyNode.callee = childExpression.callee; 9639 break; 9640 9641 case "PipelineBareAwaitedFunction": 9642 bodyNode.callee = childExpression.argument; 9643 break; 9644 9645 case "PipelineTopicExpression": 9646 if (!this.topicReferenceWasUsedInCurrentTopicContext()) { 9647 throw this.raise(startPos, `Pipeline is in topic style but does not use topic reference`); 9648 } 9649 9650 bodyNode.expression = childExpression; 9651 break; 9652 9653 default: 9654 throw this.raise(startPos, `Unknown pipeline style ${pipelineStyle}`); 9655 } 9656 9657 return this.finishNode(bodyNode, pipelineStyle); 9658 } 9659 9660 checkSmartPipelineBodyStyle(expression) { 9661 switch (expression.type) { 9662 default: 9663 return this.isSimpleReference(expression) ? "PipelineBareFunction" : "PipelineTopicExpression"; 9664 } 9665 } 9666 9667 isSimpleReference(expression) { 9668 switch (expression.type) { 9669 case "MemberExpression": 9670 return !expression.computed && this.isSimpleReference(expression.object); 9671 9672 case "Identifier": 9673 return true; 9674 9675 default: 9676 return false; 9677 } 9678 } 9679 9680 withTopicPermittingContext(callback) { 9681 const outerContextTopicState = this.state.topicContext; 9682 this.state.topicContext = { 9683 maxNumOfResolvableTopics: 1, 9684 maxTopicIndex: null 9685 }; 9686 9687 try { 9688 return callback(); 9689 } finally { 9690 this.state.topicContext = outerContextTopicState; 9691 } 9692 } 9693 9694 withTopicForbiddingContext(callback) { 9695 const outerContextTopicState = this.state.topicContext; 9696 this.state.topicContext = { 9697 maxNumOfResolvableTopics: 0, 9698 maxTopicIndex: null 9699 }; 9700 9701 try { 9702 return callback(); 9703 } finally { 9704 this.state.topicContext = outerContextTopicState; 9705 } 9706 } 9707 9708 withSoloAwaitPermittingContext(callback) { 9709 const outerContextSoloAwaitState = this.state.soloAwait; 9710 this.state.soloAwait = true; 9711 9712 try { 9713 return callback(); 9714 } finally { 9715 this.state.soloAwait = outerContextSoloAwaitState; 9716 } 9717 } 9718 9719 registerTopicReference() { 9720 this.state.topicContext.maxTopicIndex = 0; 9721 } 9722 9723 primaryTopicReferenceIsAllowedInCurrentTopicContext() { 9724 return this.state.topicContext.maxNumOfResolvableTopics >= 1; 9725 } 9726 9727 topicReferenceWasUsedInCurrentTopicContext() { 9728 return this.state.topicContext.maxTopicIndex != null && this.state.topicContext.maxTopicIndex >= 0; 9729 } 9730 9731 parseFSharpPipelineBody(prec, noIn) { 9732 const startPos = this.state.start; 9733 const startLoc = this.state.startLoc; 9734 this.state.potentialArrowAt = this.state.start; 9735 const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; 9736 this.state.inFSharpPipelineDirectBody = true; 9737 const ret = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn); 9738 this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; 9739 return ret; 9740 } 9741 9742} 9743 9744const loopLabel = { 9745 kind: "loop" 9746}, 9747 switchLabel = { 9748 kind: "switch" 9749}; 9750const FUNC_NO_FLAGS = 0b000, 9751 FUNC_STATEMENT = 0b001, 9752 FUNC_HANGING_STATEMENT = 0b010, 9753 FUNC_NULLABLE_ID = 0b100; 9754class StatementParser extends ExpressionParser { 9755 parseTopLevel(file, program) { 9756 program.sourceType = this.options.sourceType; 9757 program.interpreter = this.parseInterpreterDirective(); 9758 this.parseBlockBody(program, true, true, types.eof); 9759 9760 if (this.inModule && !this.options.allowUndeclaredExports && this.scope.undefinedExports.size > 0) { 9761 for (let _i = 0, _Array$from = Array.from(this.scope.undefinedExports); _i < _Array$from.length; _i++) { 9762 const [name] = _Array$from[_i]; 9763 const pos = this.scope.undefinedExports.get(name); 9764 this.raise(pos, `Export '${name}' is not defined`); 9765 } 9766 } 9767 9768 file.program = this.finishNode(program, "Program"); 9769 file.comments = this.state.comments; 9770 if (this.options.tokens) file.tokens = this.state.tokens; 9771 return this.finishNode(file, "File"); 9772 } 9773 9774 stmtToDirective(stmt) { 9775 const expr = stmt.expression; 9776 const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); 9777 const directive = this.startNodeAt(stmt.start, stmt.loc.start); 9778 const raw = this.input.slice(expr.start, expr.end); 9779 const val = directiveLiteral.value = raw.slice(1, -1); 9780 this.addExtra(directiveLiteral, "raw", raw); 9781 this.addExtra(directiveLiteral, "rawValue", val); 9782 directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end); 9783 return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end); 9784 } 9785 9786 parseInterpreterDirective() { 9787 if (!this.match(types.interpreterDirective)) { 9788 return null; 9789 } 9790 9791 const node = this.startNode(); 9792 node.value = this.state.value; 9793 this.next(); 9794 return this.finishNode(node, "InterpreterDirective"); 9795 } 9796 9797 isLet(context) { 9798 if (!this.isContextual("let")) { 9799 return false; 9800 } 9801 9802 skipWhiteSpace.lastIndex = this.state.pos; 9803 const skip = skipWhiteSpace.exec(this.input); 9804 const next = this.state.pos + skip[0].length; 9805 const nextCh = this.input.charCodeAt(next); 9806 if (nextCh === 91) return true; 9807 if (context) return false; 9808 if (nextCh === 123) return true; 9809 9810 if (isIdentifierStart(nextCh)) { 9811 let pos = next + 1; 9812 9813 while (isIdentifierChar(this.input.charCodeAt(pos))) { 9814 ++pos; 9815 } 9816 9817 const ident = this.input.slice(next, pos); 9818 if (!keywordRelationalOperator.test(ident)) return true; 9819 } 9820 9821 return false; 9822 } 9823 9824 parseStatement(context, topLevel) { 9825 if (this.match(types.at)) { 9826 this.parseDecorators(true); 9827 } 9828 9829 return this.parseStatementContent(context, topLevel); 9830 } 9831 9832 parseStatementContent(context, topLevel) { 9833 let starttype = this.state.type; 9834 const node = this.startNode(); 9835 let kind; 9836 9837 if (this.isLet(context)) { 9838 starttype = types._var; 9839 kind = "let"; 9840 } 9841 9842 switch (starttype) { 9843 case types._break: 9844 case types._continue: 9845 return this.parseBreakContinueStatement(node, starttype.keyword); 9846 9847 case types._debugger: 9848 return this.parseDebuggerStatement(node); 9849 9850 case types._do: 9851 return this.parseDoStatement(node); 9852 9853 case types._for: 9854 return this.parseForStatement(node); 9855 9856 case types._function: 9857 if (this.lookahead().type === types.dot) break; 9858 9859 if (context) { 9860 if (this.state.strict) { 9861 this.raise(this.state.start, "In strict mode code, functions can only be declared at top level or inside a block"); 9862 } else if (context !== "if" && context !== "label") { 9863 this.raise(this.state.start, "In non-strict mode code, functions can only be declared at top level, " + "inside a block, or as the body of an if statement"); 9864 } 9865 } 9866 9867 return this.parseFunctionStatement(node, false, !context); 9868 9869 case types._class: 9870 if (context) this.unexpected(); 9871 return this.parseClass(node, true); 9872 9873 case types._if: 9874 return this.parseIfStatement(node); 9875 9876 case types._return: 9877 return this.parseReturnStatement(node); 9878 9879 case types._switch: 9880 return this.parseSwitchStatement(node); 9881 9882 case types._throw: 9883 return this.parseThrowStatement(node); 9884 9885 case types._try: 9886 return this.parseTryStatement(node); 9887 9888 case types._const: 9889 case types._var: 9890 kind = kind || this.state.value; 9891 9892 if (context && kind !== "var") { 9893 this.unexpected(this.state.start, "Lexical declaration cannot appear in a single-statement context"); 9894 } 9895 9896 return this.parseVarStatement(node, kind); 9897 9898 case types._while: 9899 return this.parseWhileStatement(node); 9900 9901 case types._with: 9902 return this.parseWithStatement(node); 9903 9904 case types.braceL: 9905 return this.parseBlock(); 9906 9907 case types.semi: 9908 return this.parseEmptyStatement(node); 9909 9910 case types._export: 9911 case types._import: 9912 { 9913 const nextToken = this.lookahead(); 9914 9915 if (nextToken.type === types.parenL || nextToken.type === types.dot) { 9916 break; 9917 } 9918 9919 if (!this.options.allowImportExportEverywhere && !topLevel) { 9920 this.raise(this.state.start, "'import' and 'export' may only appear at the top level"); 9921 } 9922 9923 this.next(); 9924 let result; 9925 9926 if (starttype === types._import) { 9927 result = this.parseImport(node); 9928 9929 if (result.type === "ImportDeclaration" && (!result.importKind || result.importKind === "value")) { 9930 this.sawUnambiguousESM = true; 9931 } 9932 } else { 9933 result = this.parseExport(node); 9934 9935 if (result.type === "ExportNamedDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportAllDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportDefaultDeclaration") { 9936 this.sawUnambiguousESM = true; 9937 } 9938 } 9939 9940 this.assertModuleNodeAllowed(node); 9941 return result; 9942 } 9943 9944 default: 9945 { 9946 if (this.isAsyncFunction()) { 9947 if (context) { 9948 this.unexpected(null, "Async functions can only be declared at the top level or inside a block"); 9949 } 9950 9951 this.next(); 9952 return this.parseFunctionStatement(node, true, !context); 9953 } 9954 } 9955 } 9956 9957 const maybeName = this.state.value; 9958 const expr = this.parseExpression(); 9959 9960 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) { 9961 return this.parseLabeledStatement(node, maybeName, expr, context); 9962 } else { 9963 return this.parseExpressionStatement(node, expr); 9964 } 9965 } 9966 9967 assertModuleNodeAllowed(node) { 9968 if (!this.options.allowImportExportEverywhere && !this.inModule) { 9969 this.raise(node.start, `'import' and 'export' may appear only with 'sourceType: "module"'`, { 9970 code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" 9971 }); 9972 } 9973 } 9974 9975 takeDecorators(node) { 9976 const decorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; 9977 9978 if (decorators.length) { 9979 node.decorators = decorators; 9980 this.resetStartLocationFromNode(node, decorators[0]); 9981 this.state.decoratorStack[this.state.decoratorStack.length - 1] = []; 9982 } 9983 } 9984 9985 canHaveLeadingDecorator() { 9986 return this.match(types._class); 9987 } 9988 9989 parseDecorators(allowExport) { 9990 const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; 9991 9992 while (this.match(types.at)) { 9993 const decorator = this.parseDecorator(); 9994 currentContextDecorators.push(decorator); 9995 } 9996 9997 if (this.match(types._export)) { 9998 if (!allowExport) { 9999 this.unexpected(); 10000 } 10001 10002 if (this.hasPlugin("decorators") && !this.getPluginOption("decorators", "decoratorsBeforeExport")) { 10003 this.raise(this.state.start, "Using the export keyword between a decorator and a class is not allowed. " + "Please use `export @dec class` instead."); 10004 } 10005 } else if (!this.canHaveLeadingDecorator()) { 10006 this.raise(this.state.start, "Leading decorators must be attached to a class declaration"); 10007 } 10008 } 10009 10010 parseDecorator() { 10011 this.expectOnePlugin(["decorators-legacy", "decorators"]); 10012 const node = this.startNode(); 10013 this.next(); 10014 10015 if (this.hasPlugin("decorators")) { 10016 this.state.decoratorStack.push([]); 10017 const startPos = this.state.start; 10018 const startLoc = this.state.startLoc; 10019 let expr; 10020 10021 if (this.eat(types.parenL)) { 10022 expr = this.parseExpression(); 10023 this.expect(types.parenR); 10024 } else { 10025 expr = this.parseIdentifier(false); 10026 10027 while (this.eat(types.dot)) { 10028 const node = this.startNodeAt(startPos, startLoc); 10029 node.object = expr; 10030 node.property = this.parseIdentifier(true); 10031 node.computed = false; 10032 expr = this.finishNode(node, "MemberExpression"); 10033 } 10034 } 10035 10036 node.expression = this.parseMaybeDecoratorArguments(expr); 10037 this.state.decoratorStack.pop(); 10038 } else { 10039 node.expression = this.parseExprSubscripts(); 10040 } 10041 10042 return this.finishNode(node, "Decorator"); 10043 } 10044 10045 parseMaybeDecoratorArguments(expr) { 10046 if (this.eat(types.parenL)) { 10047 const node = this.startNodeAtNode(expr); 10048 node.callee = expr; 10049 node.arguments = this.parseCallExpressionArguments(types.parenR, false); 10050 this.toReferencedList(node.arguments); 10051 return this.finishNode(node, "CallExpression"); 10052 } 10053 10054 return expr; 10055 } 10056 10057 parseBreakContinueStatement(node, keyword) { 10058 const isBreak = keyword === "break"; 10059 this.next(); 10060 10061 if (this.isLineTerminator()) { 10062 node.label = null; 10063 } else { 10064 node.label = this.parseIdentifier(); 10065 this.semicolon(); 10066 } 10067 10068 this.verifyBreakContinue(node, keyword); 10069 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); 10070 } 10071 10072 verifyBreakContinue(node, keyword) { 10073 const isBreak = keyword === "break"; 10074 let i; 10075 10076 for (i = 0; i < this.state.labels.length; ++i) { 10077 const lab = this.state.labels[i]; 10078 10079 if (node.label == null || lab.name === node.label.name) { 10080 if (lab.kind != null && (isBreak || lab.kind === "loop")) break; 10081 if (node.label && isBreak) break; 10082 } 10083 } 10084 10085 if (i === this.state.labels.length) { 10086 this.raise(node.start, "Unsyntactic " + keyword); 10087 } 10088 } 10089 10090 parseDebuggerStatement(node) { 10091 this.next(); 10092 this.semicolon(); 10093 return this.finishNode(node, "DebuggerStatement"); 10094 } 10095 10096 parseHeaderExpression() { 10097 this.expect(types.parenL); 10098 const val = this.parseExpression(); 10099 this.expect(types.parenR); 10100 return val; 10101 } 10102 10103 parseDoStatement(node) { 10104 this.next(); 10105 this.state.labels.push(loopLabel); 10106 node.body = this.withTopicForbiddingContext(() => this.parseStatement("do")); 10107 this.state.labels.pop(); 10108 this.expect(types._while); 10109 node.test = this.parseHeaderExpression(); 10110 this.eat(types.semi); 10111 return this.finishNode(node, "DoWhileStatement"); 10112 } 10113 10114 parseForStatement(node) { 10115 this.next(); 10116 this.state.labels.push(loopLabel); 10117 let awaitAt = -1; 10118 10119 if ((this.scope.inAsync || !this.scope.inFunction && this.options.allowAwaitOutsideFunction) && this.eatContextual("await")) { 10120 awaitAt = this.state.lastTokStart; 10121 } 10122 10123 this.scope.enter(SCOPE_OTHER); 10124 this.expect(types.parenL); 10125 10126 if (this.match(types.semi)) { 10127 if (awaitAt > -1) { 10128 this.unexpected(awaitAt); 10129 } 10130 10131 return this.parseFor(node, null); 10132 } 10133 10134 const isLet = this.isLet(); 10135 10136 if (this.match(types._var) || this.match(types._const) || isLet) { 10137 const init = this.startNode(); 10138 const kind = isLet ? "let" : this.state.value; 10139 this.next(); 10140 this.parseVar(init, true, kind); 10141 this.finishNode(init, "VariableDeclaration"); 10142 10143 if ((this.match(types._in) || this.isContextual("of")) && init.declarations.length === 1) { 10144 return this.parseForIn(node, init, awaitAt); 10145 } 10146 10147 if (awaitAt > -1) { 10148 this.unexpected(awaitAt); 10149 } 10150 10151 return this.parseFor(node, init); 10152 } 10153 10154 const refShorthandDefaultPos = { 10155 start: 0 10156 }; 10157 const init = this.parseExpression(true, refShorthandDefaultPos); 10158 10159 if (this.match(types._in) || this.isContextual("of")) { 10160 const description = this.isContextual("of") ? "for-of statement" : "for-in statement"; 10161 this.toAssignable(init, undefined, description); 10162 this.checkLVal(init, undefined, undefined, description); 10163 return this.parseForIn(node, init, awaitAt); 10164 } else if (refShorthandDefaultPos.start) { 10165 this.unexpected(refShorthandDefaultPos.start); 10166 } 10167 10168 if (awaitAt > -1) { 10169 this.unexpected(awaitAt); 10170 } 10171 10172 return this.parseFor(node, init); 10173 } 10174 10175 parseFunctionStatement(node, isAsync, declarationPosition) { 10176 this.next(); 10177 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), isAsync); 10178 } 10179 10180 parseIfStatement(node) { 10181 this.next(); 10182 node.test = this.parseHeaderExpression(); 10183 node.consequent = this.parseStatement("if"); 10184 node.alternate = this.eat(types._else) ? this.parseStatement("if") : null; 10185 return this.finishNode(node, "IfStatement"); 10186 } 10187 10188 parseReturnStatement(node) { 10189 if (!this.scope.inFunction && !this.options.allowReturnOutsideFunction) { 10190 this.raise(this.state.start, "'return' outside of function"); 10191 } 10192 10193 this.next(); 10194 10195 if (this.isLineTerminator()) { 10196 node.argument = null; 10197 } else { 10198 node.argument = this.parseExpression(); 10199 this.semicolon(); 10200 } 10201 10202 return this.finishNode(node, "ReturnStatement"); 10203 } 10204 10205 parseSwitchStatement(node) { 10206 this.next(); 10207 node.discriminant = this.parseHeaderExpression(); 10208 const cases = node.cases = []; 10209 this.expect(types.braceL); 10210 this.state.labels.push(switchLabel); 10211 this.scope.enter(SCOPE_OTHER); 10212 let cur; 10213 10214 for (let sawDefault; !this.match(types.braceR);) { 10215 if (this.match(types._case) || this.match(types._default)) { 10216 const isCase = this.match(types._case); 10217 if (cur) this.finishNode(cur, "SwitchCase"); 10218 cases.push(cur = this.startNode()); 10219 cur.consequent = []; 10220 this.next(); 10221 10222 if (isCase) { 10223 cur.test = this.parseExpression(); 10224 } else { 10225 if (sawDefault) { 10226 this.raise(this.state.lastTokStart, "Multiple default clauses"); 10227 } 10228 10229 sawDefault = true; 10230 cur.test = null; 10231 } 10232 10233 this.expect(types.colon); 10234 } else { 10235 if (cur) { 10236 cur.consequent.push(this.parseStatement(null)); 10237 } else { 10238 this.unexpected(); 10239 } 10240 } 10241 } 10242 10243 this.scope.exit(); 10244 if (cur) this.finishNode(cur, "SwitchCase"); 10245 this.next(); 10246 this.state.labels.pop(); 10247 return this.finishNode(node, "SwitchStatement"); 10248 } 10249 10250 parseThrowStatement(node) { 10251 this.next(); 10252 10253 if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) { 10254 this.raise(this.state.lastTokEnd, "Illegal newline after throw"); 10255 } 10256 10257 node.argument = this.parseExpression(); 10258 this.semicolon(); 10259 return this.finishNode(node, "ThrowStatement"); 10260 } 10261 10262 parseTryStatement(node) { 10263 this.next(); 10264 node.block = this.parseBlock(); 10265 node.handler = null; 10266 10267 if (this.match(types._catch)) { 10268 const clause = this.startNode(); 10269 this.next(); 10270 10271 if (this.match(types.parenL)) { 10272 this.expect(types.parenL); 10273 clause.param = this.parseBindingAtom(); 10274 const simple = clause.param.type === "Identifier"; 10275 this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0); 10276 this.checkLVal(clause.param, BIND_LEXICAL, null, "catch clause"); 10277 this.expect(types.parenR); 10278 } else { 10279 clause.param = null; 10280 this.scope.enter(SCOPE_OTHER); 10281 } 10282 10283 clause.body = this.withTopicForbiddingContext(() => this.parseBlock(false, false)); 10284 this.scope.exit(); 10285 node.handler = this.finishNode(clause, "CatchClause"); 10286 } 10287 10288 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; 10289 10290 if (!node.handler && !node.finalizer) { 10291 this.raise(node.start, "Missing catch or finally clause"); 10292 } 10293 10294 return this.finishNode(node, "TryStatement"); 10295 } 10296 10297 parseVarStatement(node, kind) { 10298 this.next(); 10299 this.parseVar(node, false, kind); 10300 this.semicolon(); 10301 return this.finishNode(node, "VariableDeclaration"); 10302 } 10303 10304 parseWhileStatement(node) { 10305 this.next(); 10306 node.test = this.parseHeaderExpression(); 10307 this.state.labels.push(loopLabel); 10308 node.body = this.withTopicForbiddingContext(() => this.parseStatement("while")); 10309 this.state.labels.pop(); 10310 return this.finishNode(node, "WhileStatement"); 10311 } 10312 10313 parseWithStatement(node) { 10314 if (this.state.strict) { 10315 this.raise(this.state.start, "'with' in strict mode"); 10316 } 10317 10318 this.next(); 10319 node.object = this.parseHeaderExpression(); 10320 node.body = this.withTopicForbiddingContext(() => this.parseStatement("with")); 10321 return this.finishNode(node, "WithStatement"); 10322 } 10323 10324 parseEmptyStatement(node) { 10325 this.next(); 10326 return this.finishNode(node, "EmptyStatement"); 10327 } 10328 10329 parseLabeledStatement(node, maybeName, expr, context) { 10330 for (let _i2 = 0, _this$state$labels = this.state.labels; _i2 < _this$state$labels.length; _i2++) { 10331 const label = _this$state$labels[_i2]; 10332 10333 if (label.name === maybeName) { 10334 this.raise(expr.start, `Label '${maybeName}' is already declared`); 10335 } 10336 } 10337 10338 const kind = this.state.type.isLoop ? "loop" : this.match(types._switch) ? "switch" : null; 10339 10340 for (let i = this.state.labels.length - 1; i >= 0; i--) { 10341 const label = this.state.labels[i]; 10342 10343 if (label.statementStart === node.start) { 10344 label.statementStart = this.state.start; 10345 label.kind = kind; 10346 } else { 10347 break; 10348 } 10349 } 10350 10351 this.state.labels.push({ 10352 name: maybeName, 10353 kind: kind, 10354 statementStart: this.state.start 10355 }); 10356 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); 10357 this.state.labels.pop(); 10358 node.label = expr; 10359 return this.finishNode(node, "LabeledStatement"); 10360 } 10361 10362 parseExpressionStatement(node, expr) { 10363 node.expression = expr; 10364 this.semicolon(); 10365 return this.finishNode(node, "ExpressionStatement"); 10366 } 10367 10368 parseBlock(allowDirectives = false, createNewLexicalScope = true) { 10369 const node = this.startNode(); 10370 this.expect(types.braceL); 10371 10372 if (createNewLexicalScope) { 10373 this.scope.enter(SCOPE_OTHER); 10374 } 10375 10376 this.parseBlockBody(node, allowDirectives, false, types.braceR); 10377 10378 if (createNewLexicalScope) { 10379 this.scope.exit(); 10380 } 10381 10382 return this.finishNode(node, "BlockStatement"); 10383 } 10384 10385 isValidDirective(stmt) { 10386 return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized; 10387 } 10388 10389 parseBlockBody(node, allowDirectives, topLevel, end) { 10390 const body = node.body = []; 10391 const directives = node.directives = []; 10392 this.parseBlockOrModuleBlockBody(body, allowDirectives ? directives : undefined, topLevel, end); 10393 } 10394 10395 parseBlockOrModuleBlockBody(body, directives, topLevel, end) { 10396 let parsedNonDirective = false; 10397 let oldStrict; 10398 let octalPosition; 10399 10400 while (!this.eat(end)) { 10401 if (!parsedNonDirective && this.state.containsOctal && !octalPosition) { 10402 octalPosition = this.state.octalPosition; 10403 } 10404 10405 const stmt = this.parseStatement(null, topLevel); 10406 10407 if (directives && !parsedNonDirective && this.isValidDirective(stmt)) { 10408 const directive = this.stmtToDirective(stmt); 10409 directives.push(directive); 10410 10411 if (oldStrict === undefined && directive.value.value === "use strict") { 10412 oldStrict = this.state.strict; 10413 this.setStrict(true); 10414 10415 if (octalPosition) { 10416 this.raise(octalPosition, "Octal literal in strict mode"); 10417 } 10418 } 10419 10420 continue; 10421 } 10422 10423 parsedNonDirective = true; 10424 body.push(stmt); 10425 } 10426 10427 if (oldStrict === false) { 10428 this.setStrict(false); 10429 } 10430 } 10431 10432 parseFor(node, init) { 10433 node.init = init; 10434 this.expect(types.semi); 10435 node.test = this.match(types.semi) ? null : this.parseExpression(); 10436 this.expect(types.semi); 10437 node.update = this.match(types.parenR) ? null : this.parseExpression(); 10438 this.expect(types.parenR); 10439 node.body = this.withTopicForbiddingContext(() => this.parseStatement("for")); 10440 this.scope.exit(); 10441 this.state.labels.pop(); 10442 return this.finishNode(node, "ForStatement"); 10443 } 10444 10445 parseForIn(node, init, awaitAt) { 10446 const isForIn = this.match(types._in); 10447 this.next(); 10448 10449 if (isForIn) { 10450 if (awaitAt > -1) this.unexpected(awaitAt); 10451 } else { 10452 node.await = awaitAt > -1; 10453 } 10454 10455 if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) { 10456 this.raise(init.start, `${isForIn ? "for-in" : "for-of"} loop variable declaration may not have an initializer`); 10457 } else if (init.type === "AssignmentPattern") { 10458 this.raise(init.start, "Invalid left-hand side in for-loop"); 10459 } 10460 10461 node.left = init; 10462 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); 10463 this.expect(types.parenR); 10464 node.body = this.withTopicForbiddingContext(() => this.parseStatement("for")); 10465 this.scope.exit(); 10466 this.state.labels.pop(); 10467 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement"); 10468 } 10469 10470 parseVar(node, isFor, kind) { 10471 const declarations = node.declarations = []; 10472 const isTypescript = this.hasPlugin("typescript"); 10473 node.kind = kind; 10474 10475 for (;;) { 10476 const decl = this.startNode(); 10477 this.parseVarId(decl, kind); 10478 10479 if (this.eat(types.eq)) { 10480 decl.init = this.parseMaybeAssign(isFor); 10481 } else { 10482 if (kind === "const" && !(this.match(types._in) || this.isContextual("of"))) { 10483 if (!isTypescript) { 10484 this.unexpected(); 10485 } 10486 } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(types._in) || this.isContextual("of")))) { 10487 this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value"); 10488 } 10489 10490 decl.init = null; 10491 } 10492 10493 declarations.push(this.finishNode(decl, "VariableDeclarator")); 10494 if (!this.eat(types.comma)) break; 10495 } 10496 10497 return node; 10498 } 10499 10500 parseVarId(decl, kind) { 10501 decl.id = this.parseBindingAtom(); 10502 this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, undefined, "variable declaration"); 10503 } 10504 10505 parseFunction(node, statement = FUNC_NO_FLAGS, isAsync = false) { 10506 const isStatement = statement & FUNC_STATEMENT; 10507 const isHangingStatement = statement & FUNC_HANGING_STATEMENT; 10508 const requireId = !!isStatement && !(statement & FUNC_NULLABLE_ID); 10509 this.initFunction(node, isAsync); 10510 10511 if (this.match(types.star) && isHangingStatement) { 10512 this.unexpected(this.state.start, "Generators can only be declared at the top level or inside a block"); 10513 } 10514 10515 node.generator = this.eat(types.star); 10516 10517 if (isStatement) { 10518 node.id = this.parseFunctionId(requireId); 10519 } 10520 10521 const oldInClassProperty = this.state.inClassProperty; 10522 const oldYieldPos = this.state.yieldPos; 10523 const oldAwaitPos = this.state.awaitPos; 10524 this.state.inClassProperty = false; 10525 this.state.yieldPos = 0; 10526 this.state.awaitPos = 0; 10527 this.scope.enter(functionFlags(node.async, node.generator)); 10528 10529 if (!isStatement) { 10530 node.id = this.parseFunctionId(); 10531 } 10532 10533 this.parseFunctionParams(node); 10534 this.withTopicForbiddingContext(() => { 10535 this.parseFunctionBodyAndFinish(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); 10536 }); 10537 this.scope.exit(); 10538 10539 if (isStatement && !isHangingStatement) { 10540 this.checkFunctionStatementId(node); 10541 } 10542 10543 this.state.inClassProperty = oldInClassProperty; 10544 this.state.yieldPos = oldYieldPos; 10545 this.state.awaitPos = oldAwaitPos; 10546 return node; 10547 } 10548 10549 parseFunctionId(requireId) { 10550 return requireId || this.match(types.name) ? this.parseIdentifier() : null; 10551 } 10552 10553 parseFunctionParams(node, allowModifiers) { 10554 const oldInParameters = this.state.inParameters; 10555 this.state.inParameters = true; 10556 this.expect(types.parenL); 10557 node.params = this.parseBindingList(types.parenR, false, allowModifiers); 10558 this.state.inParameters = oldInParameters; 10559 this.checkYieldAwaitInDefaultParams(); 10560 } 10561 10562 checkFunctionStatementId(node) { 10563 if (!node.id) return; 10564 this.checkLVal(node.id, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION, null, "function name"); 10565 } 10566 10567 parseClass(node, isStatement, optionalId) { 10568 this.next(); 10569 this.takeDecorators(node); 10570 const oldStrict = this.state.strict; 10571 this.state.strict = true; 10572 this.parseClassId(node, isStatement, optionalId); 10573 this.parseClassSuper(node); 10574 node.body = this.parseClassBody(!!node.superClass); 10575 this.state.strict = oldStrict; 10576 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); 10577 } 10578 10579 isClassProperty() { 10580 return this.match(types.eq) || this.match(types.semi) || this.match(types.braceR); 10581 } 10582 10583 isClassMethod() { 10584 return this.match(types.parenL); 10585 } 10586 10587 isNonstaticConstructor(method) { 10588 return !method.computed && !method.static && (method.key.name === "constructor" || method.key.value === "constructor"); 10589 } 10590 10591 parseClassBody(constructorAllowsSuper) { 10592 this.state.classLevel++; 10593 const state = { 10594 hadConstructor: false 10595 }; 10596 let decorators = []; 10597 const classBody = this.startNode(); 10598 classBody.body = []; 10599 this.expect(types.braceL); 10600 this.withTopicForbiddingContext(() => { 10601 while (!this.eat(types.braceR)) { 10602 if (this.eat(types.semi)) { 10603 if (decorators.length > 0) { 10604 this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon"); 10605 } 10606 10607 continue; 10608 } 10609 10610 if (this.match(types.at)) { 10611 decorators.push(this.parseDecorator()); 10612 continue; 10613 } 10614 10615 const member = this.startNode(); 10616 10617 if (decorators.length) { 10618 member.decorators = decorators; 10619 this.resetStartLocationFromNode(member, decorators[0]); 10620 decorators = []; 10621 } 10622 10623 this.parseClassMember(classBody, member, state, constructorAllowsSuper); 10624 10625 if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) { 10626 this.raise(member.start, "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?"); 10627 } 10628 } 10629 }); 10630 10631 if (decorators.length) { 10632 this.raise(this.state.start, "You have trailing decorators with no method"); 10633 } 10634 10635 this.state.classLevel--; 10636 return this.finishNode(classBody, "ClassBody"); 10637 } 10638 10639 parseClassMember(classBody, member, state, constructorAllowsSuper) { 10640 let isStatic = false; 10641 const containsEsc = this.state.containsEsc; 10642 10643 if (this.match(types.name) && this.state.value === "static") { 10644 const key = this.parseIdentifier(true); 10645 10646 if (this.isClassMethod()) { 10647 const method = member; 10648 method.kind = "method"; 10649 method.computed = false; 10650 method.key = key; 10651 method.static = false; 10652 this.pushClassMethod(classBody, method, false, false, false, false); 10653 return; 10654 } else if (this.isClassProperty()) { 10655 const prop = member; 10656 prop.computed = false; 10657 prop.key = key; 10658 prop.static = false; 10659 classBody.body.push(this.parseClassProperty(prop)); 10660 return; 10661 } else if (containsEsc) { 10662 throw this.unexpected(); 10663 } 10664 10665 isStatic = true; 10666 } 10667 10668 this.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper); 10669 } 10670 10671 parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) { 10672 const publicMethod = member; 10673 const privateMethod = member; 10674 const publicProp = member; 10675 const privateProp = member; 10676 const method = publicMethod; 10677 const publicMember = publicMethod; 10678 member.static = isStatic; 10679 10680 if (this.eat(types.star)) { 10681 method.kind = "method"; 10682 this.parseClassPropertyName(method); 10683 10684 if (method.key.type === "PrivateName") { 10685 this.pushClassPrivateMethod(classBody, privateMethod, true, false); 10686 return; 10687 } 10688 10689 if (this.isNonstaticConstructor(publicMethod)) { 10690 this.raise(publicMethod.key.start, "Constructor can't be a generator"); 10691 } 10692 10693 this.pushClassMethod(classBody, publicMethod, true, false, false, false); 10694 return; 10695 } 10696 10697 const containsEsc = this.state.containsEsc; 10698 const key = this.parseClassPropertyName(member); 10699 const isPrivate = key.type === "PrivateName"; 10700 const isSimple = key.type === "Identifier"; 10701 this.parsePostMemberNameModifiers(publicMember); 10702 10703 if (this.isClassMethod()) { 10704 method.kind = "method"; 10705 10706 if (isPrivate) { 10707 this.pushClassPrivateMethod(classBody, privateMethod, false, false); 10708 return; 10709 } 10710 10711 const isConstructor = this.isNonstaticConstructor(publicMethod); 10712 let allowsDirectSuper = false; 10713 10714 if (isConstructor) { 10715 publicMethod.kind = "constructor"; 10716 10717 if (publicMethod.decorators) { 10718 this.raise(publicMethod.start, "You can't attach decorators to a class constructor"); 10719 } 10720 10721 if (state.hadConstructor && !this.hasPlugin("typescript")) { 10722 this.raise(key.start, "Duplicate constructor in the same class"); 10723 } 10724 10725 state.hadConstructor = true; 10726 allowsDirectSuper = constructorAllowsSuper; 10727 } 10728 10729 this.pushClassMethod(classBody, publicMethod, false, false, isConstructor, allowsDirectSuper); 10730 } else if (this.isClassProperty()) { 10731 if (isPrivate) { 10732 this.pushClassPrivateProperty(classBody, privateProp); 10733 } else { 10734 this.pushClassProperty(classBody, publicProp); 10735 } 10736 } else if (isSimple && key.name === "async" && !containsEsc && !this.isLineTerminator()) { 10737 const isGenerator = this.eat(types.star); 10738 method.kind = "method"; 10739 this.parseClassPropertyName(method); 10740 10741 if (method.key.type === "PrivateName") { 10742 this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true); 10743 } else { 10744 if (this.isNonstaticConstructor(publicMethod)) { 10745 this.raise(publicMethod.key.start, "Constructor can't be an async function"); 10746 } 10747 10748 this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false); 10749 } 10750 } else if (isSimple && (key.name === "get" || key.name === "set") && !containsEsc && !(this.match(types.star) && this.isLineTerminator())) { 10751 method.kind = key.name; 10752 this.parseClassPropertyName(publicMethod); 10753 10754 if (method.key.type === "PrivateName") { 10755 this.pushClassPrivateMethod(classBody, privateMethod, false, false); 10756 } else { 10757 if (this.isNonstaticConstructor(publicMethod)) { 10758 this.raise(publicMethod.key.start, "Constructor can't have get/set modifier"); 10759 } 10760 10761 this.pushClassMethod(classBody, publicMethod, false, false, false, false); 10762 } 10763 10764 this.checkGetterSetterParams(publicMethod); 10765 } else if (this.isLineTerminator()) { 10766 if (isPrivate) { 10767 this.pushClassPrivateProperty(classBody, privateProp); 10768 } else { 10769 this.pushClassProperty(classBody, publicProp); 10770 } 10771 } else { 10772 this.unexpected(); 10773 } 10774 } 10775 10776 parseClassPropertyName(member) { 10777 const key = this.parsePropertyName(member); 10778 10779 if (!member.computed && member.static && (key.name === "prototype" || key.value === "prototype")) { 10780 this.raise(key.start, "Classes may not have static property named prototype"); 10781 } 10782 10783 if (key.type === "PrivateName" && key.id.name === "constructor") { 10784 this.raise(key.start, "Classes may not have a private field named '#constructor'"); 10785 } 10786 10787 return key; 10788 } 10789 10790 pushClassProperty(classBody, prop) { 10791 if (this.isNonstaticConstructor(prop)) { 10792 this.raise(prop.key.start, "Classes may not have a non-static field named 'constructor'"); 10793 } 10794 10795 classBody.body.push(this.parseClassProperty(prop)); 10796 } 10797 10798 pushClassPrivateProperty(classBody, prop) { 10799 this.expectPlugin("classPrivateProperties", prop.key.start); 10800 classBody.body.push(this.parseClassPrivateProperty(prop)); 10801 } 10802 10803 pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { 10804 classBody.body.push(this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true)); 10805 } 10806 10807 pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { 10808 this.expectPlugin("classPrivateMethods", method.key.start); 10809 classBody.body.push(this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true)); 10810 } 10811 10812 parsePostMemberNameModifiers(methodOrProp) {} 10813 10814 parseAccessModifier() { 10815 return undefined; 10816 } 10817 10818 parseClassPrivateProperty(node) { 10819 this.state.inClassProperty = true; 10820 this.scope.enter(SCOPE_CLASS | SCOPE_SUPER); 10821 node.value = this.eat(types.eq) ? this.parseMaybeAssign() : null; 10822 this.semicolon(); 10823 this.state.inClassProperty = false; 10824 this.scope.exit(); 10825 return this.finishNode(node, "ClassPrivateProperty"); 10826 } 10827 10828 parseClassProperty(node) { 10829 if (!node.typeAnnotation) { 10830 this.expectPlugin("classProperties"); 10831 } 10832 10833 this.state.inClassProperty = true; 10834 this.scope.enter(SCOPE_CLASS | SCOPE_SUPER); 10835 10836 if (this.match(types.eq)) { 10837 this.expectPlugin("classProperties"); 10838 this.next(); 10839 node.value = this.parseMaybeAssign(); 10840 } else { 10841 node.value = null; 10842 } 10843 10844 this.semicolon(); 10845 this.state.inClassProperty = false; 10846 this.scope.exit(); 10847 return this.finishNode(node, "ClassProperty"); 10848 } 10849 10850 parseClassId(node, isStatement, optionalId) { 10851 if (this.match(types.name)) { 10852 node.id = this.parseIdentifier(); 10853 10854 if (isStatement) { 10855 this.checkLVal(node.id, BIND_CLASS, undefined, "class name"); 10856 } 10857 } else { 10858 if (optionalId || !isStatement) { 10859 node.id = null; 10860 } else { 10861 this.unexpected(null, "A class name is required"); 10862 } 10863 } 10864 } 10865 10866 parseClassSuper(node) { 10867 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; 10868 } 10869 10870 parseExport(node) { 10871 const hasDefault = this.maybeParseExportDefaultSpecifier(node); 10872 const parseAfterDefault = !hasDefault || this.eat(types.comma); 10873 const hasStar = parseAfterDefault && this.eatExportStar(node); 10874 const hasNamespace = hasStar && this.maybeParseExportNamespaceSpecifier(node); 10875 const parseAfterNamespace = parseAfterDefault && (!hasNamespace || this.eat(types.comma)); 10876 const isFromRequired = hasDefault || hasStar; 10877 10878 if (hasStar && !hasNamespace) { 10879 if (hasDefault) this.unexpected(); 10880 this.parseExportFrom(node, true); 10881 return this.finishNode(node, "ExportAllDeclaration"); 10882 } 10883 10884 const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node); 10885 10886 if (hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers || hasNamespace && parseAfterNamespace && !hasSpecifiers) { 10887 throw this.unexpected(null, types.braceL); 10888 } 10889 10890 let hasDeclaration; 10891 10892 if (isFromRequired || hasSpecifiers) { 10893 hasDeclaration = false; 10894 this.parseExportFrom(node, isFromRequired); 10895 } else { 10896 hasDeclaration = this.maybeParseExportDeclaration(node); 10897 } 10898 10899 if (isFromRequired || hasSpecifiers || hasDeclaration) { 10900 this.checkExport(node, true, false, !!node.source); 10901 return this.finishNode(node, "ExportNamedDeclaration"); 10902 } 10903 10904 if (this.eat(types._default)) { 10905 node.declaration = this.parseExportDefaultExpression(); 10906 this.checkExport(node, true, true); 10907 return this.finishNode(node, "ExportDefaultDeclaration"); 10908 } 10909 10910 throw this.unexpected(null, types.braceL); 10911 } 10912 10913 eatExportStar(node) { 10914 return this.eat(types.star); 10915 } 10916 10917 maybeParseExportDefaultSpecifier(node) { 10918 if (this.isExportDefaultSpecifier()) { 10919 this.expectPlugin("exportDefaultFrom"); 10920 const specifier = this.startNode(); 10921 specifier.exported = this.parseIdentifier(true); 10922 node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; 10923 return true; 10924 } 10925 10926 return false; 10927 } 10928 10929 maybeParseExportNamespaceSpecifier(node) { 10930 if (this.isContextual("as")) { 10931 if (!node.specifiers) node.specifiers = []; 10932 this.expectPlugin("exportNamespaceFrom"); 10933 const specifier = this.startNodeAt(this.state.lastTokStart, this.state.lastTokStartLoc); 10934 this.next(); 10935 specifier.exported = this.parseIdentifier(true); 10936 node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); 10937 return true; 10938 } 10939 10940 return false; 10941 } 10942 10943 maybeParseExportNamedSpecifiers(node) { 10944 if (this.match(types.braceL)) { 10945 if (!node.specifiers) node.specifiers = []; 10946 node.specifiers.push(...this.parseExportSpecifiers()); 10947 node.source = null; 10948 node.declaration = null; 10949 return true; 10950 } 10951 10952 return false; 10953 } 10954 10955 maybeParseExportDeclaration(node) { 10956 if (this.shouldParseExportDeclaration()) { 10957 if (this.isContextual("async")) { 10958 const next = this.lookahead(); 10959 10960 if (next.type !== types._function) { 10961 this.unexpected(next.start, `Unexpected token, expected "function"`); 10962 } 10963 } 10964 10965 node.specifiers = []; 10966 node.source = null; 10967 node.declaration = this.parseExportDeclaration(node); 10968 return true; 10969 } 10970 10971 return false; 10972 } 10973 10974 isAsyncFunction() { 10975 if (!this.isContextual("async")) return false; 10976 const { 10977 pos 10978 } = this.state; 10979 skipWhiteSpace.lastIndex = pos; 10980 const skip = skipWhiteSpace.exec(this.input); 10981 if (!skip || !skip.length) return false; 10982 const next = pos + skip[0].length; 10983 return !lineBreak.test(this.input.slice(pos, next)) && this.input.slice(next, next + 8) === "function" && (next + 8 === this.length || !isIdentifierChar(this.input.charCodeAt(next + 8))); 10984 } 10985 10986 parseExportDefaultExpression() { 10987 const expr = this.startNode(); 10988 const isAsync = this.isAsyncFunction(); 10989 10990 if (this.match(types._function) || isAsync) { 10991 this.next(); 10992 10993 if (isAsync) { 10994 this.next(); 10995 } 10996 10997 return this.parseFunction(expr, FUNC_STATEMENT | FUNC_NULLABLE_ID, isAsync); 10998 } else if (this.match(types._class)) { 10999 return this.parseClass(expr, true, true); 11000 } else if (this.match(types.at)) { 11001 if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport")) { 11002 this.unexpected(this.state.start, "Decorators must be placed *before* the 'export' keyword." + " You can set the 'decoratorsBeforeExport' option to false to use" + " the 'export @decorator class {}' syntax"); 11003 } 11004 11005 this.parseDecorators(false); 11006 return this.parseClass(expr, true, true); 11007 } else if (this.match(types._const) || this.match(types._var) || this.isLet()) { 11008 return this.raise(this.state.start, "Only expressions, functions or classes are allowed as the `default` export."); 11009 } else { 11010 const res = this.parseMaybeAssign(); 11011 this.semicolon(); 11012 return res; 11013 } 11014 } 11015 11016 parseExportDeclaration(node) { 11017 return this.parseStatement(null); 11018 } 11019 11020 isExportDefaultSpecifier() { 11021 if (this.match(types.name)) { 11022 return this.state.value !== "async" && this.state.value !== "let"; 11023 } 11024 11025 if (!this.match(types._default)) { 11026 return false; 11027 } 11028 11029 const lookahead = this.lookahead(); 11030 return lookahead.type === types.comma || lookahead.type === types.name && lookahead.value === "from"; 11031 } 11032 11033 parseExportFrom(node, expect) { 11034 if (this.eatContextual("from")) { 11035 node.source = this.parseImportSource(); 11036 this.checkExport(node); 11037 } else { 11038 if (expect) { 11039 this.unexpected(); 11040 } else { 11041 node.source = null; 11042 } 11043 } 11044 11045 this.semicolon(); 11046 } 11047 11048 shouldParseExportDeclaration() { 11049 if (this.match(types.at)) { 11050 this.expectOnePlugin(["decorators", "decorators-legacy"]); 11051 11052 if (this.hasPlugin("decorators")) { 11053 if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { 11054 this.unexpected(this.state.start, "Decorators must be placed *before* the 'export' keyword." + " You can set the 'decoratorsBeforeExport' option to false to use" + " the 'export @decorator class {}' syntax"); 11055 } else { 11056 return true; 11057 } 11058 } 11059 } 11060 11061 return this.state.type.keyword === "var" || this.state.type.keyword === "const" || this.state.type.keyword === "function" || this.state.type.keyword === "class" || this.isLet() || this.isAsyncFunction(); 11062 } 11063 11064 checkExport(node, checkNames, isDefault, isFrom) { 11065 if (checkNames) { 11066 if (isDefault) { 11067 this.checkDuplicateExports(node, "default"); 11068 } else if (node.specifiers && node.specifiers.length) { 11069 for (let _i3 = 0, _node$specifiers = node.specifiers; _i3 < _node$specifiers.length; _i3++) { 11070 const specifier = _node$specifiers[_i3]; 11071 this.checkDuplicateExports(specifier, specifier.exported.name); 11072 11073 if (!isFrom && specifier.local) { 11074 this.checkReservedWord(specifier.local.name, specifier.local.start, true, false); 11075 this.scope.checkLocalExport(specifier.local); 11076 } 11077 } 11078 } else if (node.declaration) { 11079 if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { 11080 const id = node.declaration.id; 11081 if (!id) throw new Error("Assertion failure"); 11082 this.checkDuplicateExports(node, id.name); 11083 } else if (node.declaration.type === "VariableDeclaration") { 11084 for (let _i4 = 0, _node$declaration$dec = node.declaration.declarations; _i4 < _node$declaration$dec.length; _i4++) { 11085 const declaration = _node$declaration$dec[_i4]; 11086 this.checkDeclaration(declaration.id); 11087 } 11088 } 11089 } 11090 } 11091 11092 const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; 11093 11094 if (currentContextDecorators.length) { 11095 const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression"); 11096 11097 if (!node.declaration || !isClass) { 11098 throw this.raise(node.start, "You can only use decorators on an export when exporting a class"); 11099 } 11100 11101 this.takeDecorators(node.declaration); 11102 } 11103 } 11104 11105 checkDeclaration(node) { 11106 if (node.type === "Identifier") { 11107 this.checkDuplicateExports(node, node.name); 11108 } else if (node.type === "ObjectPattern") { 11109 for (let _i5 = 0, _node$properties = node.properties; _i5 < _node$properties.length; _i5++) { 11110 const prop = _node$properties[_i5]; 11111 this.checkDeclaration(prop); 11112 } 11113 } else if (node.type === "ArrayPattern") { 11114 for (let _i6 = 0, _node$elements = node.elements; _i6 < _node$elements.length; _i6++) { 11115 const elem = _node$elements[_i6]; 11116 11117 if (elem) { 11118 this.checkDeclaration(elem); 11119 } 11120 } 11121 } else if (node.type === "ObjectProperty") { 11122 this.checkDeclaration(node.value); 11123 } else if (node.type === "RestElement") { 11124 this.checkDeclaration(node.argument); 11125 } else if (node.type === "AssignmentPattern") { 11126 this.checkDeclaration(node.left); 11127 } 11128 } 11129 11130 checkDuplicateExports(node, name) { 11131 if (this.state.exportedIdentifiers.indexOf(name) > -1) { 11132 throw this.raise(node.start, name === "default" ? "Only one default export allowed per module." : `\`${name}\` has already been exported. Exported identifiers must be unique.`); 11133 } 11134 11135 this.state.exportedIdentifiers.push(name); 11136 } 11137 11138 parseExportSpecifiers() { 11139 const nodes = []; 11140 let first = true; 11141 this.expect(types.braceL); 11142 11143 while (!this.eat(types.braceR)) { 11144 if (first) { 11145 first = false; 11146 } else { 11147 this.expect(types.comma); 11148 if (this.eat(types.braceR)) break; 11149 } 11150 11151 const node = this.startNode(); 11152 node.local = this.parseIdentifier(true); 11153 node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone(); 11154 nodes.push(this.finishNode(node, "ExportSpecifier")); 11155 } 11156 11157 return nodes; 11158 } 11159 11160 parseImport(node) { 11161 node.specifiers = []; 11162 11163 if (!this.match(types.string)) { 11164 const hasDefault = this.maybeParseDefaultImportSpecifier(node); 11165 const parseNext = !hasDefault || this.eat(types.comma); 11166 const hasStar = parseNext && this.maybeParseStarImportSpecifier(node); 11167 if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node); 11168 this.expectContextual("from"); 11169 } 11170 11171 node.source = this.parseImportSource(); 11172 this.semicolon(); 11173 return this.finishNode(node, "ImportDeclaration"); 11174 } 11175 11176 parseImportSource() { 11177 if (!this.match(types.string)) this.unexpected(); 11178 return this.parseExprAtom(); 11179 } 11180 11181 shouldParseDefaultImport(node) { 11182 return this.match(types.name); 11183 } 11184 11185 parseImportSpecifierLocal(node, specifier, type, contextDescription) { 11186 specifier.local = this.parseIdentifier(); 11187 this.checkLVal(specifier.local, BIND_LEXICAL, undefined, contextDescription); 11188 node.specifiers.push(this.finishNode(specifier, type)); 11189 } 11190 11191 maybeParseDefaultImportSpecifier(node) { 11192 if (this.shouldParseDefaultImport(node)) { 11193 this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier", "default import specifier"); 11194 return true; 11195 } 11196 11197 return false; 11198 } 11199 11200 maybeParseStarImportSpecifier(node) { 11201 if (this.match(types.star)) { 11202 const specifier = this.startNode(); 11203 this.next(); 11204 this.expectContextual("as"); 11205 this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier", "import namespace specifier"); 11206 return true; 11207 } 11208 11209 return false; 11210 } 11211 11212 parseNamedImportSpecifiers(node) { 11213 let first = true; 11214 this.expect(types.braceL); 11215 11216 while (!this.eat(types.braceR)) { 11217 if (first) { 11218 first = false; 11219 } else { 11220 if (this.eat(types.colon)) { 11221 this.unexpected(null, "ES2015 named imports do not destructure. " + "Use another statement for destructuring after the import."); 11222 } 11223 11224 this.expect(types.comma); 11225 if (this.eat(types.braceR)) break; 11226 } 11227 11228 this.parseImportSpecifier(node); 11229 } 11230 } 11231 11232 parseImportSpecifier(node) { 11233 const specifier = this.startNode(); 11234 specifier.imported = this.parseIdentifier(true); 11235 11236 if (this.eatContextual("as")) { 11237 specifier.local = this.parseIdentifier(); 11238 } else { 11239 this.checkReservedWord(specifier.imported.name, specifier.start, true, true); 11240 specifier.local = specifier.imported.__clone(); 11241 } 11242 11243 this.checkLVal(specifier.local, BIND_LEXICAL, undefined, "import specifier"); 11244 node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); 11245 } 11246 11247} 11248 11249class Parser extends StatementParser { 11250 constructor(options, input) { 11251 options = getOptions(options); 11252 super(options, input); 11253 const ScopeHandler = this.getScopeHandler(); 11254 this.options = options; 11255 this.inModule = this.options.sourceType === "module"; 11256 this.scope = new ScopeHandler(this.raise.bind(this), this.inModule); 11257 this.plugins = pluginsMap(this.options.plugins); 11258 this.filename = options.sourceFilename; 11259 } 11260 11261 getScopeHandler() { 11262 return ScopeHandler; 11263 } 11264 11265 parse() { 11266 this.scope.enter(SCOPE_PROGRAM); 11267 const file = this.startNode(); 11268 const program = this.startNode(); 11269 this.nextToken(); 11270 return this.parseTopLevel(file, program); 11271 } 11272 11273} 11274 11275function pluginsMap(plugins) { 11276 const pluginMap = new Map(); 11277 11278 for (let _i = 0; _i < plugins.length; _i++) { 11279 const plugin = plugins[_i]; 11280 const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}]; 11281 if (!pluginMap.has(name)) pluginMap.set(name, options || {}); 11282 } 11283 11284 return pluginMap; 11285} 11286 11287function parse(input, options) { 11288 if (options && options.sourceType === "unambiguous") { 11289 options = Object.assign({}, options); 11290 11291 try { 11292 options.sourceType = "module"; 11293 const parser = getParser(options, input); 11294 const ast = parser.parse(); 11295 if (!parser.sawUnambiguousESM) ast.program.sourceType = "script"; 11296 return ast; 11297 } catch (moduleError) { 11298 try { 11299 options.sourceType = "script"; 11300 return getParser(options, input).parse(); 11301 } catch (scriptError) {} 11302 11303 throw moduleError; 11304 } 11305 } else { 11306 return getParser(options, input).parse(); 11307 } 11308} 11309function parseExpression(input, options) { 11310 const parser = getParser(options, input); 11311 11312 if (parser.options.strictMode) { 11313 parser.state.strict = true; 11314 } 11315 11316 return parser.getExpression(); 11317} 11318 11319function getParser(options, input) { 11320 let cls = Parser; 11321 11322 if (options && options.plugins) { 11323 validatePlugins(options.plugins); 11324 cls = getParserClass(options.plugins); 11325 } 11326 11327 return new cls(options, input); 11328} 11329 11330const parserClassCache = {}; 11331 11332function getParserClass(pluginsFromOptions) { 11333 const pluginList = mixinPluginNames.filter(name => hasPlugin(pluginsFromOptions, name)); 11334 const key = pluginList.join("/"); 11335 let cls = parserClassCache[key]; 11336 11337 if (!cls) { 11338 cls = Parser; 11339 11340 for (let _i = 0; _i < pluginList.length; _i++) { 11341 const plugin = pluginList[_i]; 11342 cls = mixinPlugins[plugin](cls); 11343 } 11344 11345 parserClassCache[key] = cls; 11346 } 11347 11348 return cls; 11349} 11350 11351exports.parse = parse; 11352exports.parseExpression = parseExpression; 11353exports.tokTypes = types; 11354