• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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