• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /**
2   * Copyright (c) 2021 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   * http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #include <ir/astNode.h>
17  #include <ir/base/classDefinition.h>
18  #include <ir/base/decorator.h>
19  #include <ir/base/metaProperty.h>
20  #include <ir/base/methodDefinition.h>
21  #include <ir/base/property.h>
22  #include <ir/base/scriptFunction.h>
23  #include <ir/base/spreadElement.h>
24  #include <ir/base/templateElement.h>
25  #include <ir/expression.h>
26  #include <ir/expressions/arrayExpression.h>
27  #include <ir/expressions/arrowFunctionExpression.h>
28  #include <ir/expressions/assignmentExpression.h>
29  #include <ir/expressions/awaitExpression.h>
30  #include <ir/expressions/binaryExpression.h>
31  #include <ir/expressions/callExpression.h>
32  #include <ir/expressions/chainExpression.h>
33  #include <ir/expressions/classExpression.h>
34  #include <ir/expressions/conditionalExpression.h>
35  #include <ir/expressions/functionExpression.h>
36  #include <ir/expressions/identifier.h>
37  #include <ir/expressions/importExpression.h>
38  #include <ir/expressions/literals/bigIntLiteral.h>
39  #include <ir/expressions/literals/booleanLiteral.h>
40  #include <ir/expressions/literals/nullLiteral.h>
41  #include <ir/expressions/literals/numberLiteral.h>
42  #include <ir/expressions/literals/regExpLiteral.h>
43  #include <ir/expressions/literals/stringLiteral.h>
44  #include <ir/expressions/memberExpression.h>
45  #include <ir/expressions/newExpression.h>
46  #include <ir/expressions/objectExpression.h>
47  #include <ir/expressions/omittedExpression.h>
48  #include <ir/expressions/sequenceExpression.h>
49  #include <ir/expressions/superExpression.h>
50  #include <ir/expressions/taggedTemplateExpression.h>
51  #include <ir/expressions/templateLiteral.h>
52  #include <ir/expressions/thisExpression.h>
53  #include <ir/expressions/unaryExpression.h>
54  #include <ir/expressions/updateExpression.h>
55  #include <ir/expressions/yieldExpression.h>
56  #include <ir/statements/blockStatement.h>
57  #include <ir/ts/tsAsExpression.h>
58  #include <ir/ts/tsNonNullExpression.h>
59  #include <ir/ts/tsPrivateIdentifier.h>
60  #include <ir/ts/tsTypeAssertion.h>
61  #include <ir/ts/tsTypeParameter.h>
62  #include <ir/ts/tsTypeParameterDeclaration.h>
63  #include <ir/ts/tsTypeParameterInstantiation.h>
64  #include <ir/ts/tsTypeReference.h>
65  #include <ir/validationInfo.h>
66  #include <lexer/lexer.h>
67  #include <lexer/regexp/regexp.h>
68  #include <lexer/token/letters.h>
69  #include <lexer/token/sourceLocation.h>
70  #include <lexer/token/token.h>
71  #include <macros.h>
72  
73  #include <memory>
74  
75  #include "parserImpl.h"
76  
77  namespace panda::es2panda::parser {
78  
ParseYieldExpression()79  ir::YieldExpression *ParserImpl::ParseYieldExpression()
80  {
81      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD);
82  
83      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
84      lexer::SourcePosition endLoc = lexer_->GetToken().End();
85  
86      if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) {
87          ThrowSyntaxError("Unexpected identifier");
88      }
89  
90      lexer_->NextToken();
91  
92      bool isDelegate = false;
93      ir::Expression *argument = nullptr;
94  
95      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY && !lexer_->GetToken().NewLine()) {
96          isDelegate = true;
97          lexer_->NextToken();
98  
99          argument = ParseExpression();
100          endLoc = argument->End();
101      } else if (!lexer_->GetToken().NewLine() && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
102                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS &&
103                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET &&
104                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
105                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
106                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
107                 lexer_->GetToken().Type() != lexer::TokenType::EOS) {
108          argument = ParseExpression();
109          endLoc = argument->End();
110      }
111  
112      auto *yieldNode = AllocNode<ir::YieldExpression>(argument, isDelegate);
113      yieldNode->SetRange({startLoc, endLoc});
114  
115      return yieldNode;
116  }
117  
ParsePotentialExpressionSequence(ir::Expression * expr,ExpressionParseFlags flags)118  ir::Expression *ParserImpl::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
119  {
120      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
121          (flags & ExpressionParseFlags::ACCEPT_COMMA)) {
122          return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST));
123      }
124  
125      return expr;
126  }
127  
ParseTsAsExpression(ir::Expression * expr,ExpressionParseFlags flags)128  ir::TSAsExpression *ParserImpl::ParseTsAsExpression(ir::Expression *expr, [[maybe_unused]] ExpressionParseFlags flags)
129  {
130      lexer_->NextToken();  // eat 'as'
131      TypeAnnotationParsingOptions options =
132          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::ALLOW_CONST;
133      ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options);
134  
135      bool isConst = false;
136      if (typeAnnotation->IsTSTypeReference() && typeAnnotation->AsTSTypeReference()->TypeName()->IsIdentifier()) {
137          const util::StringView &refName = typeAnnotation->AsTSTypeReference()->TypeName()->AsIdentifier()->Name();
138          if (refName.Is("const")) {
139              isConst = true;
140          }
141      }
142  
143      lexer::SourcePosition startLoc = expr->Start();
144      auto *asExpr = AllocNode<ir::TSAsExpression>(expr, typeAnnotation, isConst);
145      asExpr->SetRange({startLoc, lexer_->GetToken().End()});
146  
147      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
148          lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS &&
149          !(flags & ExpressionParseFlags::EXP_DISALLOW_AS)) {
150          return ParseTsAsExpression(asExpr, flags);
151      }
152  
153      return asExpr;
154  }
155  
ParseExpression(ExpressionParseFlags flags)156  ir::Expression *ParserImpl::ParseExpression(ExpressionParseFlags flags)
157  {
158      if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD && !(flags & ExpressionParseFlags::DISALLOW_YIELD)) {
159          ir::YieldExpression *yieldExpr = ParseYieldExpression();
160  
161          return ParsePotentialExpressionSequence(yieldExpr, flags);
162      }
163  
164      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
165          const auto startPos = lexer_->Save();
166  
167          // TODO(rsipka): ParseTsGenericArrowFunction and ParseTsTypeAssertion might be in a common function
168          ir::Expression *expr = nullptr;
169          try {
170              expr = ParseTsGenericArrowFunction();
171          } catch ([[maybe_unused]] const class Error &e) {
172              expr = nullptr;
173          }
174          if (expr != nullptr) {
175              return expr;
176          }
177          lexer_->Rewind(startPos);
178      }
179  
180      ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
181      ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
182  
183      if (lexer_->GetToken().NewLine()) {
184          return assignmentExpression;
185      }
186  
187      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
188          (flags & ExpressionParseFlags::ACCEPT_COMMA)) {
189          return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST),
190                                         flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN);
191      }
192  
193      return assignmentExpression;
194  }
195  
ParseArrayExpression(ExpressionParseFlags flags)196  ir::Expression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags)
197  {
198      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
199  
200      ArenaVector<ir::Expression *> elements(Allocator()->Adapter());
201  
202      lexer_->NextToken();
203  
204      bool trailingComma = false;
205      bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
206  
207      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
208          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
209              auto *omitted = AllocNode<ir::OmittedExpression>();
210              omitted->SetRange(lexer_->GetToken().Loc());
211              elements.push_back(omitted);
212              lexer_->NextToken();
213              continue;
214          }
215  
216          ir::Expression *element {};
217          if (inPattern) {
218              element = ParsePatternElement();
219          } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
220              element = ParseSpreadElement(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
221          } else {
222              element = ParseExpression(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
223          }
224  
225          bool containsRest = element->IsRestElement();
226  
227          elements.push_back(element);
228  
229          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
230              if (containsRest) {
231                  ThrowSyntaxError("Rest element must be last element", startLoc);
232              }
233  
234              lexer_->NextToken();  // eat comma
235  
236              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
237                  trailingComma = true;
238                  break;
239              }
240  
241              continue;
242          }
243  
244          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
245              ThrowSyntaxError("Unexpected token, expected ',' or ']'");
246          }
247      }
248  
249      auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION;
250      auto *arrayExpressionNode = AllocNode<ir::ArrayExpression>(nodeType, std::move(elements), trailingComma);
251      arrayExpressionNode->SetRange({startLoc, lexer_->GetToken().End()});
252      lexer_->NextToken();
253  
254      if (inPattern) {
255          arrayExpressionNode->SetDeclaration();
256      }
257  
258      if (Extension() == ScriptExtension::TS && (flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN) &&
259          lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
260          context_.Status() |= ParserStatus::FUNCTION_PARAM;
261          ParsePotentialTsFunctionParameter(ExpressionParseFlags::NO_OPTS, arrayExpressionNode);
262      }
263  
264      if (!(flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN)) {
265          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
266              !arrayExpressionNode->ConvertibleToArrayPattern()) {
267              ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", arrayExpressionNode->Start());
268          } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
269              ir::ValidationInfo info = arrayExpressionNode->ValidateExpression();
270              if (info.Fail()) {
271                  ThrowSyntaxError(info.msg.Utf8(), info.pos);
272              }
273          }
274      }
275  
276      return arrayExpressionNode;
277  }
278  
ValidateArrowParameter(ir::Expression * expr)279  ParserStatus ParserImpl::ValidateArrowParameter(ir::Expression *expr)
280  {
281      switch (expr->Type()) {
282          case ir::AstNodeType::SPREAD_ELEMENT: {
283              if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
284                  ThrowSyntaxError("Invalid rest element.");
285              }
286  
287              [[fallthrough]];
288          }
289          case ir::AstNodeType::REST_ELEMENT: {
290              ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
291              return ParserStatus::HAS_COMPLEX_PARAM;
292          }
293          case ir::AstNodeType::IDENTIFIER: {
294              const util::StringView &identifier = expr->AsIdentifier()->Name();
295  
296              if (identifier.Is("arguments")) {
297                  ThrowSyntaxError("Binding 'arguments' in strict mode is invalid");
298              } else if (identifier.Is("eval")) {
299                  ThrowSyntaxError("Binding 'eval' in strict mode is invalid");
300              }
301  
302              ValidateArrowParameterBindings(expr);
303              return ParserStatus::NO_OPTS;
304          }
305          case ir::AstNodeType::OBJECT_EXPRESSION: {
306              ir::ObjectExpression *objectPattern = expr->AsObjectExpression();
307  
308              if (!objectPattern->ConvertibleToObjectPattern()) {
309                  ThrowSyntaxError("Invalid destructuring assignment target");
310              }
311  
312              ValidateArrowParameterBindings(expr);
313              return ParserStatus::HAS_COMPLEX_PARAM;
314          }
315          case ir::AstNodeType::ARRAY_EXPRESSION: {
316              ir::ArrayExpression *arrayPattern = expr->AsArrayExpression();
317  
318              if (!arrayPattern->ConvertibleToArrayPattern()) {
319                  ThrowSyntaxError("Invalid destructuring assignment target");
320              }
321  
322              ValidateArrowParameterBindings(expr);
323              return ParserStatus::HAS_COMPLEX_PARAM;
324          }
325          case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
326              auto *assignmentExpr = expr->AsAssignmentExpression();
327              if (assignmentExpr->Right()->IsYieldExpression()) {
328                  ThrowSyntaxError("yield is not allowed in arrow function parameters");
329              }
330  
331              if (assignmentExpr->Right()->IsAwaitExpression()) {
332                  ThrowSyntaxError("await is not allowed in arrow function parameters");
333              }
334  
335              if (!assignmentExpr->ConvertibleToAssignmentPattern()) {
336                  ThrowSyntaxError("Invalid destructuring assignment target");
337              }
338  
339              ValidateArrowParameterBindings(expr);
340              return ParserStatus::HAS_COMPLEX_PARAM;
341          }
342          default: {
343              break;
344          }
345      }
346      ThrowSyntaxError("Insufficient formal parameter in arrow function.");
347      return ParserStatus::NO_OPTS;
348  }
349  
ParseArrowFunctionExpressionBody(ArrowFunctionContext * arrowFunctionContext,binder::FunctionScope * functionScope,ArrowFunctionDescriptor * desc,ir::TSTypeParameterDeclaration * typeParamDecl,ir::Expression * returnTypeAnnotation)350  ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowFunctionContext *arrowFunctionContext,
351                                                                            binder::FunctionScope *functionScope,
352                                                                            ArrowFunctionDescriptor *desc,
353                                                                            ir::TSTypeParameterDeclaration *typeParamDecl,
354                                                                            ir::Expression *returnTypeAnnotation)
355  {
356      context_.Status() |= desc->newStatus;
357  
358      functionScope->BindParamScope(desc->paramScope);
359      desc->paramScope->BindFunctionScope(functionScope);
360  
361      lexer_->NextToken();  // eat '=>'
362      ir::ScriptFunction *funcNode {};
363  
364      ir::AstNode *body = nullptr;
365      lexer::SourcePosition endLoc;
366      lexer::SourcePosition bodyStart = lexer_->GetToken().Start();
367  
368      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
369          body = ParseExpression();
370          endLoc = body->AsExpression()->End();
371          arrowFunctionContext->AddFlag(ir::ScriptFunctionFlags::EXPRESSION);
372      } else {
373          lexer_->NextToken();
374          auto statements = ParseStatementList();
375          body = AllocNode<ir::BlockStatement>(functionScope, std::move(statements));
376          body->SetRange({bodyStart, lexer_->GetToken().End()});
377  
378          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
379              ThrowSyntaxError("Expected a '}'");
380          }
381  
382          lexer_->NextToken();
383          endLoc = body->End();
384      }
385  
386      funcNode = AllocNode<ir::ScriptFunction>(functionScope, std::move(desc->params), typeParamDecl, body,
387                                               returnTypeAnnotation, arrowFunctionContext->Flags(), false,
388                                               Extension() == ScriptExtension::TS);
389      funcNode->SetRange({desc->startLoc, endLoc});
390      functionScope->BindNode(funcNode);
391      desc->paramScope->BindNode(funcNode);
392  
393      auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(funcNode);
394      arrowFuncNode->SetRange(funcNode->Range());
395  
396      return arrowFuncNode;
397  }
398  
ConvertToArrowParameter(ir::Expression * expr,bool isAsync,binder::FunctionParamScope * paramScope)399  ArrowFunctionDescriptor ParserImpl::ConvertToArrowParameter(ir::Expression *expr, bool isAsync,
400                                                              binder::FunctionParamScope *paramScope)
401  {
402      auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
403      ArenaVector<ir::Expression *> params(Allocator()->Adapter());
404  
405      if (!expr) {
406          return ArrowFunctionDescriptor {std::move(params), paramScope, lexer_->GetToken().Start(), arrowStatus};
407      }
408  
409      switch (expr->Type()) {
410          case ir::AstNodeType::REST_ELEMENT:
411          case ir::AstNodeType::IDENTIFIER:
412          case ir::AstNodeType::OBJECT_EXPRESSION:
413          case ir::AstNodeType::ASSIGNMENT_EXPRESSION:
414          case ir::AstNodeType::ARRAY_EXPRESSION: {
415              arrowStatus |= ValidateArrowParameter(expr);
416  
417              params.push_back(expr);
418              break;
419          }
420          case ir::AstNodeType::SEQUENCE_EXPRESSION: {
421              auto &sequence = expr->AsSequenceExpression()->Sequence();
422  
423              for (auto *it : sequence) {
424                  arrowStatus |= ValidateArrowParameter(it);
425              }
426  
427              params.swap(sequence);
428              break;
429          }
430          case ir::AstNodeType::CALL_EXPRESSION: {
431              if (isAsync) {
432                  auto &arguments = expr->AsCallExpression()->Arguments();
433  
434                  for (auto *it : arguments) {
435                      arrowStatus |= ValidateArrowParameter(it);
436                  }
437  
438                  params.swap(arguments);
439                  break;
440              }
441  
442              [[fallthrough]];
443          }
444          default: {
445              ThrowSyntaxError("Unexpected token, arrow (=>)");
446          }
447      }
448  
449      for (const auto *param : params) {
450          Binder()->AddParamDecl(param);
451      }
452  
453      return ArrowFunctionDescriptor {std::move(params), paramScope, expr->Start(), arrowStatus};
454  }
455  
ParseArrowFunctionExpression(ir::Expression * expr,ir::TSTypeParameterDeclaration * typeParamDecl,ir::Expression * returnTypeAnnotation,bool isAsync)456  ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpression(ir::Expression *expr,
457                                                                        ir::TSTypeParameterDeclaration *typeParamDecl,
458                                                                        ir::Expression *returnTypeAnnotation,
459                                                                        bool isAsync)
460  {
461      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW);
462  
463      if (lexer_->GetToken().NewLine()) {
464          ThrowSyntaxError(
465              "expected '=>' on the same line after an argument list, "
466              "got line terminator");
467      }
468  
469      ArrowFunctionContext arrowFunctionContext(this, isAsync);
470      FunctionParameterContext functionParamContext(&context_, Binder());
471      ArrowFunctionDescriptor desc =
472          ConvertToArrowParameter(expr, isAsync, functionParamContext.LexicalScope().GetScope());
473  
474      auto functionCtx = binder::LexicalScope<binder::FunctionScope>(Binder());
475      return ParseArrowFunctionExpressionBody(&arrowFunctionContext, functionCtx.GetScope(), &desc, typeParamDecl,
476                                              returnTypeAnnotation);
477  }
478  
ParseTsGenericArrowFunction()479  ir::ArrowFunctionExpression *ParserImpl::ParseTsGenericArrowFunction()
480  {
481      ArrowFunctionContext arrowFunctionContext(this, false);
482  
483      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
484      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
485  
486      ir::TSTypeParameterDeclaration *typeParamDecl = ParseTsTypeParameterDeclaration(false);
487  
488      if (typeParamDecl == nullptr || lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
489          return nullptr;
490      }
491  
492      FunctionParameterContext funcParamContext(&context_, Binder());
493      ArenaVector<ir::Expression *> params = ParseFunctionParams(true);
494  
495      ParserStatus arrowStatus = ParserStatus::NO_OPTS;
496  
497      if (std::any_of(params.begin(), params.end(), [](const auto *param) { return !param->IsIdentifier(); })) {
498          arrowStatus = ParserStatus::HAS_COMPLEX_PARAM;
499      }
500  
501      ir::Expression *returnTypeAnnotation = nullptr;
502      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
503          lexer_->NextToken();  // eat ':'
504          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
505          returnTypeAnnotation = ParseTsTypeAnnotation(&options);
506      }
507  
508      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
509          return nullptr;
510      }
511  
512      ArrowFunctionDescriptor desc(std::move(params), funcParamContext.LexicalScope().GetScope(), startLoc, arrowStatus);
513  
514      auto functionCtx = binder::LexicalScope<binder::FunctionScope>(Binder());
515      return ParseArrowFunctionExpressionBody(&arrowFunctionContext, functionCtx.GetScope(), &desc, typeParamDecl,
516                                              returnTypeAnnotation);
517  }
518  
ParseTsTypeAssertion(ExpressionParseFlags flags)519  ir::TSTypeAssertion *ParserImpl::ParseTsTypeAssertion(ExpressionParseFlags flags)
520  {
521      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
522      lexer::SourcePosition start = lexer_->GetToken().Start();
523      lexer_->NextToken();  // eat '<'
524  
525      TypeAnnotationParsingOptions options =
526          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::ALLOW_CONST;
527      ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options);
528  
529      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
530          return nullptr;
531      }
532  
533      lexer_->NextToken();  // eat '>'
534      ir::Expression *expression = ParseUnaryOrPrefixUpdateExpression(flags);
535      auto *typeAssertion = AllocNode<ir::TSTypeAssertion>(typeAnnotation, expression);
536      typeAssertion->SetRange({start, lexer_->GetToken().End()});
537  
538      return typeAssertion;
539  }
540  
ParseCoverParenthesizedExpressionAndArrowParameterList()541  ir::Expression *ParserImpl::ParseCoverParenthesizedExpressionAndArrowParameterList()
542  {
543      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
544      lexer::SourcePosition start = lexer_->GetToken().Start();
545      lexer_->NextToken();
546      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
547  
548      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
549          ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
550  
551          restElement->SetGrouped();
552          restElement->SetStart(start);
553  
554          if (Extension() == ScriptExtension::TS &&
555              lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
556              ParsePotentialTsFunctionParameter(ExpressionParseFlags::IN_REST, restElement);
557          }
558  
559          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
560              ThrowSyntaxError("Rest parameter must be last formal parameter");
561          }
562  
563          lexer_->NextToken();
564  
565          ir::Expression *returnTypeAnnotation = nullptr;
566          if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
567              lexer_->NextToken();  // eat ':'
568              options |= TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
569              returnTypeAnnotation = ParseTsTypeAnnotation(&options);
570              options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
571          }
572  
573          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
574              ThrowSyntaxError("Unexpected token");
575          }
576  
577          return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
578      }
579  
580      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
581          lexer_->NextToken();
582  
583          ir::Expression *returnTypeAnnotation = nullptr;
584          if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
585              lexer_->NextToken();  // eat ':'
586              options |= TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
587              returnTypeAnnotation = ParseTsTypeAnnotation(&options);
588              options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
589          }
590  
591          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
592              ThrowSyntaxError("Unexpected token");
593          }
594  
595          auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
596          arrowExpr->SetStart(start);
597          arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
598  
599          return arrowExpr;
600      }
601  
602      ir::Expression *expr =
603          ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
604                          ExpressionParseFlags::POTENTIALLY_IN_PATTERN | ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN);
605  
606      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
607          ThrowSyntaxError("Unexpected token, expected ')'");
608      }
609  
610      expr->SetGrouped();
611      expr->SetRange({start, lexer_->GetToken().End()});
612      lexer_->NextToken();
613  
614      if (Extension() == ScriptExtension::TS && ((context_.Status() & ParserStatus::FUNCTION_PARAM) ||
615                                                 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON)) {
616          context_.Status() &= ~ParserStatus::FUNCTION_PARAM;
617  
618          ir::Expression *returnTypeAnnotation = nullptr;
619          const auto startPos = lexer_->Save();
620  
621          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
622              lexer_->NextToken();  // eat ':'
623              options &= ~TypeAnnotationParsingOptions::THROW_ERROR;
624              options |= TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
625              returnTypeAnnotation = ParseTsTypeAnnotation(&options);
626              options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
627  
628              if (returnTypeAnnotation == nullptr) {
629                  lexer_->Rewind(startPos);
630                  return expr;
631              }
632          }
633  
634          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
635              lexer_->Rewind(startPos);
636              return expr;
637          }
638  
639          return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
640      }
641  
642      return expr;
643  }
644  
CheckInvalidDestructuring(const ir::AstNode * object) const645  void ParserImpl::CheckInvalidDestructuring(const ir::AstNode *object) const
646  {
647      object->Iterate([this](ir::AstNode *childNode) -> void {
648          switch (childNode->Type()) {
649              case ir::AstNodeType::ASSIGNMENT_PATTERN: {
650                  ThrowSyntaxError("Invalid property initializer");
651                  break;
652              }
653              case ir::AstNodeType::REST_ELEMENT:
654              case ir::AstNodeType::PROPERTY:
655              case ir::AstNodeType::OBJECT_EXPRESSION: {
656                  CheckInvalidDestructuring(childNode);
657                  break;
658              }
659              default: {
660                  break;
661              }
662          }
663      });
664  }
665  
ValidateParenthesizedExpression(ir::Expression * lhsExpression)666  void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression)
667  {
668      switch (lhsExpression->Type()) {
669          case ir::AstNodeType::IDENTIFIER: {
670              if (lhsExpression->AsIdentifier()->TypeAnnotation() != nullptr) {
671                  ThrowSyntaxError("'=>' expected.");
672              }
673              break;
674          }
675          case ir::AstNodeType::MEMBER_EXPRESSION: {
676              break;
677          }
678          case ir::AstNodeType::ARRAY_EXPRESSION: {
679              if (lhsExpression->AsArrayExpression()->TypeAnnotation() != nullptr) {
680                  ThrowSyntaxError("'=>' expected.");
681              }
682              auto info = lhsExpression->AsArrayExpression()->ValidateExpression();
683              if (info.Fail()) {
684                  ThrowSyntaxError(info.msg.Utf8(), info.pos);
685              }
686              break;
687          }
688          case ir::AstNodeType::OBJECT_EXPRESSION: {
689              if (lhsExpression->AsObjectExpression()->TypeAnnotation() != nullptr) {
690                  ThrowSyntaxError("'=>' expected.");
691              }
692              auto info = lhsExpression->AsObjectExpression()->ValidateExpression();
693              if (info.Fail()) {
694                  ThrowSyntaxError(info.msg.Utf8(), info.pos);
695              }
696              break;
697          }
698          case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
699              if (lhsExpression->AsAssignmentExpression()->ConvertibleToAssignmentPattern(false)) {
700                  break;
701              }
702              [[fallthrough]];
703          }
704          case ir::AstNodeType::SPREAD_ELEMENT: {
705              ThrowSyntaxError("Invalid left-hand side in assignment expression");
706          }
707          default: {
708              break;
709          }
710      }
711  }
712  
ParseAssignmentExpression(ir::Expression * lhsExpression,ExpressionParseFlags flags)713  ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpression, ExpressionParseFlags flags)
714  {
715      lexer::TokenType tokenType = lexer_->GetToken().Type();
716      if (lhsExpression->IsGrouped() && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
717          if (lhsExpression->IsSequenceExpression()) {
718              for (auto *seq : lhsExpression->AsSequenceExpression()->Sequence()) {
719                  ValidateParenthesizedExpression(seq);
720              }
721          } else {
722              ValidateParenthesizedExpression(lhsExpression);
723          }
724      }
725  
726      switch (tokenType) {
727          case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: {
728              lexer_->NextToken();
729              ir::Expression *consequent = ParseExpression();
730  
731              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
732                  ThrowSyntaxError("Unexpected token, expected ':'");
733              }
734  
735              lexer_->NextToken();
736              ir::Expression *alternate = ParseExpression();
737  
738              auto *conditionalExpr = AllocNode<ir::ConditionalExpression>(lhsExpression, consequent, alternate);
739              conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()});
740              return conditionalExpr;
741          }
742          case lexer::TokenType::PUNCTUATOR_ARROW: {
743              if (lexer_->GetToken().NewLine()) {
744                  ThrowSyntaxError("Uncaught SyntaxError: expected expression, got '=>'");
745              }
746  
747              return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false);
748          }
749          case lexer::TokenType::KEYW_IN: {
750              if (flags & ExpressionParseFlags::STOP_AT_IN) {
751                  break;
752              }
753  
754              [[fallthrough]];
755          }
756          case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING:
757          case lexer::TokenType::PUNCTUATOR_LOGICAL_OR:
758          case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
759          case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
760          case lexer::TokenType::PUNCTUATOR_BITWISE_XOR:
761          case lexer::TokenType::PUNCTUATOR_BITWISE_AND:
762          case lexer::TokenType::PUNCTUATOR_EQUAL:
763          case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
764          case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
765          case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
766          case lexer::TokenType::PUNCTUATOR_LESS_THAN:
767          case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
768          case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
769          case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
770          case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
771          case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
772          case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
773          case lexer::TokenType::PUNCTUATOR_PLUS:
774          case lexer::TokenType::PUNCTUATOR_MINUS:
775          case lexer::TokenType::PUNCTUATOR_MULTIPLY:
776          case lexer::TokenType::PUNCTUATOR_DIVIDE:
777          case lexer::TokenType::PUNCTUATOR_MOD:
778          case lexer::TokenType::KEYW_INSTANCEOF:
779          case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
780              ir::Expression *binaryExpression = ParseBinaryExpression(lhsExpression);
781  
782              return ParseAssignmentExpression(binaryExpression);
783          }
784          case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: {
785              ValidateAssignmentTarget(flags, lhsExpression);
786  
787              lexer_->NextToken();
788              ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
789  
790              auto *binaryAssignmentExpression =
791                  AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
792  
793              binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
794              return binaryAssignmentExpression;
795          }
796          case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL:
797          case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL:
798          case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL:
799          case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL:
800          case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL:
801          case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL:
802          case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
803          case lexer::TokenType::PUNCTUATOR_MOD_EQUAL:
804          case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL:
805          case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL:
806          case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL:
807          case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL:
808          case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL:
809          case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL:
810          case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: {
811              ValidateLvalueAssignmentTarget(lhsExpression);
812  
813              lexer_->NextToken();
814              ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
815  
816              auto *binaryAssignmentExpression =
817                  AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
818  
819              binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
820              return binaryAssignmentExpression;
821          }
822          case lexer::TokenType::LITERAL_IDENT: {
823              if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS &&
824                  !(flags & ExpressionParseFlags::EXP_DISALLOW_AS) && !lexer_->GetToken().NewLine()) {
825                  ir::Expression *asExpression = ParseTsAsExpression(lhsExpression, flags);
826                  return ParseAssignmentExpression(asExpression);
827              }
828              break;
829          }
830          default:
831              break;
832      }
833  
834      return lhsExpression;
835  }
836  
ParseTemplateLiteral()837  ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral()
838  {
839      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
840  
841      ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter());
842      ArenaVector<ir::Expression *> expressions(Allocator()->Adapter());
843  
844      while (true) {
845          lexer_->ResetTokenEnd();
846          const auto startPos = lexer_->Save();
847  
848          lexer_->ScanString<LEX_CHAR_BACK_TICK>();
849          util::StringView cooked = lexer_->GetToken().String();
850  
851          lexer_->Rewind(startPos);
852          auto [raw, end, scanExpression] = lexer_->ScanTemplateString();
853  
854          auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked);
855          element->SetRange({lexer::SourcePosition {startPos.iterator.Index(), startPos.line},
856                             lexer::SourcePosition {end, lexer_->Line()}});
857          quasis.push_back(element);
858  
859          if (!scanExpression) {
860              lexer_->ScanTemplateStringEnd();
861              break;
862          }
863  
864          ir::Expression *expression = nullptr;
865  
866          {
867              lexer::TemplateLiteralParserContext ctx(lexer_);
868              lexer_->PushTemplateContext(&ctx);
869              lexer_->NextToken();
870              expression = ParseExpression();
871          }
872  
873          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
874              ThrowSyntaxError("Unexpected token, expected '}'.");
875          }
876  
877          expressions.push_back(expression);
878      }
879  
880      auto *templateNode = AllocNode<ir::TemplateLiteral>(std::move(quasis), std::move(expressions));
881      templateNode->SetRange({startLoc, lexer_->GetToken().End()});
882  
883      lexer_->NextToken();
884  
885      return templateNode;
886  }
887  
ParseNewExpression()888  ir::NewExpression *ParserImpl::ParseNewExpression()
889  {
890      lexer::SourcePosition start = lexer_->GetToken().Start();
891  
892      lexer_->NextToken();  // eat new
893  
894      // parse callee part of NewExpression
895      ir::Expression *callee = ParseMemberExpression(true);
896      if (callee->IsImportExpression() && !callee->IsGrouped()) {
897          ThrowSyntaxError("Cannot use new with import(...)");
898      }
899  
900      // parse type params of NewExpression
901      lexer::SourcePosition endLoc = callee->End();
902      ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
903      if (Extension() == ScriptExtension::TS) {
904          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
905              lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
906          }
907          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
908              typeParamInst = ParseTsTypeParameterInstantiation();
909              if (typeParamInst != nullptr) {
910                  endLoc = typeParamInst->End();
911              }
912          }
913      }
914  
915      ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
916  
917      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
918          auto *newExprNode = AllocNode<ir::NewExpression>(callee, typeParamInst, std::move(arguments));
919          newExprNode->SetRange({start, endLoc});
920  
921          return newExprNode;
922      }
923  
924      lexer_->NextToken();  // eat left pranthesis
925  
926      // parse argument part of NewExpression
927      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
928          ir::Expression *argument = nullptr;
929  
930          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
931              argument = ParseSpreadElement();
932          } else {
933              argument = ParseExpression();
934          }
935  
936          arguments.push_back(argument);
937  
938          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
939              lexer_->NextToken();  // eat comma
940          }
941  
942          if (lexer_->GetToken().Type() == lexer::TokenType::EOS) {
943              ThrowSyntaxError("Unexpected token in argument parsing");
944          }
945      }
946  
947      auto *newExprNode = AllocNode<ir::NewExpression>(callee, typeParamInst, std::move(arguments));
948      newExprNode->SetRange({start, lexer_->GetToken().End()});
949  
950      lexer_->NextToken();
951  
952      return newExprNode;
953  }
954  
ParseLeftHandSideExpression(ExpressionParseFlags flags)955  ir::Expression *ParserImpl::ParseLeftHandSideExpression(ExpressionParseFlags flags)
956  {
957      return ParseMemberExpression(false, flags);
958  }
959  
ParsePotentialNewTarget()960  ir::MetaProperty *ParserImpl::ParsePotentialNewTarget()
961  {
962      lexer::SourceRange loc = lexer_->GetToken().Loc();
963  
964      if (lexer_->Lookahead() == LEX_CHAR_DOT) {
965          lexer_->NextToken();
966          lexer_->NextToken();
967  
968          if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && lexer_->GetToken().Ident().Is("target")) {
969              if (!(context_.Status() & ParserStatus::ALLOW_NEW_TARGET)) {
970                  ThrowSyntaxError("'new.Target' is not allowed here");
971              }
972  
973              if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) {
974                  ThrowSyntaxError("'new.Target' must not contain escaped characters");
975              }
976  
977              auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::NEW_TARGET);
978              metaProperty->SetRange(loc);
979              lexer_->NextToken();
980              return metaProperty;
981          }
982      }
983  
984      return nullptr;
985  }
986  
ParsePrimaryExpression(ExpressionParseFlags flags)987  ir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags)
988  {
989      switch (lexer_->GetToken().Type()) {
990          case lexer::TokenType::KEYW_IMPORT: {
991              return ParseImportExpression();
992          }
993          case lexer::TokenType::LITERAL_IDENT: {
994              auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
995              identNode->SetReference();
996              identNode->SetRange(lexer_->GetToken().Loc());
997  
998              lexer_->NextToken();
999  
1000              if (Extension() == ScriptExtension::TS && (flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN) &&
1001                  lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
1002                  context_.Status() |= ParserStatus::FUNCTION_PARAM;
1003                  ParsePotentialTsFunctionParameter(ExpressionParseFlags::NO_OPTS, identNode);
1004              }
1005  
1006              return identNode;
1007          }
1008          case lexer::TokenType::LITERAL_TRUE: {
1009              auto *trueNode = AllocNode<ir::BooleanLiteral>(true);
1010              trueNode->SetRange(lexer_->GetToken().Loc());
1011  
1012              lexer_->NextToken();
1013              return trueNode;
1014          }
1015          case lexer::TokenType::LITERAL_FALSE: {
1016              auto *falseNode = AllocNode<ir::BooleanLiteral>(false);
1017              falseNode->SetRange(lexer_->GetToken().Loc());
1018  
1019              lexer_->NextToken();
1020              return falseNode;
1021          }
1022          case lexer::TokenType::LITERAL_NULL: {
1023              auto *nullNode = AllocNode<ir::NullLiteral>();
1024              nullNode->SetRange(lexer_->GetToken().Loc());
1025  
1026              lexer_->NextToken();
1027              return nullNode;
1028          }
1029          case lexer::TokenType::LITERAL_NUMBER: {
1030              ir::Expression *numberNode = nullptr;
1031  
1032              if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
1033                  numberNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
1034              } else {
1035                  numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
1036              }
1037  
1038              numberNode->SetRange(lexer_->GetToken().Loc());
1039  
1040              lexer_->NextToken();
1041              return numberNode;
1042          }
1043          case lexer::TokenType::LITERAL_STRING: {
1044              auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
1045              stringNode->SetRange(lexer_->GetToken().Loc());
1046  
1047              lexer_->NextToken();
1048              return stringNode;
1049          }
1050          case lexer::TokenType::PUNCTUATOR_DIVIDE:
1051          case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: {
1052              lexer_->ResetTokenEnd();
1053              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL) {
1054                  lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_DIVIDE, 1);
1055              }
1056              auto regexp = lexer_->ScanRegExp();
1057  
1058              lexer::RegExpParser reParser(regexp, Allocator());
1059  
1060              try {
1061                  reParser.ParsePattern();
1062              } catch (lexer::RegExpError &e) {
1063                  ThrowSyntaxError(e.message.c_str());
1064              }
1065  
1066              auto *regexpNode = AllocNode<ir::RegExpLiteral>(regexp.patternStr, regexp.flagsStr);
1067              regexpNode->SetRange(lexer_->GetToken().Loc());
1068  
1069              lexer_->NextToken();
1070              return regexpNode;
1071          }
1072          case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1073              return ParseArrayExpression(CarryAllowTsParamAndPatternFlags(flags));
1074          }
1075          case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1076              return ParseCoverParenthesizedExpressionAndArrowParameterList();
1077          }
1078          case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1079              return ParseObjectExpression(CarryAllowTsParamAndPatternFlags(flags));
1080          }
1081          case lexer::TokenType::KEYW_FUNCTION: {
1082              return ParseFunctionExpression();
1083          }
1084          case lexer::TokenType::KEYW_CLASS: {
1085              lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1086              ir::ClassDefinition *classDefinition = ParseClassDefinition(false);
1087  
1088              auto *classExpr = AllocNode<ir::ClassExpression>(classDefinition);
1089              classExpr->SetRange({startLoc, classDefinition->End()});
1090  
1091              return classExpr;
1092          }
1093          case lexer::TokenType::KEYW_THIS: {
1094              auto *thisExprNode = AllocNode<ir::ThisExpression>();
1095              thisExprNode->SetRange(lexer_->GetToken().Loc());
1096  
1097              lexer_->NextToken();  // eat this
1098              return thisExprNode;
1099          }
1100          case lexer::TokenType::KEYW_SUPER: {
1101              auto *superExprNode = AllocNode<ir::SuperExpression>();
1102              superExprNode->SetRange(lexer_->GetToken().Loc());
1103  
1104              lexer_->NextToken();  // eat super
1105  
1106              if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD ||
1107                   lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) &&
1108                  (context_.Status() & ParserStatus::ALLOW_SUPER)) {
1109                  return superExprNode;
1110              }
1111  
1112              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1113                  (context_.Status() & ParserStatus::ALLOW_SUPER_CALL)) {
1114                  return superExprNode;
1115              }
1116  
1117              ThrowSyntaxError("Unexpected super keyword");
1118          }
1119          case lexer::TokenType::KEYW_NEW: {
1120              ir::MetaProperty *newTarget = ParsePotentialNewTarget();
1121  
1122              if (newTarget) {
1123                  return newTarget;
1124              }
1125  
1126              return ParseNewExpression();
1127          }
1128          case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1129              return ParseTemplateLiteral();
1130          }
1131          default: {
1132              break;
1133          }
1134      }
1135  
1136      ThrowSyntaxError("Primary expression expected");
1137      return nullptr;
1138  }
1139  
GetOperatorPrecedence(lexer::TokenType operatorType)1140  static size_t GetOperatorPrecedence(lexer::TokenType operatorType)
1141  {
1142      ASSERT(lexer::Token::IsBinaryToken(operatorType));
1143  
1144      switch (operatorType) {
1145          case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: {
1146              constexpr auto precedence = 1;
1147              return precedence;
1148          }
1149          case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: {
1150              constexpr auto precedence = 2;
1151              return precedence;
1152          }
1153          case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
1154          case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
1155              constexpr auto precedence = 3;
1156              return precedence;
1157          }
1158          case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: {
1159              constexpr auto precedence = 4;
1160              return precedence;
1161          }
1162          case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
1163              constexpr auto precedence = 5;
1164              return precedence;
1165          }
1166          case lexer::TokenType::PUNCTUATOR_EQUAL:
1167          case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
1168          case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
1169          case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
1170              constexpr auto precedence = 6;
1171              return precedence;
1172          }
1173          case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1174          case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
1175          case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
1176          case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
1177          case lexer::TokenType::KEYW_INSTANCEOF:
1178          case lexer::TokenType::KEYW_IN: {
1179              constexpr auto precedence = 7;
1180              return precedence;
1181          }
1182          case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1183          case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
1184          case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
1185              constexpr auto precedence = 8;
1186              return precedence;
1187          }
1188          case lexer::TokenType::PUNCTUATOR_PLUS:
1189          case lexer::TokenType::PUNCTUATOR_MINUS: {
1190              constexpr auto precedence = 9;
1191              return precedence;
1192          }
1193          case lexer::TokenType::PUNCTUATOR_MULTIPLY:
1194          case lexer::TokenType::PUNCTUATOR_DIVIDE:
1195          case lexer::TokenType::PUNCTUATOR_MOD: {
1196              const auto precedence = 10;
1197              return precedence;
1198          }
1199          case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
1200              constexpr auto precedence = 11;
1201              return precedence;
1202          }
1203          default: {
1204             UNREACHABLE();
1205          }
1206      }
1207  }
1208  
ShouldBinaryExpressionBeAmended(ir::BinaryExpression * binaryExpression,lexer::TokenType operatorType)1209  static inline bool ShouldBinaryExpressionBeAmended(ir::BinaryExpression *binaryExpression,
1210                                                     lexer::TokenType operatorType)
1211  {
1212      return GetOperatorPrecedence(binaryExpression->OperatorType()) <= GetOperatorPrecedence(operatorType) &&
1213             !binaryExpression->IsGrouped() &&
1214             (operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION ||
1215              binaryExpression->OperatorType() != lexer::TokenType::PUNCTUATOR_EXPONENTIATION);
1216  }
1217  
ParseBinaryExpression(ir::Expression * left)1218  ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left)
1219  {
1220      lexer::TokenType operatorType = lexer_->GetToken().Type();
1221      ASSERT(lexer::Token::IsBinaryToken(operatorType));
1222  
1223      if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) {
1224          if (left->IsUnaryExpression() && !left->IsGrouped()) {
1225              ThrowSyntaxError(
1226                  "Illegal expression. Wrap left hand side or entire "
1227                  "exponentiation in parentheses.");
1228          }
1229      }
1230  
1231      lexer_->NextToken();
1232  
1233      ir::Expression *rightExprNode = ParseExpression(ExpressionParseFlags::DISALLOW_YIELD);
1234  
1235      ir::Expression *rightExpr = rightExprNode;
1236      ir::ConditionalExpression *conditionalExpr = nullptr;
1237  
1238      if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) {
1239          conditionalExpr = rightExpr->AsConditionalExpression();
1240          rightExpr = conditionalExpr->Test();
1241      }
1242  
1243      if (rightExpr->IsBinaryExpression() &&
1244          ShouldBinaryExpressionBeAmended(rightExpr->AsBinaryExpression(), operatorType)) {
1245          if ((operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1246               operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1247              rightExpr->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING) {
1248              ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1249          }
1250  
1251          bool shouldBeAmended = true;
1252  
1253          ir::BinaryExpression *binaryExpression = rightExpr->AsBinaryExpression();
1254          ir::BinaryExpression *parentExpression = nullptr;
1255  
1256          while (binaryExpression->Left()->IsBinaryExpression() && shouldBeAmended) {
1257              parentExpression = binaryExpression;
1258              parentExpression->SetStart(left->Start());
1259              binaryExpression = binaryExpression->Left()->AsBinaryExpression();
1260              shouldBeAmended = ShouldBinaryExpressionBeAmended(binaryExpression, operatorType);
1261          }
1262  
1263          if (shouldBeAmended) {
1264              auto *leftExprNode = AllocNode<ir::BinaryExpression>(left, binaryExpression->Left(), operatorType);
1265              leftExprNode->SetRange({left->Start(), binaryExpression->Left()->End()});
1266  
1267              binaryExpression->SetLeft(leftExprNode);
1268          } else {
1269              // Transfer the parent's left ownership to right_node
1270              ir::Expression *rightNode = parentExpression->Left();
1271  
1272              auto *binaryOrLogicalExpressionNode = AllocNode<ir::BinaryExpression>(left, rightNode, operatorType);
1273              binaryOrLogicalExpressionNode->SetRange({left->Start(), rightNode->End()});
1274  
1275              parentExpression->SetLeft(binaryOrLogicalExpressionNode);
1276          }
1277      } else {
1278          if (operatorType == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && rightExpr->IsBinaryExpression() &&
1279              rightExpr->AsBinaryExpression()->IsLogical() && !rightExpr->IsGrouped()) {
1280              ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1281          }
1282          const lexer::SourcePosition &endPos = rightExpr->End();
1283          rightExpr = AllocNode<ir::BinaryExpression>(left, rightExpr, operatorType);
1284          rightExpr->SetRange({left->Start(), endPos});
1285      }
1286  
1287      if (conditionalExpr != nullptr) {
1288          conditionalExpr->SetStart(rightExpr->Start());
1289          conditionalExpr->SetTest(rightExpr);
1290          return conditionalExpr;
1291      }
1292  
1293      return rightExpr;
1294  }
1295  
ParseCallExpression(ir::Expression * callee,bool isOptionalChain,bool isAsync)1296  ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool isOptionalChain, bool isAsync)
1297  {
1298      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1299  
1300      while (true) {
1301          lexer_->NextToken();
1302          ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
1303  
1304          while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1305              ir::Expression *argument = nullptr;
1306              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1307                  argument = ParseSpreadElement();
1308              } else {
1309                  argument = ParseExpression(isAsync ? ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN
1310                                                     : ExpressionParseFlags::NO_OPTS);
1311              }
1312  
1313              arguments.push_back(argument);
1314  
1315              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1316                  lexer_->NextToken();
1317              } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1318                  ThrowSyntaxError("Expected a ')'");
1319              }
1320          }
1321  
1322          auto *callExpr = AllocNode<ir::CallExpression>(callee, std::move(arguments), nullptr, isOptionalChain);
1323          callExpr->SetRange({callee->Start(), lexer_->GetToken().End()});
1324          isOptionalChain = false;
1325  
1326          lexer_->NextToken();
1327  
1328          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1329              return callExpr;
1330          }
1331  
1332          callee = callExpr;
1333      }
1334  
1335      UNREACHABLE();
1336      return nullptr;
1337  }
1338  
ParseOptionalChain(ir::Expression * leftSideExpr)1339  ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr)
1340  {
1341      lexer::TokenType tokenType = lexer_->GetToken().Type();
1342      ir::Expression *returnExpression = nullptr;
1343  
1344      if (tokenType == lexer::TokenType::LITERAL_IDENT) {
1345          auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1346          identNode->SetReference();
1347          identNode->SetRange(lexer_->GetToken().Loc());
1348  
1349          returnExpression = AllocNode<ir::MemberExpression>(
1350              leftSideExpr, identNode, ir::MemberExpression::MemberExpressionKind::PROPERTY_ACCESS, false, true);
1351          returnExpression->SetRange({leftSideExpr->Start(), identNode->End()});
1352          lexer_->NextToken();
1353      }
1354  
1355      if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1356          lexer_->NextToken();  // eat '['
1357          ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1358  
1359          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1360              ThrowSyntaxError("Unexpected token");
1361          }
1362  
1363          returnExpression = AllocNode<ir::MemberExpression>(
1364              leftSideExpr, propertyNode, ir::MemberExpression::MemberExpressionKind::ELEMENT_ACCESS, true, true);
1365          returnExpression->SetRange({leftSideExpr->Start(), lexer_->GetToken().End()});
1366          lexer_->NextToken();
1367      }
1368  
1369      if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1370          returnExpression = ParseCallExpression(leftSideExpr, true);
1371      }
1372  
1373      // Static semantic
1374      if (tokenType == lexer::TokenType::PUNCTUATOR_BACK_TICK ||
1375          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1376          ThrowSyntaxError("Tagged Template Literals are not allowed in optionalChain");
1377      }
1378  
1379      return returnExpression;
1380  }
1381  
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1382  ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expression **returnExpression,
1383                                                                         const lexer::SourcePosition &startLoc,
1384                                                                         bool ignoreCallExpression)
1385  {
1386      ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1387  
1388      const auto savedPos = lexer_->Save();
1389  
1390      switch (lexer_->GetToken().Type()) {
1391          case lexer::TokenType::KEYW_FUNCTION: {
1392              *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
1393              (*returnExpression)->SetStart(startLoc);
1394              break;
1395          }
1396          case lexer::TokenType::LITERAL_IDENT: {
1397              ir::Expression *identRef = ParsePrimaryExpression();
1398              ASSERT(identRef->IsIdentifier());
1399  
1400              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1401                  ThrowSyntaxError("Unexpected token, expected '=>'");
1402              }
1403  
1404              ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
1405              arrowFuncExpr->SetStart(startLoc);
1406  
1407              return arrowFuncExpr;
1408          }
1409          case lexer::TokenType::PUNCTUATOR_ARROW: {
1410              ir::ArrowFunctionExpression *arrowFuncExpr =
1411                  ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
1412              arrowFuncExpr->SetStart(startLoc);
1413              return arrowFuncExpr;
1414          }
1415          case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: {
1416              if (Extension() == ScriptExtension::TS) {
1417                  return nullptr;
1418              }
1419  
1420              break;
1421          }
1422          case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1423              if (Extension() != ScriptExtension::TS) {
1424                  return nullptr;
1425              }
1426  
1427              typeParamDecl = ParseTsTypeParameterDeclaration(false);
1428              if (!typeParamDecl) {
1429                  lexer_->Rewind(savedPos);
1430                  return nullptr;
1431              }
1432  
1433              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1434                  ThrowSyntaxError("'(' expected");
1435              }
1436  
1437              [[fallthrough]];
1438          }
1439          case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1440              if (ignoreCallExpression) {
1441                  lexer_->Rewind(savedPos);
1442                  break;
1443              }
1444              ir::CallExpression *callExpression = ParseCallExpression(*returnExpression, false, true);
1445  
1446              ir::Expression *returnTypeAnnotation = nullptr;
1447              if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1448                  lexer_->NextToken();  // eat ':'
1449                  TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1450                  returnTypeAnnotation = ParseTsTypeAnnotation(&options);
1451              }
1452  
1453              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1454                  ir::ArrowFunctionExpression *arrowFuncExpr =
1455                      ParseArrowFunctionExpression(callExpression, typeParamDecl, returnTypeAnnotation, true);
1456                  arrowFuncExpr->SetStart(startLoc);
1457  
1458                  return arrowFuncExpr;
1459              }
1460  
1461              if (Extension() == ScriptExtension::TS && (returnTypeAnnotation || typeParamDecl)) {
1462                  ThrowSyntaxError("'=>' expected");
1463              }
1464  
1465              *returnExpression = callExpression;
1466              break;
1467          }
1468          default: {
1469              break;
1470          }
1471      }
1472  
1473      return nullptr;
1474  }
1475  
ParsePotentialTsGenericFunctionCall(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1476  bool ParserImpl::ParsePotentialTsGenericFunctionCall(ir::Expression **returnExpression,
1477                                                       const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
1478  {
1479      if (Extension() != ScriptExtension::TS || lexer_->Lookahead() == LEX_CHAR_LESS_THAN) {
1480          return true;
1481      }
1482  
1483      const auto savedPos = lexer_->Save();
1484  
1485      bool isLeftShift = false;
1486      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1487          lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1488          isLeftShift = true;
1489      }
1490  
1491      ir::TSTypeParameterInstantiation *typeParams;
1492      try {
1493          typeParams = ParseTsTypeParameterInstantiation(false);
1494      } catch (const Error &e) {
1495          if (!isLeftShift) {
1496              throw e;
1497          }
1498          typeParams = nullptr;
1499      }
1500  
1501      if (!typeParams) {
1502          lexer_->Rewind(savedPos);
1503          return true;
1504      }
1505  
1506      if (lexer_->GetToken().Type() == lexer::TokenType::EOS) {
1507          ThrowSyntaxError("'(' or '`' expected");
1508      }
1509  
1510      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1511          if (!ignoreCallExpression) {
1512              *returnExpression = ParseCallExpression(*returnExpression, false);
1513              (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
1514              return false;
1515          }
1516      }
1517  
1518      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1519          ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
1520          lexer::SourcePosition endLoc = propertyNode->End();
1521  
1522          *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
1523          (*returnExpression)->SetRange({startLoc, endLoc});
1524          return false;
1525      }
1526  
1527      lexer_->Rewind(savedPos);
1528      return true;
1529  }
1530  
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)1531  ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
1532                                                         bool ignoreCallExpression, bool *isChainExpression)
1533  {
1534      ir::Expression *returnExpression = primaryExpr;
1535  
1536      while (true) {
1537          switch (lexer_->GetToken().Type()) {
1538              case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: {
1539                  *isChainExpression = true;
1540                  lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat ?.
1541                  returnExpression = ParseOptionalChain(returnExpression);
1542                  continue;
1543              }
1544              case lexer::TokenType::PUNCTUATOR_PERIOD: {
1545                  lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat period
1546                  bool isPrivate = false;
1547  
1548                  lexer::SourcePosition memberStart = lexer_->GetToken().Start();
1549  
1550                  if (Extension() == ScriptExtension::TS &&
1551                      lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1552                      if (!(context_.Status() & ParserStatus::IN_CLASS_BODY)) {
1553                          ThrowSyntaxError("Private identifiers are not allowed outside class bodies.");
1554                      }
1555                      isPrivate = true;
1556                      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1557                  }
1558  
1559                  if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1560                      ThrowSyntaxError("Expected an identifier");
1561                  }
1562  
1563                  auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1564                  identNode->SetRange(lexer_->GetToken().Loc());
1565  
1566                  ir::Expression *property = nullptr;
1567                  if (isPrivate) {
1568                      property = AllocNode<ir::TSPrivateIdentifier>(identNode, nullptr, nullptr);
1569                      property->SetRange({memberStart, identNode->End()});
1570                  } else {
1571                      property = identNode;
1572                  }
1573  
1574                  const lexer::SourcePosition &startPos = returnExpression->Start();
1575                  returnExpression = AllocNode<ir::MemberExpression>(
1576                      returnExpression, property, ir::MemberExpression::MemberExpressionKind::PROPERTY_ACCESS, false,
1577                      false);
1578                  returnExpression->SetRange({startPos, property->End()});
1579                  lexer_->NextToken();
1580                  continue;
1581              }
1582              case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1583                  if (context_.Status() & ParserStatus::IN_DECORATOR) {
1584                      break;
1585                  }
1586  
1587                  lexer_->NextToken();  // eat '['
1588                  ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1589  
1590                  if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1591                      ThrowSyntaxError("Unexpected token");
1592                  }
1593  
1594                  const lexer::SourcePosition &startPos = returnExpression->Start();
1595                  returnExpression = AllocNode<ir::MemberExpression>(
1596                      returnExpression, propertyNode, ir::MemberExpression::MemberExpressionKind::ELEMENT_ACCESS, true,
1597                      false);
1598                  returnExpression->SetRange({startPos, lexer_->GetToken().End()});
1599                  lexer_->NextToken();
1600                  continue;
1601              }
1602              case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1603              case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1604                  bool shouldBreak =
1605                      ParsePotentialTsGenericFunctionCall(&returnExpression, startLoc, ignoreCallExpression);
1606                  if (shouldBreak) {
1607                      break;
1608                  }
1609  
1610                  continue;
1611              }
1612              case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1613                  ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
1614                  lexer::SourcePosition endLoc = propertyNode->End();
1615  
1616                  returnExpression = AllocNode<ir::TaggedTemplateExpression>(returnExpression, propertyNode, nullptr);
1617                  returnExpression->SetRange({startLoc, endLoc});
1618                  continue;
1619              }
1620              case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1621                  if (!ignoreCallExpression) {
1622                      returnExpression = ParseCallExpression(returnExpression, false);
1623                      continue;
1624                  }
1625                  break;
1626              }
1627              case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
1628                  if (Extension() != ScriptExtension::TS || !returnExpression || lexer_->GetToken().NewLine()) {
1629                      break;
1630                  }
1631  
1632                  returnExpression = AllocNode<ir::TSNonNullExpression>(returnExpression);
1633                  returnExpression->SetRange({startLoc, lexer_->GetToken().End()});
1634                  lexer_->NextToken();
1635                  continue;
1636              }
1637              default: {
1638                  break;
1639              }
1640          }
1641  
1642          break;
1643      }
1644  
1645      return returnExpression;
1646  }
1647  
ValidateUpdateExpression(ir::Expression * returnExpression,bool isChainExpression)1648  void ParserImpl::ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression)
1649  {
1650      if (returnExpression->IsTSAsExpression()) {
1651          ValidateUpdateExpression(returnExpression->AsTSAsExpression()->Expr(), isChainExpression);
1652          return;
1653      }
1654      if (returnExpression->IsTSTypeAssertion()) {
1655          ValidateUpdateExpression(returnExpression->AsTSTypeAssertion()->GetExpression(), isChainExpression);
1656          return;
1657      }
1658  
1659      if ((!returnExpression->IsMemberExpression() && !returnExpression->IsIdentifier() &&
1660           !returnExpression->IsTSNonNullExpression()) ||
1661          isChainExpression) {
1662          ThrowSyntaxError("Invalid left-hand side operator.");
1663      }
1664  
1665      if (returnExpression->IsIdentifier()) {
1666          const util::StringView &returnExpressionStr = returnExpression->AsIdentifier()->Name();
1667  
1668          if (returnExpressionStr.Is("eval")) {
1669              ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid");
1670          }
1671  
1672          if (returnExpressionStr.Is("arguments")) {
1673              ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid");
1674          }
1675      }
1676  }
1677  
ParseMemberExpression(bool ignoreCallExpression,ExpressionParseFlags flags)1678  ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, ExpressionParseFlags flags)
1679  {
1680      bool isAsync = lexer_->GetToken().IsAsyncModifier();
1681      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1682      ir::Expression *returnExpression = ParsePrimaryExpression(flags);
1683  
1684      if (lexer_->GetToken().NewLine() && returnExpression->IsArrowFunctionExpression()) {
1685          return returnExpression;
1686      }
1687  
1688      if (isAsync && !lexer_->GetToken().NewLine()) {
1689          ir::ArrowFunctionExpression *arrow = ParsePotentialArrowExpression(&returnExpression, startLoc,
1690                                                                             ignoreCallExpression);
1691  
1692          if (arrow) {
1693              return arrow;
1694          }
1695      }
1696  
1697      bool isChainExpression = false;
1698      returnExpression = ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression);
1699  
1700      if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) {
1701          lexer::SourcePosition start = returnExpression->Start();
1702  
1703          ValidateUpdateExpression(returnExpression, isChainExpression);
1704  
1705          returnExpression = AllocNode<ir::UpdateExpression>(returnExpression, lexer_->GetToken().Type(), false);
1706  
1707          returnExpression->SetRange({start, lexer_->GetToken().End()});
1708          lexer_->NextToken();
1709      }
1710  
1711      if (isChainExpression) {
1712          lexer::SourcePosition endLoc = returnExpression->End();
1713          returnExpression = AllocNode<ir::ChainExpression>(returnExpression);
1714          returnExpression->SetRange({startLoc, endLoc});
1715      }
1716  
1717      return returnExpression;
1718  }
1719  
ParsePotentialTsFunctionParameter(ExpressionParseFlags flags,ir::Expression * returnNode,bool isDeclare)1720  void ParserImpl::ParsePotentialTsFunctionParameter(ExpressionParseFlags flags, ir::Expression *returnNode,
1721                                                     bool isDeclare)
1722  {
1723      if (Extension() != ScriptExtension::TS || !(context_.Status() & ParserStatus::FUNCTION_PARAM)) {
1724          return;
1725      }
1726  
1727      bool isOptional = false;
1728  
1729      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1730          if (flags & ExpressionParseFlags::IN_REST) {
1731              ThrowSyntaxError("A rest parameter cannot be optional");
1732          }
1733  
1734          ASSERT(returnNode->IsIdentifier() || returnNode->IsObjectPattern() || returnNode->IsArrayPattern());
1735          if (returnNode->IsIdentifier()) {
1736              returnNode->AsIdentifier()->SetOptional(true);
1737          } else if (returnNode->IsObjectPattern()) {
1738              returnNode->AsObjectPattern()->SetOptional(true);
1739          } else if (returnNode->IsArrayPattern()) {
1740              returnNode->AsArrayPattern()->SetOptional(true);
1741          }
1742  
1743          isOptional = true;
1744          lexer_->NextToken();  // eat '?'
1745      }
1746  
1747      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1748          lexer_->NextToken();  // eat ':'
1749          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1750          returnNode->SetTsTypeAnnotation(ParseTsTypeAnnotation(&options));
1751      }
1752  
1753      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1754          return;
1755      }
1756  
1757      if (flags & ExpressionParseFlags::IN_REST) {
1758          ThrowSyntaxError("A rest parameter cannot have an initializer");
1759      }
1760  
1761      if (returnNode->IsIdentifier() && isOptional) {
1762          ThrowSyntaxError("Parameter cannot have question mark and initializer");
1763      }
1764  }
1765  
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault,bool isDeclare)1766  ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault, bool isDeclare)
1767  {
1768      ir::Expression *returnNode = nullptr;
1769  
1770      switch (lexer_->GetToken().Type()) {
1771          case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1772              returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1773              break;
1774          }
1775          case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
1776              if (flags & ExpressionParseFlags::IN_REST) {
1777                  ThrowSyntaxError("Unexpected token");
1778              }
1779  
1780              returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1781              break;
1782          }
1783          case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1784              returnNode =
1785                  ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
1786              break;
1787          }
1788          case lexer::TokenType::LITERAL_IDENT: {
1789              returnNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1790              returnNode->AsIdentifier()->SetReference();
1791              returnNode->SetRange(lexer_->GetToken().Loc());
1792              lexer_->NextToken();
1793              break;
1794          }
1795          default: {
1796              ThrowSyntaxError("Unexpected token, expected an identifier.");
1797          }
1798      }
1799  
1800      ParsePotentialTsFunctionParameter(flags, returnNode, isDeclare);
1801  
1802      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1803          return returnNode;
1804      }
1805  
1806      if (flags & ExpressionParseFlags::IN_REST) {
1807          ThrowSyntaxError("Unexpected token, expected ')'");
1808      }
1809  
1810      if (!allowDefault) {
1811          ThrowSyntaxError("Invalid destructuring assignment target");
1812      }
1813  
1814      lexer_->NextToken();
1815  
1816      if ((context_.Status() & ParserStatus::GENERATOR_FUNCTION) &&
1817          lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
1818          ThrowSyntaxError("Yield is not allowed in generator parameters");
1819      }
1820  
1821      ir::Expression *rightNode = ParseExpression();
1822  
1823      auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1824          ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1825      assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
1826  
1827      return assignmentExpression;
1828  }
1829  
CheckPropertyKeyAsycModifier(ParserStatus * methodStatus)1830  void ParserImpl::CheckPropertyKeyAsycModifier(ParserStatus *methodStatus)
1831  {
1832      const auto asyncPos = lexer_->Save();
1833      lexer_->NextToken();
1834  
1835      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1836          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
1837          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1838          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1839          if (lexer_->GetToken().NewLine()) {
1840              ThrowSyntaxError(
1841                  "Async methods cannot have a line terminator between "
1842                  "'async' and the property name");
1843          }
1844  
1845          *methodStatus |= ParserStatus::ASYNC_FUNCTION;
1846      } else {
1847          lexer_->Rewind(asyncPos);
1848      }
1849  }
1850  
IsAccessorDelimiter(char32_t cp)1851  static bool IsAccessorDelimiter(char32_t cp)
1852  {
1853      switch (cp) {
1854          case LEX_CHAR_LEFT_PAREN:
1855          case LEX_CHAR_COLON:
1856          case LEX_CHAR_COMMA:
1857          case LEX_CHAR_RIGHT_BRACE: {
1858              return true;
1859          }
1860          default: {
1861              return false;
1862          }
1863      }
1864  }
1865  
IsShorthandDelimiter(char32_t cp)1866  static bool IsShorthandDelimiter(char32_t cp)
1867  {
1868      switch (cp) {
1869          case LEX_CHAR_EQUALS:
1870          case LEX_CHAR_COMMA:
1871          case LEX_CHAR_RIGHT_BRACE: {
1872              return true;
1873          }
1874          default: {
1875              return false;
1876          }
1877      }
1878  }
1879  
ValidateAccessor(ExpressionParseFlags flags,lexer::TokenFlags currentTokenFlags)1880  void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags)
1881  {
1882      if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
1883          ThrowSyntaxError("Unexpected token");
1884      }
1885  
1886      if (currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) {
1887          ThrowSyntaxError("Keyword must not contain escaped characters");
1888      }
1889  }
1890  
ParseShorthandProperty(const lexer::LexerPosition * startPos)1891  ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos)
1892  {
1893      char32_t nextCp = lexer_->Lookahead();
1894      lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
1895  
1896      /* Rewind the lexer to the beginning of the ident to repase as common
1897       * identifier */
1898      lexer_->Rewind(*startPos);
1899      lexer_->NextToken();
1900      lexer::SourcePosition start = lexer_->GetToken().Start();
1901  
1902      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1903          ThrowSyntaxError("Expected an identifier");
1904      }
1905  
1906      if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_PRIVATE &&
1907          lexer_->GetToken().KeywordType() <= lexer::TokenType::KEYW_DECLARE) {
1908          ThrowSyntaxError(" Unexpected reserved word", lexer_->GetToken().Start());
1909      }
1910  
1911      const util::StringView &ident = lexer_->GetToken().Ident();
1912  
1913      auto *key = AllocNode<ir::Identifier>(ident);
1914      key->SetRange(lexer_->GetToken().Loc());
1915  
1916      ir::Expression *value = AllocNode<ir::Identifier>(ident);
1917      value->AsIdentifier()->SetReference();
1918      value->SetRange(lexer_->GetToken().Loc());
1919  
1920      lexer::SourcePosition end;
1921  
1922      if (nextCp == LEX_CHAR_EQUALS) {
1923          if (keywordType == lexer::TokenType::KEYW_EVAL) {
1924              ThrowSyntaxError("eval can't be defined or assigned to in strict mode code");
1925          }
1926  
1927          lexer_->NextToken();  // substitution
1928          lexer_->NextToken();  // eat substitution
1929  
1930          ir::Expression *rightNode = ParseExpression();
1931  
1932          auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1933              ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1934          assignmentExpression->SetRange({value->Start(), rightNode->End()});
1935          end = rightNode->End();
1936          value = assignmentExpression;
1937      } else {
1938          end = lexer_->GetToken().End();
1939          lexer_->NextToken();
1940      }
1941  
1942      auto *returnProperty = AllocNode<ir::Property>(key, value);
1943      returnProperty->SetRange({start, end});
1944  
1945      return returnProperty;
1946  }
1947  
ParsePropertyModifiers(ExpressionParseFlags flags,ir::PropertyKind * propertyKind,ParserStatus * methodStatus)1948  bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::PropertyKind *propertyKind,
1949                                          ParserStatus *methodStatus)
1950  {
1951      if (lexer_->GetToken().IsAsyncModifier()) {
1952          CheckPropertyKeyAsycModifier(methodStatus);
1953      }
1954  
1955      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1956          if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
1957              ThrowSyntaxError("Unexpected token");
1958          }
1959  
1960          lexer_->NextToken();
1961          *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
1962      }
1963  
1964      lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags();
1965      char32_t nextCp = lexer_->Lookahead();
1966      lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
1967      // Parse getter property
1968      if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) {
1969          ValidateAccessor(flags, currentTokenFlags);
1970  
1971          *propertyKind = ir::PropertyKind::GET;
1972          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1973  
1974          return false;
1975      }
1976  
1977      // Parse setter property
1978      if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) {
1979          ValidateAccessor(flags, currentTokenFlags);
1980  
1981          *propertyKind = ir::PropertyKind::SET;
1982          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1983  
1984          return false;
1985      }
1986  
1987      // Parse shorthand property or assignment pattern
1988      return (IsShorthandDelimiter(nextCp) && !(*methodStatus & ParserStatus::ASYNC_FUNCTION));
1989  }
1990  
ParseGeneratorPropertyModifier(ExpressionParseFlags flags,ParserStatus * methodStatus)1991  void ParserImpl::ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus)
1992  {
1993      if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
1994          ThrowSyntaxError("Unexpected token");
1995      }
1996  
1997      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1998      *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
1999  }
2000  
ParsePropertyKey(ExpressionParseFlags flags)2001  ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags)
2002  {
2003      ir::Expression *key = nullptr;
2004  
2005      switch (lexer_->GetToken().Type()) {
2006          case lexer::TokenType::LITERAL_IDENT: {
2007              const util::StringView &ident = lexer_->GetToken().Ident();
2008              key = AllocNode<ir::Identifier>(ident);
2009              key->SetRange(lexer_->GetToken().Loc());
2010              break;
2011          }
2012          case lexer::TokenType::LITERAL_STRING: {
2013              const util::StringView &string = lexer_->GetToken().String();
2014              key = AllocNode<ir::StringLiteral>(string);
2015              key->SetRange(lexer_->GetToken().Loc());
2016              break;
2017          }
2018          case lexer::TokenType::LITERAL_NUMBER: {
2019              if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
2020                  key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
2021              } else {
2022                  key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
2023              }
2024  
2025              key->SetRange(lexer_->GetToken().Loc());
2026              break;
2027          }
2028          case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
2029              lexer_->NextToken();  // eat left square bracket
2030  
2031              key = ParseExpression(flags | ExpressionParseFlags::ACCEPT_COMMA);
2032  
2033              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2034                  ThrowSyntaxError("Unexpected token, expected ']'");
2035              }
2036              break;
2037          }
2038          default: {
2039              ThrowSyntaxError("Unexpected token in property key");
2040          }
2041      }
2042  
2043      lexer_->NextToken();
2044      return key;
2045  }
2046  
ParsePropertyValue(const ir::PropertyKind * propertyKind,const ParserStatus * methodStatus,ExpressionParseFlags flags)2047  ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyKind, const ParserStatus *methodStatus,
2048                                                 ExpressionParseFlags flags)
2049  {
2050      bool isMethod = *methodStatus & ParserStatus::FUNCTION;
2051      bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
2052  
2053      if (!isMethod && !ir::Property::IsAccessorKind(*propertyKind)) {
2054          // If the actual property is not getter/setter nor method, the following
2055          // token must be ':'
2056          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2057              ThrowSyntaxError("Unexpected token, expected ':'");
2058          }
2059  
2060          lexer_->NextToken();  // eat colon
2061  
2062          if (!inPattern) {
2063              return ParseExpression(flags);
2064          }
2065  
2066          return ParsePatternElement();
2067      }
2068  
2069      if (inPattern) {
2070          ThrowSyntaxError("Object pattern can't contain methods");
2071      }
2072  
2073      ir::ScriptFunction *methodDefinitonNode =
2074          ParseFunction(*methodStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER);
2075      lexer_->NextToken();
2076      methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD);
2077  
2078      size_t paramsSize = methodDefinitonNode->Params().size();
2079  
2080      auto *value = AllocNode<ir::FunctionExpression>(methodDefinitonNode);
2081      value->SetRange(methodDefinitonNode->Range());
2082  
2083      if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) {
2084          ThrowSyntaxError("Setter must have exactly one formal parameter");
2085      }
2086  
2087      if (*propertyKind == ir::PropertyKind::GET && paramsSize != 0) {
2088          ThrowSyntaxError("Getter must not have formal parameters");
2089      }
2090  
2091      return value;
2092  }
2093  
ParsePropertyDefinition(ExpressionParseFlags flags)2094  ir::Expression *ParserImpl::ParsePropertyDefinition(ExpressionParseFlags flags)
2095  {
2096      ir::PropertyKind propertyKind = ir::PropertyKind::INIT;
2097      ParserStatus methodStatus = ParserStatus::NO_OPTS;
2098  
2099      const auto startPos = lexer_->Save();
2100      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2101      lexer::SourcePosition start = lexer_->GetToken().Start();
2102  
2103      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2104          return ParseSpreadElement(flags);
2105      }
2106  
2107      if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
2108          if (ParsePropertyModifiers(flags, &propertyKind, &methodStatus)) {
2109              return ParseShorthandProperty(&startPos);
2110          }
2111      } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2112          ParseGeneratorPropertyModifier(flags, &methodStatus);
2113      }
2114  
2115      bool isComputed = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET;
2116      ir::Expression *key = ParsePropertyKey(flags);
2117  
2118      // Parse method property
2119      if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
2120           lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) &&
2121          !ir::Property::IsAccessorKind(propertyKind)) {
2122          methodStatus |= ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2123          propertyKind = ir::PropertyKind::INIT;
2124      } else if (methodStatus & (ParserStatus::GENERATOR_FUNCTION | ParserStatus::ASYNC_FUNCTION)) {
2125          ThrowSyntaxError("Unexpected identifier");
2126      }
2127  
2128      ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags);
2129      lexer::SourcePosition end = value->End();
2130  
2131      ASSERT(key);
2132      ASSERT(value);
2133  
2134      auto *returnProperty =
2135          AllocNode<ir::Property>(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed);
2136      returnProperty->SetRange({start, end});
2137  
2138      return returnProperty;
2139  }
2140  
ParsePropertyEnd()2141  bool ParserImpl::ParsePropertyEnd()
2142  {
2143      // Property definiton must end with ',' or '}' otherwise we throw SyntaxError
2144      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
2145          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2146          ThrowSyntaxError("Unexpected token, expected ',' or '}'");
2147      }
2148  
2149      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
2150          lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE) {
2151          lexer_->NextToken();
2152          return true;
2153      }
2154  
2155      return false;
2156  }
2157  
ParseObjectExpression(ExpressionParseFlags flags)2158  ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags flags)
2159  {
2160      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
2161      lexer::SourcePosition start = lexer_->GetToken().Start();
2162      ArenaVector<ir::Expression *> properties(Allocator()->Adapter());
2163      bool trailingComma = false;
2164      bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
2165  
2166      if (lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE) {
2167          lexer_->NextToken();
2168      }
2169  
2170      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2171          ir::Expression *property = ParsePropertyDefinition(flags | ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
2172          properties.push_back(property);
2173          trailingComma = ParsePropertyEnd();
2174      }
2175  
2176      auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION;
2177      auto *objectExpression = AllocNode<ir::ObjectExpression>(nodeType, std::move(properties), trailingComma);
2178      objectExpression->SetRange({start, lexer_->GetToken().End()});
2179      lexer_->NextToken();
2180  
2181      if (inPattern) {
2182          objectExpression->SetDeclaration();
2183      }
2184  
2185      if (Extension() == ScriptExtension::TS && (flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN) &&
2186          lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
2187          context_.Status() |= ParserStatus::FUNCTION_PARAM;
2188          ParsePotentialTsFunctionParameter(ExpressionParseFlags::NO_OPTS, objectExpression);
2189      }
2190  
2191      if (!(flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN)) {
2192          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
2193              !objectExpression->ConvertibleToObjectPattern()) {
2194              ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", objectExpression->Start());
2195          } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2196              ir::ValidationInfo info = objectExpression->ValidateExpression();
2197              if (info.Fail()) {
2198                  ThrowSyntaxError(info.msg.Utf8(), info.pos);
2199              }
2200          }
2201      }
2202  
2203      return objectExpression;
2204  }
2205  
ParseSequenceExpression(ir::Expression * startExpr,bool acceptRest,bool acceptTsParam)2206  ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *startExpr, bool acceptRest,
2207                                                              bool acceptTsParam)
2208  {
2209      lexer::SourcePosition start = startExpr->Start();
2210  
2211      ArenaVector<ir::Expression *> sequence(Allocator()->Adapter());
2212      sequence.push_back(startExpr);
2213  
2214      while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2215          lexer_->NextToken();
2216  
2217          if (acceptRest && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2218              ir::SpreadElement *expr = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
2219              sequence.push_back(expr);
2220              break;
2221          }
2222  
2223          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && lexer_->CheckArrow()) {
2224              break;
2225          }
2226  
2227          sequence.push_back(ParseExpression(acceptTsParam ? ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN
2228                                                           : ExpressionParseFlags::NO_OPTS));
2229      }
2230  
2231      lexer::SourcePosition end = sequence.back()->End();
2232      auto *sequenceNode = AllocNode<ir::SequenceExpression>(std::move(sequence));
2233      sequenceNode->SetRange({start, end});
2234  
2235      return sequenceNode;
2236  }
2237  
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)2238  ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
2239  {
2240      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
2241          // TODO(rsipka): negative cases are not covered, probably this is not a complete solution yet
2242          return ParseTsTypeAssertion(flags);
2243      }
2244  
2245      if (!lexer_->GetToken().IsUnary()) {
2246          return ParseLeftHandSideExpression(flags);
2247      }
2248  
2249      lexer::TokenType operatorType = lexer_->GetToken().Type();
2250      lexer::SourcePosition start = lexer_->GetToken().Start();
2251      lexer_->NextToken();
2252      ir::Expression *argument = ParseUnaryOrPrefixUpdateExpression();
2253  
2254      if (lexer::Token::IsUpdateToken(operatorType)) {
2255          ValidateUpdateExpression(argument, false);
2256      }
2257  
2258      if (operatorType == lexer::TokenType::KEYW_DELETE && argument->IsIdentifier()) {
2259          ThrowSyntaxError("Deleting local variable in strict mode");
2260      }
2261  
2262      lexer::SourcePosition end = argument->End();
2263  
2264      ir::Expression *returnExpr = nullptr;
2265  
2266      if (lexer::Token::IsUpdateToken(operatorType)) {
2267          returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true);
2268      } else if (operatorType == lexer::TokenType::KEYW_AWAIT) {
2269          returnExpr = AllocNode<ir::AwaitExpression>(argument);
2270      } else {
2271          returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType);
2272      }
2273  
2274      returnExpr->SetRange({start, end});
2275  
2276      return returnExpr;
2277  }
2278  
ParseImportExpression()2279  ir::Expression *ParserImpl::ParseImportExpression()
2280  {
2281      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2282      lexer::SourcePosition endLoc = lexer_->GetToken().End();
2283      lexer_->NextToken();  // eat import
2284  
2285      // parse import.Meta
2286      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
2287          if (!context_.IsModule()) {
2288              ThrowSyntaxError("'import.Meta' may appear only with 'sourceType: module'");
2289          }
2290  
2291          lexer_->NextToken();  // eat dot
2292  
2293          if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT ||
2294              lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_META) {
2295              ThrowSyntaxError("The only valid meta property for import is import.Meta");
2296          }
2297  
2298          auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::IMPORT_META);
2299          metaProperty->SetRange({startLoc, endLoc});
2300  
2301          lexer_->NextToken();
2302          return metaProperty;
2303      }
2304  
2305      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
2306          ThrowSyntaxError("Unexpected token");
2307      }
2308  
2309      lexer_->NextToken();  // eat left parentheses
2310  
2311      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2312          ThrowSyntaxError("Argument of dynamic import cannot be spread element.");
2313      }
2314  
2315      ir::Expression *source = ParseExpression();
2316  
2317      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2318          ThrowSyntaxError(
2319              "Dynamic imports can only accept a module specifier, optional assertion is not supported yet.");
2320      }
2321  
2322      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
2323          ThrowSyntaxError("Unexpected token");
2324      }
2325  
2326      auto *importExpression = AllocNode<ir::ImportExpression>(source);
2327      importExpression->SetRange({startLoc, lexer_->GetToken().End()});
2328  
2329      lexer_->NextToken();  // eat right paren
2330      return importExpression;
2331  }
2332  
ParseFunctionExpression(ParserStatus newStatus)2333  ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStatus)
2334  {
2335      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2336      ir::Identifier *ident = nullptr;
2337  
2338      if (!(newStatus & ParserStatus::ARROW_FUNCTION)) {
2339          ParserStatus savedStatus = context_.Status();
2340  
2341          if (newStatus & ParserStatus::ASYNC_FUNCTION) {
2342              context_.Status() |= (ParserStatus::DISALLOW_AWAIT | ParserStatus::ASYNC_FUNCTION);
2343          }
2344  
2345          lexer_->NextToken();
2346  
2347          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2348              newStatus |= ParserStatus::GENERATOR_FUNCTION;
2349              lexer_->NextToken();
2350          }
2351  
2352          if ((Extension() == ScriptExtension::JS &&
2353               lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) ||
2354              (Extension() == ScriptExtension::TS &&
2355               lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
2356               lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
2357              if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2358                  ThrowSyntaxError("Expected an identifier.");
2359              }
2360  
2361              CheckStrictReservedWord();
2362  
2363              ident = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
2364              ident->SetRange(lexer_->GetToken().Loc());
2365              lexer_->NextToken();
2366          }
2367  
2368          context_.Status() = savedStatus;
2369      }
2370  
2371      ir::ScriptFunction *functionNode = ParseFunction(newStatus);
2372      if (functionNode->Body() != nullptr) {
2373          lexer_->NextToken();
2374      }
2375      functionNode->SetStart(startLoc);
2376  
2377      if (ident) {
2378          auto *funcParamScope = functionNode->Scope()->ParamScope();
2379          funcParamScope->BindName(Allocator(), ident->Name());
2380          functionNode->SetIdent(ident);
2381      }
2382  
2383      auto *funcExpr = AllocNode<ir::FunctionExpression>(functionNode);
2384      funcExpr->SetRange(functionNode->Range());
2385  
2386      return funcExpr;
2387  }
2388  
2389  }  // namespace panda::es2panda::parser
2390