• 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 "parserImpl.h"
17  
18  #include <binder/scope.h>
19  #include <binder/tsBinding.h>
20  #include <util/helpers.h>
21  #include <ir/astDump.h>
22  #include <ir/astNode.h>
23  #include <ir/base/classDefinition.h>
24  #include <ir/base/classProperty.h>
25  #include <ir/base/decorator.h>
26  #include <ir/base/methodDefinition.h>
27  #include <ir/base/property.h>
28  #include <ir/base/scriptFunction.h>
29  #include <ir/base/spreadElement.h>
30  #include <ir/expression.h>
31  #include <ir/expressions/arrayExpression.h>
32  #include <ir/expressions/assignmentExpression.h>
33  #include <ir/expressions/callExpression.h>
34  #include <ir/expressions/functionExpression.h>
35  #include <ir/expressions/identifier.h>
36  #include <ir/expressions/literals/bigIntLiteral.h>
37  #include <ir/expressions/literals/booleanLiteral.h>
38  #include <ir/expressions/literals/nullLiteral.h>
39  #include <ir/expressions/literals/numberLiteral.h>
40  #include <ir/expressions/literals/stringLiteral.h>
41  #include <ir/expressions/memberExpression.h>
42  #include <ir/expressions/objectExpression.h>
43  #include <ir/expressions/superExpression.h>
44  #include <ir/module/exportDefaultDeclaration.h>
45  #include <ir/module/exportNamedDeclaration.h>
46  #include <ir/module/exportSpecifier.h>
47  #include <ir/statements/blockStatement.h>
48  #include <ir/statements/classDeclaration.h>
49  #include <ir/statements/emptyStatement.h>
50  #include <ir/statements/expressionStatement.h>
51  #include <ir/statements/functionDeclaration.h>
52  #include <ir/statements/variableDeclaration.h>
53  #include <ir/ts/tsAnyKeyword.h>
54  #include <ir/ts/tsArrayType.h>
55  #include <ir/ts/tsAsExpression.h>
56  #include <ir/ts/tsBigintKeyword.h>
57  #include <ir/ts/tsBooleanKeyword.h>
58  #include <ir/ts/tsClassImplements.h>
59  #include <ir/ts/tsConditionalType.h>
60  #include <ir/ts/tsConstructorType.h>
61  #include <ir/ts/tsEnumDeclaration.h>
62  #include <ir/ts/tsEnumMember.h>
63  #include <ir/ts/tsFunctionType.h>
64  #include <ir/ts/tsImportType.h>
65  #include <ir/ts/tsIndexSignature.h>
66  #include <ir/ts/tsIndexedAccessType.h>
67  #include <ir/ts/tsInferType.h>
68  #include <ir/ts/tsIntersectionType.h>
69  #include <ir/ts/tsLiteralType.h>
70  #include <ir/ts/tsMappedType.h>
71  #include <ir/ts/tsMethodSignature.h>
72  #include <ir/ts/tsModuleDeclaration.h>
73  #include <ir/ts/tsNamedTupleMember.h>
74  #include <ir/ts/tsNeverKeyword.h>
75  #include <ir/ts/tsNullKeyword.h>
76  #include <ir/ts/tsNumberKeyword.h>
77  #include <ir/ts/tsObjectKeyword.h>
78  #include <ir/ts/tsOptionalType.h>
79  #include <ir/ts/tsParameterProperty.h>
80  #include <ir/ts/tsParenthesizedType.h>
81  #include <ir/ts/tsPrivateIdentifier.h>
82  #include <ir/ts/tsPropertySignature.h>
83  #include <ir/ts/tsQualifiedName.h>
84  #include <ir/ts/tsRestType.h>
85  #include <ir/ts/tsSignatureDeclaration.h>
86  #include <ir/ts/tsStringKeyword.h>
87  #include <ir/ts/tsSymbolKeyword.h>
88  #include <ir/ts/tsTemplateLiteralType.h>
89  #include <ir/ts/tsThisType.h>
90  #include <ir/ts/tsTupleType.h>
91  #include <ir/ts/tsTypeAssertion.h>
92  #include <ir/ts/tsTypeLiteral.h>
93  #include <ir/ts/tsTypeOperator.h>
94  #include <ir/ts/tsTypeParameterDeclaration.h>
95  #include <ir/ts/tsTypeParameterInstantiation.h>
96  #include <ir/ts/tsTypePredicate.h>
97  #include <ir/ts/tsTypeQuery.h>
98  #include <ir/ts/tsTypeReference.h>
99  #include <ir/ts/tsUndefinedKeyword.h>
100  #include <ir/ts/tsUnionType.h>
101  #include <ir/ts/tsUnknownKeyword.h>
102  #include <ir/ts/tsVoidKeyword.h>
103  #include <lexer/lexer.h>
104  #include <lexer/token/letters.h>
105  #include <lexer/token/sourceLocation.h>
106  #include <mem/pool_manager.h>
107  
108  namespace panda::es2panda::parser {
109  
ParserImpl(ScriptExtension extension)110  ParserImpl::ParserImpl(ScriptExtension extension) : program_(extension), context_(&program_) {}
111  
InitLexer(const std::string & fileName,const std::string & source)112  std::unique_ptr<lexer::Lexer> ParserImpl::InitLexer(const std::string &fileName, const std::string &source)
113  {
114      bool isDtsFile = false;
115      if (Extension() == ScriptExtension::TS) {
116          isDtsFile = util::Helpers::FileExtensionIs(fileName, ".d.ts");
117      }
118      program_.SetSource(source, fileName, isDtsFile);
119      auto lexer = std::make_unique<lexer::Lexer>(&context_);
120      lexer_ = lexer.get();
121  
122      return lexer;
123  }
124  
Parse(const std::string & fileName,const std::string & source,const std::string & recordName,ScriptKind kind)125  Program ParserImpl::Parse(const std::string &fileName, const std::string &source,
126                            const std::string &recordName, ScriptKind kind)
127  {
128      program_.SetKind(kind);
129      program_.SetRecordName(recordName);
130  
131      /*
132       * In order to make the lexer's memory alive, the return value 'lexer' can not be omitted.
133       */
134      auto lexer = InitLexer(fileName, source);
135      switch (kind) {
136          case ScriptKind::SCRIPT: {
137              ParseScript();
138              break;
139          }
140          case ScriptKind::MODULE: {
141              ParseModule();
142              break;
143          }
144          case ScriptKind::COMMONJS: {
145              ParseCommonjs();
146              break;
147          }
148          default: {
149              UNREACHABLE();
150          }
151      }
152      binder::ResolveBindingFlags bindFlags = binder::ResolveBindingFlags::ALL;
153      if (Extension() == ScriptExtension::TS) {
154          bindFlags = binder::ResolveBindingFlags::TS_BEFORE_TRANSFORM;
155      }
156      Binder()->IdentifierAnalysis(bindFlags);
157      return std::move(program_);
158  }
159  
ParseScript()160  void ParserImpl::ParseScript()
161  {
162      ParseProgram(ScriptKind::SCRIPT);
163  }
164  
ParseModule()165  void ParserImpl::ParseModule()
166  {
167      context_.Status() |= (ParserStatus::MODULE);
168      ParseProgram(ScriptKind::MODULE);
169  }
170  
ParseProgram(ScriptKind kind)171  void ParserImpl::ParseProgram(ScriptKind kind)
172  {
173      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
174      lexer_->NextToken();
175  
176      auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL);
177      if (IsDtsFile() && !CheckTopStatementsForRequiredDeclare(statements)) {
178          ThrowSyntaxError(
179              "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.");
180      }
181  
182      auto *blockStmt = AllocNode<ir::BlockStatement>(Binder()->GetScope(), std::move(statements));
183      Binder()->GetScope()->BindNode(blockStmt);
184      blockStmt->SetRange({startLoc, lexer_->GetToken().End()});
185  
186      program_.SetAst(blockStmt);
187  }
188  
CheckTopStatementsForRequiredDeclare(const ArenaVector<ir::Statement * > & statements)189  bool ParserImpl::CheckTopStatementsForRequiredDeclare(const ArenaVector<ir::Statement *> &statements)
190  {
191      for (auto *statement : statements) {
192          switch (statement->Type()) {
193              case ir::AstNodeType::TS_INTERFACE_DECLARATION:
194              case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION:
195              case ir::AstNodeType::IMPORT_DECLARATION:
196              case ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION:
197              case ir::AstNodeType::EXPORT_ALL_DECLARATION:
198              case ir::AstNodeType::EXPORT_DEFAULT_DECLARATION:
199              case ir::AstNodeType::EXPORT_NAMED_DECLARATION:
200              case ir::AstNodeType::TS_NAMESPACE_EXPORT_DECLARATION:
201                  continue;
202              case ir::AstNodeType::CLASS_DECLARATION: {
203                  if (!statement->AsClassDeclaration()->Definition()->Declare()) {
204                      return false;
205                  }
206                  break;
207              }
208              case ir::AstNodeType::FUNCTION_DECLARATION: {
209                  if (!statement->AsFunctionDeclaration()->Function()->Declare() &&
210                      !statement->AsFunctionDeclaration()->Function()->IsOverload()) {
211                      return false;
212                  }
213                  break;
214              }
215              case ir::AstNodeType::VARIABLE_DECLARATION: {
216                  if (!statement->AsVariableDeclaration()->Declare()) {
217                      return false;
218                  }
219                  break;
220              }
221              case ir::AstNodeType::TS_MODULE_DECLARATION: {
222                  if (!statement->AsTSModuleDeclaration()->Declare()) {
223                      return false;
224                  }
225                  break;
226              }
227              case ir::AstNodeType::TS_ENUM_DECLARATION: {
228                  if (!statement->AsTSEnumDeclaration()->IsDeclare()) {
229                      return false;
230                  }
231                  break;
232              }
233              default:
234                  ThrowSyntaxError("Statements are not allowed in ambient contexts.");
235                  UNREACHABLE();
236          }
237      }
238      return true;
239  }
240  
241  /*
242   * Definitions of private methods
243   */
CarryExpressionParserFlag(ExpressionParseFlags origin,ExpressionParseFlags carry)244  ExpressionParseFlags ParserImpl::CarryExpressionParserFlag(ExpressionParseFlags origin, ExpressionParseFlags carry)
245  {
246      return static_cast<ExpressionParseFlags>(origin & carry);
247  }
248  
CarryPatternFlags(ExpressionParseFlags flags)249  ExpressionParseFlags ParserImpl::CarryPatternFlags(ExpressionParseFlags flags)
250  {
251      return CarryExpressionParserFlag(flags, ExpressionParseFlags::POTENTIALLY_IN_PATTERN |
252                                                  ExpressionParseFlags::OBJECT_PATTERN);
253  }
254  
CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags)255  ExpressionParseFlags ParserImpl::CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags)
256  {
257      return CarryExpressionParserFlag(flags, ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN |
258                                              ExpressionParseFlags::POTENTIALLY_IN_PATTERN |
259                                              ExpressionParseFlags::OBJECT_PATTERN);
260  }
261  
CurrentLiteralIsBasicType()262  bool ParserImpl::CurrentLiteralIsBasicType()
263  {
264      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
265             lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
266  
267      switch (lexer_->GetToken().KeywordType()) {
268          case lexer::TokenType::KEYW_ANY:
269          case lexer::TokenType::KEYW_BOOLEAN:
270          case lexer::TokenType::KEYW_NUMBER:
271          case lexer::TokenType::KEYW_STRING:
272          case lexer::TokenType::KEYW_SYMBOL:
273          case lexer::TokenType::KEYW_UNKNOWN:
274          case lexer::TokenType::KEYW_UNDEFINED:
275          case lexer::TokenType::KEYW_NEVER:
276          case lexer::TokenType::KEYW_OBJECT:
277          case lexer::TokenType::KEYW_BIGINT: {
278              return true;
279          }
280          default: {
281              break;
282          }
283      }
284  
285      return false;
286  }
CurrentIsBasicType()287  bool ParserImpl::CurrentIsBasicType()
288  {
289      switch (lexer_->GetToken().Type()) {
290          case lexer::TokenType::PUNCTUATOR_MINUS:
291          case lexer::TokenType::LITERAL_NUMBER:
292          case lexer::TokenType::LITERAL_STRING:
293          case lexer::TokenType::LITERAL_FALSE:
294          case lexer::TokenType::LITERAL_TRUE:
295          case lexer::TokenType::LITERAL_NULL:
296          case lexer::TokenType::KEYW_VOID: {
297              return true;
298          }
299          case lexer::TokenType::LITERAL_IDENT: {
300              return CurrentLiteralIsBasicType();
301          }
302          default: {
303              break;
304          }
305      }
306  
307      return false;
308  }
309  
ParseTsConstExpression()310  ir::TSTypeReference *ParserImpl::ParseTsConstExpression()
311  {
312      auto *identRef = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
313      identRef->SetReference();
314      identRef->SetRange(lexer_->GetToken().Loc());
315  
316      auto *typeReference = AllocNode<ir::TSTypeReference>(identRef, nullptr);
317      typeReference->SetRange(lexer_->GetToken().Loc());
318  
319      lexer_->NextToken();
320  
321      return typeReference;
322  }
323  
ParseTsIdentifierReference(TypeAnnotationParsingOptions options)324  ir::Expression *ParserImpl::ParseTsIdentifierReference(TypeAnnotationParsingOptions options)
325  {
326      if (CurrentLiteralIsBasicType() && lexer_->Lookahead() != LEX_CHAR_DOT) {
327          return ParseTsBasicType(options);
328      }
329  
330      return ParseTsTypeReferenceOrQuery(options, false);
331  }
332  
IsStartOfMappedType() const333  bool ParserImpl::IsStartOfMappedType() const
334  {
335      auto pos = lexer_->Save();
336      lexer_->NextToken();
337      bool result = false;
338  
339      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
340          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
341          lexer_->NextToken();
342          result = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY;
343          lexer_->Rewind(pos);
344          return result;
345      }
346  
347      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
348          lexer_->NextToken();
349      }
350  
351      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
352          lexer_->Rewind(pos);
353          return false;
354      }
355  
356      lexer_->NextToken();
357  
358      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
359          lexer_->Rewind(pos);
360          return false;
361      }
362  
363      lexer_->NextToken();
364  
365      result = lexer_->GetToken().Type() == lexer::TokenType::KEYW_IN;
366  
367      lexer_->Rewind(pos);
368      return result;
369  }
370  
IsStartOfTsTypePredicate() const371  bool ParserImpl::IsStartOfTsTypePredicate() const
372  {
373      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
374             lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS);
375  
376      auto pos = lexer_->Save();
377      bool isAsserts = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
378      if (isAsserts) {
379          lexer_->NextToken();
380      }
381  
382      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT &&
383          lexer_->GetToken().Type() != lexer::TokenType::KEYW_THIS) {
384          lexer_->Rewind(pos);
385          return false;
386      }
387  
388      if (isAsserts) {
389          lexer_->Rewind(pos);
390          return true;
391      }
392  
393      lexer_->NextToken();
394  
395      bool result = !lexer_->GetToken().NewLine() && (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IS);
396      lexer_->Rewind(pos);
397      return result;
398  }
399  
IsStartOfAbstractConstructorType() const400  bool ParserImpl::IsStartOfAbstractConstructorType() const
401  {
402      if (lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) {
403          return false;
404      }
405  
406      lexer::LexerPosition pos = lexer_->Save();
407      lexer_->NextToken();  // eat 'abstract'
408      bool result = lexer_->GetToken().Type() == lexer::TokenType::KEYW_NEW;
409  
410      lexer_->Rewind(pos);
411  
412      return result;
413  }
414  
ParseTsTypeLiteralOrTsMappedType(ir::Expression * typeAnnotation)415  ir::Expression *ParserImpl::ParseTsTypeLiteralOrTsMappedType(ir::Expression *typeAnnotation)
416  {
417      if (typeAnnotation) {
418          return nullptr;
419      }
420  
421      if (IsStartOfMappedType()) {
422          return ParseTsMappedType();
423      }
424  
425      lexer::SourcePosition bodyStart = lexer_->GetToken().Start();
426      auto members = ParseTsTypeLiteralOrInterface();
427      lexer::SourcePosition bodyEnd = lexer_->GetToken().End();
428      lexer_->NextToken();
429  
430      auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members));
431      auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, literalType);
432      literalType->SetVariable(typeVar);
433      literalType->SetRange({bodyStart, bodyEnd});
434      return literalType;
435  }
436  
ParseTsTypeReferenceOrTsTypePredicate(ir::Expression * typeAnnotation,bool canBeTsTypePredicate,bool throwError)437  ir::Expression *ParserImpl::ParseTsTypeReferenceOrTsTypePredicate(ir::Expression *typeAnnotation,
438                                                                    bool canBeTsTypePredicate, bool throwError)
439  {
440      if (typeAnnotation) {
441          return nullptr;
442      }
443  
444      if (canBeTsTypePredicate && IsStartOfTsTypePredicate()) {
445          return ParseTsTypePredicate();
446      }
447  
448      return ParseTsTypeOperatorOrTypeReference(throwError);
449  }
450  
ParseTsThisTypeOrTsTypePredicate(ir::Expression * typeAnnotation,bool canBeTsTypePredicate,bool throwError)451  ir::Expression *ParserImpl::ParseTsThisTypeOrTsTypePredicate(ir::Expression *typeAnnotation, bool canBeTsTypePredicate,
452                                                               bool throwError)
453  {
454      if (typeAnnotation) {
455          return nullptr;
456      }
457  
458      if (canBeTsTypePredicate && IsStartOfTsTypePredicate()) {
459          return ParseTsTypePredicate();
460      }
461  
462      return ParseTsThisType(throwError);
463  }
464  
ParseTsTemplateLiteralType(bool throwError)465  ir::Expression *ParserImpl::ParseTsTemplateLiteralType(bool throwError)
466  {
467      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK);
468      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
469  
470      ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter());
471      ArenaVector<ir::Expression *> references(Allocator()->Adapter());
472  
473      while (true) {
474          lexer_->ResetTokenEnd();
475          const auto startPos = lexer_->Save();
476  
477          lexer_->ScanString<LEX_CHAR_BACK_TICK>();
478          util::StringView cooked = lexer_->GetToken().String();
479  
480          lexer_->Rewind(startPos);
481          auto [raw, end, scanExpression] = lexer_->ScanTemplateString();
482  
483          auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked);
484          element->SetRange({lexer::SourcePosition{startPos.iterator.Index(), startPos.line},
485                             lexer::SourcePosition{end, lexer_->Line()}});
486          quasis.push_back(element);
487  
488          if (!scanExpression) {
489              lexer_->ScanTemplateStringEnd();
490              break;
491          }
492  
493          ir::Expression *reference = nullptr;
494  
495          {
496              lexer::TemplateLiteralParserContext ctx(lexer_);
497              lexer_->PushTemplateContext(&ctx);
498              lexer_->NextToken();
499              TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
500              reference = ParseTsTypeAnnotation(&options);
501          }
502  
503          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
504              if (throwError) {
505                  ThrowSyntaxError("Unexpected token, expected '}'.");
506              }
507              return nullptr;
508          }
509  
510          references.push_back(reference);
511      }
512  
513      ir::Expression *typeAnnotation = AllocNode<ir::TSTemplateLiteralType>(std::move(quasis), std::move(references));
514      typeAnnotation->SetRange({startLoc, lexer_->GetToken().End()});
515  
516      lexer_->NextToken();
517  
518      return typeAnnotation;
519  }
520  
ParseTsTypeAnnotationElement(ir::Expression * typeAnnotation,TypeAnnotationParsingOptions * options)521  ir::Expression *ParserImpl::ParseTsTypeAnnotationElement(ir::Expression *typeAnnotation,
522                                                           TypeAnnotationParsingOptions *options)
523  {
524      switch (lexer_->GetToken().Type()) {
525          case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
526              if (*options & (TypeAnnotationParsingOptions::IN_MODIFIER | TypeAnnotationParsingOptions::IN_UNION |
527                  TypeAnnotationParsingOptions::IN_INTERSECTION)) {
528                  break;
529              }
530  
531              return ParseTsUnionType(typeAnnotation, *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS);
532          }
533          case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
534              if (*options & (TypeAnnotationParsingOptions::IN_MODIFIER |
535  	        TypeAnnotationParsingOptions::IN_INTERSECTION)) {
536                  break;
537              }
538  
539              return ParseTsIntersectionType(typeAnnotation, *options & TypeAnnotationParsingOptions::IN_UNION,
540                                             *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS);
541          }
542          case lexer::TokenType::PUNCTUATOR_LESS_THAN:
543          case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
544          case lexer::TokenType::KEYW_NEW: {
545              return ParseTsParenthesizedOrFunctionType(typeAnnotation,
546                                                        *options & TypeAnnotationParsingOptions::THROW_ERROR);
547          }
548          case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
549              if (typeAnnotation) {
550                  if (lexer_->GetToken().NewLine()) {
551                      break;
552                  }
553                  if (lexer_->Lookahead() == LEX_CHAR_RIGHT_SQUARE) {
554                      return ParseTsArrayType(typeAnnotation);
555                  }
556  
557                  return ParseTsIndexAccessType(typeAnnotation, *options & TypeAnnotationParsingOptions::THROW_ERROR);
558              }
559  
560              return ParseTsTupleType();
561          }
562          case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
563              return ParseTsTypeLiteralOrTsMappedType(typeAnnotation);
564          }
565          case lexer::TokenType::PUNCTUATOR_MINUS:
566          case lexer::TokenType::LITERAL_NUMBER:
567          case lexer::TokenType::LITERAL_STRING:
568          case lexer::TokenType::LITERAL_FALSE:
569          case lexer::TokenType::LITERAL_TRUE:
570          case lexer::TokenType::LITERAL_NULL:
571          case lexer::TokenType::KEYW_VOID: {
572              if (typeAnnotation) {
573                  break;
574              }
575  
576              return ParseTsBasicType(*options);
577          }
578          case lexer::TokenType::KEYW_TYPEOF: {
579              if (typeAnnotation) {
580                  break;
581              }
582  
583              return ParseTsTypeReferenceOrQuery(*options, true);
584          }
585          case lexer::TokenType::KEYW_IMPORT: {
586              if (typeAnnotation) {
587                  break;
588              }
589  
590              lexer::SourcePosition startLoc = lexer_->GetToken().Start();
591              return ParseTsImportType(startLoc);
592          }
593          case lexer::TokenType::KEYW_CONST: {
594              if (!(*options & TypeAnnotationParsingOptions::ALLOW_CONST)) {
595                  break;
596              }
597  
598              *options &= ~TypeAnnotationParsingOptions::ALLOW_CONST;
599              return ParseTsConstExpression();
600          }
601          case lexer::TokenType::LITERAL_IDENT: {
602              if (IsStartOfAbstractConstructorType()) {
603                  return ParseTsParenthesizedOrFunctionType(typeAnnotation,
604                                                            *options & TypeAnnotationParsingOptions::THROW_ERROR);
605              }
606  
607              return ParseTsTypeReferenceOrTsTypePredicate(
608                  typeAnnotation, *options & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE,
609                  *options & TypeAnnotationParsingOptions::THROW_ERROR);
610          }
611          case lexer::TokenType::KEYW_EXTENDS: {
612              if (*options & (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) {
613                  break;
614              }
615  
616              if (!typeAnnotation) {
617                  return ParseTsIdentifierReference(*options);
618              }
619  
620              return ParseTsConditionalType(typeAnnotation, *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS);
621          }
622          case lexer::TokenType::KEYW_THIS: {
623              return ParseTsThisTypeOrTsTypePredicate(typeAnnotation,
624                                                      *options & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE,
625                                                      *options & TypeAnnotationParsingOptions::THROW_ERROR);
626          }
627          case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
628              return ParseTsTemplateLiteralType(*options & TypeAnnotationParsingOptions::THROW_ERROR);
629          }
630          default: {
631              break;
632          }
633      }
634  
635      if (!typeAnnotation && (*options & TypeAnnotationParsingOptions::THROW_ERROR)) {
636          ThrowSyntaxError("Type expected");
637      }
638  
639      return nullptr;
640  }
641  
ParseTsImportType(const lexer::SourcePosition & startLoc,bool isTypeof)642  ir::TSImportType *ParserImpl::ParseTsImportType(const lexer::SourcePosition &startLoc, bool isTypeof)
643  {
644      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_IMPORT);
645  
646      lexer_->NextToken();
647  
648      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
649          ThrowSyntaxError("'(' expected");
650      }
651  
652      lexer_->NextToken();
653  
654      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
655      ir::Expression *param = ParseTsTypeAnnotation(&options);
656  
657      if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) {
658          ThrowSyntaxError("String literal expected");
659      }
660  
661      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
662          ThrowSyntaxError("')' expected");
663      }
664  
665      lexer_->NextToken();
666  
667      ir::Expression *qualifier = nullptr;
668      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
669          lexer_->NextToken();
670  
671          if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
672              ThrowSyntaxError("Identifier expected");
673          }
674  
675          qualifier = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
676          qualifier->SetRange(lexer_->GetToken().Loc());
677  
678          lexer_->NextToken();
679  
680          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
681              qualifier = ParseTsQualifiedReference(qualifier);
682          }
683      }
684  
685      ir::TSTypeParameterInstantiation *typeParams = nullptr;
686      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT ||
687          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
688          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
689              lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
690          }
691  
692          typeParams = ParseTsTypeParameterInstantiation();
693      }
694  
695      auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof);
696  
697      importType->SetRange({startLoc, lexer_->GetToken().End()});
698  
699      return importType;
700  }
701  
ParseTsThisType(bool throwError)702  ir::Expression *ParserImpl::ParseTsThisType(bool throwError)
703  {
704      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS);
705  
706      if (throwError && !(context_.Status() & ParserStatus::ALLOW_THIS_TYPE)) {
707          ThrowSyntaxError(
708              "A 'this' type is available only in a non-static member "
709              "of a class or interface.");
710      }
711  
712      auto *returnType = AllocNode<ir::TSThisType>();
713      returnType->SetRange(lexer_->GetToken().Loc());
714  
715      lexer_->NextToken();
716  
717      return returnType;
718  }
719  
ParseTsConditionalType(ir::Expression * checkType,bool restrictExtends)720  ir::Expression *ParserImpl::ParseTsConditionalType(ir::Expression *checkType, bool restrictExtends)
721  {
722      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
723      if (restrictExtends) {
724          ThrowSyntaxError("'?' expected.");
725      }
726  
727      lexer::SourcePosition startLoc = checkType->Start();
728  
729      lexer_->NextToken();  // eat 'extends'
730  
731      ParserStatus savedStatus = context_.Status();
732      context_.Status() |= ParserStatus::IN_EXTENDS;
733  
734      TypeAnnotationParsingOptions options =
735          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
736      auto *extendsType = ParseTsTypeAnnotation(&options);
737  
738      context_.Status() = savedStatus;
739  
740      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
741          ThrowSyntaxError("'?' expected.");
742      }
743  
744      lexer_->NextToken();  // eat '?'
745  
746      options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
747      auto *trueType = ParseTsTypeAnnotation(&options);
748  
749      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
750          ThrowSyntaxError("':' expected.");
751      }
752  
753      lexer_->NextToken();  // eat ':'
754  
755      auto *falseType = ParseTsTypeAnnotation(&options);
756  
757      lexer::SourcePosition endLoc = falseType->End();
758  
759      auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType);
760  
761      conditionalType->SetRange({startLoc, endLoc});
762  
763      return conditionalType;
764  }
765  
ParseTsTypeAnnotation(TypeAnnotationParsingOptions * options)766  ir::Expression *ParserImpl::ParseTsTypeAnnotation(TypeAnnotationParsingOptions *options)
767  {
768      ir::Expression *typeAnnotation = nullptr;
769  
770      while (true) {
771          ir::Expression *element = ParseTsTypeAnnotationElement(typeAnnotation, options);
772  
773          *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
774  
775          if (!element) {
776              break;
777          }
778  
779          typeAnnotation = element;
780  
781          if ((*options & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) && lexer_->GetToken().NewLine()) {
782              break;
783          }
784      }
785  
786      return typeAnnotation;
787  }
788  
ParseTsTypeOperatorOrTypeReference(bool throwError)789  ir::Expression *ParserImpl::ParseTsTypeOperatorOrTypeReference(bool throwError)
790  {
791      TypeAnnotationParsingOptions options = throwError ?
792          TypeAnnotationParsingOptions::THROW_ERROR : TypeAnnotationParsingOptions::NO_OPTS;
793  
794      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
795          lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start();
796          lexer_->NextToken();
797  
798          options |= TypeAnnotationParsingOptions::IN_MODIFIER;
799          ir::Expression *type = ParseTsTypeAnnotation(&options);
800          ASSERT(type != nullptr);
801  
802          if (!type->IsTSArrayType() && !type->IsTSTupleType()) {
803              ThrowSyntaxError(
804                  "'readonly' type modifier is only permitted on array "
805                  "and tuple literal types.");
806          }
807  
808          auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY);
809  
810          typeOperator->SetRange({typeOperatorStart, type->End()});
811  
812          return typeOperator;
813      }
814  
815      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) {
816          lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start();
817          lexer_->NextToken();
818  
819          options |= TypeAnnotationParsingOptions::IN_MODIFIER;
820          ir::Expression *type = ParseTsTypeAnnotation(&options);
821          ASSERT(type != nullptr);
822  
823          auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF);
824  
825          typeOperator->SetRange({typeOperatorStart, type->End()});
826  
827          return typeOperator;
828      }
829  
830      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNIQUE) {
831          lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start();
832          lexer_->NextToken();
833  
834          ir::Expression *type = ParseTsTypeAnnotation(&options);
835          ASSERT(type != nullptr);
836  
837          auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::UNIQUE);
838  
839          typeOperator->SetRange({typeOperatorStart, type->End()});
840  
841          return typeOperator;
842      }
843  
844      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) {
845          if (!(context_.Status() & ParserStatus::IN_EXTENDS)) {
846              ThrowSyntaxError(
847                  "'infer' declarations are only permitted in the "
848                  "'extends' clause of a conditional type.");
849          }
850  
851          lexer::SourcePosition inferStart = lexer_->GetToken().Start();
852          lexer_->NextToken();
853  
854          ir::TSTypeParameter *typeParam = ParseTsTypeParameter(true);
855  
856          auto *inferType = AllocNode<ir::TSInferType>(typeParam);
857  
858          inferType->SetRange({inferStart, lexer_->GetToken().End()});
859  
860          return inferType;
861      }
862  
863      return ParseTsIdentifierReference(options);
864  }
865  
IsTSNamedTupleMember()866  bool ParserImpl::IsTSNamedTupleMember()
867  {
868      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
869          return false;
870      }
871      const auto savePos = lexer_->Save();
872      bool isNamedMember = false;
873      lexer_->NextToken();
874      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON ||
875          (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK &&
876           lexer_->Lookahead() == LEX_CHAR_COLON)) {
877              isNamedMember = true;
878      }
879      lexer_->Rewind(savePos);
880      return isNamedMember;
881  }
882  
HandleRestType(ir::AstNodeType elementType,bool * hasRestType) const883  void ParserImpl::HandleRestType(ir::AstNodeType elementType, bool *hasRestType) const
884  {
885      if (elementType ==  ir::AstNodeType::TS_ARRAY_TYPE && *hasRestType) {
886          ThrowSyntaxError("A rest element cannot follow another rest element");
887      }
888      *hasRestType = true;
889  }
890  
ParseTsTupleElement(ir::TSTupleKind * kind,bool * seenOptional,bool * hasRestType)891  ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional, bool *hasRestType)
892  {
893      lexer::SourcePosition startPos = lexer_->GetToken().Start();
894      ir::Expression *element = nullptr;
895      bool isRestType = false;
896      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
897  
898      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
899          isRestType = true;
900          lexer_->NextToken();  // eat '...'
901      }
902  
903      if (IsTSNamedTupleMember()) {
904          if (*kind == ir::TSTupleKind::DEFAULT) {
905              ThrowSyntaxError("Tuple members must all have or haven't names");
906          }
907          *kind = ir::TSTupleKind::NAMED;
908  
909          auto *elementIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
910          elementIdent->SetRange(lexer_->GetToken().Loc());
911          lexer_->NextToken();  // eat identifier
912  
913          bool isOptional = false;
914          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
915              lexer_->NextToken();  // eat '?'
916              isOptional = true;
917              *seenOptional = true;
918          } else if (*seenOptional && !isRestType) {
919              ThrowSyntaxError("A required element cannot follow an optional element");
920          }
921  
922          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
923              ThrowSyntaxError("':' expected");
924          }
925  
926          lexer_->NextToken();  // eat ':'
927          auto *elementType = ParseTsTypeAnnotation(&options);
928          ASSERT(elementType != nullptr);
929  
930          if (elementType && isRestType) {
931              HandleRestType(elementType->Type(), hasRestType);
932          }
933  
934          element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional, isRestType);
935          element->SetRange({startPos, elementType->End()});
936      } else {
937          if (*kind == ir::TSTupleKind::NAMED) {
938              ThrowSyntaxError("Tuple members must all have or haven't names");
939          }
940          *kind = ir::TSTupleKind::DEFAULT;
941  
942          element = ParseTsTypeAnnotation(&options);
943          ASSERT(element != nullptr);
944          if (element && isRestType) {
945              HandleRestType(element->Type(), hasRestType);
946              lexer::SourcePosition endPos = element->End();
947              element = AllocNode<ir::TSRestType>(std::move(element));
948              element->SetRange({startPos, endPos});
949          }
950  
951          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
952              lexer::SourcePosition elementStartPos = element->Start();
953              element = AllocNode<ir::TSOptionalType>(std::move(element));
954              element->SetRange({elementStartPos, lexer_->GetToken().End()});
955              lexer_->NextToken();  // eat '?'
956              *seenOptional = true;
957          } else if (*seenOptional && !isRestType) {
958              ThrowSyntaxError("A required element cannot follow an optional element");
959          }
960      }
961      return element;
962  }
963  
ParseTsTupleType()964  ir::TSTupleType *ParserImpl::ParseTsTupleType()
965  {
966      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
967      lexer::SourcePosition tupleStart = lexer_->GetToken().Start();
968      ArenaVector<ir::Expression *> elements(Allocator()->Adapter());
969      ir::TSTupleKind kind = ir::TSTupleKind::NONE;
970      bool seenOptional = false;
971      bool hasRestType = false;
972  
973      lexer_->NextToken();  // eat '['
974  
975      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
976          ir::Expression *element = ParseTsTupleElement(&kind, &seenOptional, &hasRestType);
977  
978          elements.push_back(element);
979  
980          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
981              break;
982          }
983  
984          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
985              ThrowSyntaxError("',' expected.");
986          }
987  
988          lexer_->NextToken();  // eat ','
989      }
990  
991      lexer::SourcePosition tupleEnd = lexer_->GetToken().End();
992      lexer_->NextToken();  // eat ']'
993  
994      auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements));
995      tupleType->SetRange({tupleStart, tupleEnd});
996      return tupleType;
997  }
998  
ParseTsQualifiedReference(ir::Expression * typeName)999  ir::Expression *ParserImpl::ParseTsQualifiedReference(ir::Expression *typeName)
1000  {
1001      lexer::SourcePosition startLoc = typeName->Start();
1002  
1003      do {
1004          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat '.'
1005  
1006          if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1007              ThrowSyntaxError("Identifier expected");
1008          }
1009  
1010          auto *propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1011          propName->SetRange(lexer_->GetToken().Loc());
1012  
1013          typeName = AllocNode<ir::TSQualifiedName>(typeName, propName);
1014          typeName->SetRange({typeName->AsTSQualifiedName()->Left()->Start(), lexer_->GetToken().End()});
1015  
1016          lexer_->NextToken();
1017      } while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD);
1018  
1019      typeName->SetRange({startLoc, lexer_->GetToken().End()});
1020  
1021      return typeName;
1022  }
1023  
ParseTsIndexAccessType(ir::Expression * typeName,bool throwError)1024  ir::Expression *ParserImpl::ParseTsIndexAccessType(ir::Expression *typeName, bool throwError)
1025  {
1026      TypeAnnotationParsingOptions options = throwError ?
1027          TypeAnnotationParsingOptions::THROW_ERROR : TypeAnnotationParsingOptions::NO_OPTS;
1028  
1029      do {
1030          lexer_->NextToken();  // eat '['
1031  
1032          ir::Expression *indexType = ParseTsTypeAnnotation(&options);
1033  
1034          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1035              if (!throwError) {
1036                  return nullptr;
1037              }
1038              ThrowSyntaxError("']' expected");
1039          }
1040  
1041          lexer_->NextToken();  // eat ']'
1042  
1043          typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType);
1044          typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), lexer_->GetToken().End()});
1045      } while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
1046               lexer_->Lookahead() != LEX_CHAR_RIGHT_SQUARE);
1047  
1048      return typeName;
1049  }
1050  
ParseTsTypeReferenceOrQuery(TypeAnnotationParsingOptions options,bool parseQuery)1051  ir::Expression *ParserImpl::ParseTsTypeReferenceOrQuery(TypeAnnotationParsingOptions options, bool parseQuery)
1052  {
1053      lexer::SourcePosition referenceStartLoc = lexer_->GetToken().Start();
1054  
1055      if (parseQuery) {
1056          ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF);
1057          lexer_->NextToken();  // eat 'typeof'
1058  
1059          if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) {
1060              lexer::SourcePosition &startLoc = referenceStartLoc;
1061              return ParseTsImportType(startLoc, true);
1062          }
1063  
1064          if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1065              ThrowSyntaxError("Identifier expected.");
1066          }
1067      }
1068  
1069      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
1070             lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
1071  
1072      ir::Expression *typeName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1073      typeName->SetRange(lexer_->GetToken().Loc());
1074      typeName->AsIdentifier()->SetReference();
1075  
1076      if (lexer_->Lookahead() == LEX_CHAR_LESS_THAN) {
1077          lexer_->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1078      } else {
1079          lexer_->NextToken();
1080      }
1081  
1082      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1083          typeName = ParseTsQualifiedReference(typeName);
1084      }
1085  
1086      ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
1087      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1088          if (parseQuery) {
1089              ThrowSyntaxError("Unexpected token.");
1090          }
1091  
1092          typeParamInst = ParseTsTypeParameterInstantiation(options & TypeAnnotationParsingOptions::THROW_ERROR);
1093      }
1094  
1095      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
1096          lexer_->Lookahead() != LEX_CHAR_RIGHT_SQUARE) {
1097          if (parseQuery) {
1098              typeName = AllocNode<ir::TSTypeQuery>(typeName);
1099          } else {
1100              typeName = AllocNode<ir::TSTypeReference>(typeName, typeParamInst);
1101          }
1102  
1103          typeName->SetRange({referenceStartLoc, lexer_->GetToken().End()});
1104  
1105          return ParseTsIndexAccessType(typeName, options & TypeAnnotationParsingOptions::THROW_ERROR);
1106      }
1107  
1108      ir::Expression *returnNode = nullptr;
1109  
1110      lexer::SourcePosition referenceEndLoc = typeName->End();
1111  
1112      if (parseQuery) {
1113          returnNode = AllocNode<ir::TSTypeQuery>(typeName);
1114      } else {
1115          returnNode = AllocNode<ir::TSTypeReference>(typeName, typeParamInst);
1116      }
1117  
1118      returnNode->SetRange({referenceStartLoc, referenceEndLoc});
1119  
1120      return returnNode;
1121  }
1122  
ParseTsMappedTypeParameter()1123  ir::TSTypeParameter *ParserImpl::ParseTsMappedTypeParameter()
1124  {
1125      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1126  
1127      auto *paramName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1128      paramName->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()});
1129  
1130      lexer_->NextToken();
1131  
1132      lexer_->NextToken();  // eat 'in'
1133  
1134      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1135      ir::Expression *constraint = ParseTsTypeAnnotation(&options);
1136  
1137      lexer::SourcePosition endLoc = constraint->End();
1138  
1139      auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr);
1140  
1141      typeParameter->SetRange({startLoc, endLoc});
1142  
1143      return typeParameter;
1144  }
1145  
ParseMappedOption(lexer::TokenType tokenType)1146  ir::MappedOption ParserImpl::ParseMappedOption(lexer::TokenType tokenType)
1147  {
1148      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS &&
1149          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS &&
1150          lexer_->GetToken().KeywordType() != tokenType && lexer_->GetToken().Type() != tokenType) {
1151          return ir::MappedOption::NO_OPTS;
1152      }
1153  
1154      auto result = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS
1155                                                                                    : ir::MappedOption::PLUS;
1156  
1157      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
1158          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
1159          lexer_->NextToken();
1160      }
1161  
1162      if (lexer_->GetToken().KeywordType() != tokenType && lexer_->GetToken().Type() != tokenType) {
1163          ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."});
1164      }
1165  
1166      lexer_->NextToken();
1167  
1168      return result;
1169  }
1170  
ParseTsMappedType()1171  ir::TSMappedType *ParserImpl::ParseTsMappedType()
1172  {
1173      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
1174  
1175      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1176      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
1177  
1178      ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY);
1179  
1180      lexer_->NextToken();  // eat '['
1181  
1182      ir::TSTypeParameter *typeParameter = ParseTsMappedTypeParameter();
1183  
1184      ir::Expression *nameKeyType = nullptr;
1185      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) {
1186          lexer_->NextToken();  // eat 'as'
1187          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1188          nameKeyType = ParseTsTypeAnnotation(&options);
1189          ASSERT(nameKeyType != nullptr);
1190      }
1191  
1192      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1193          ThrowSyntaxError("']' expected");
1194      }
1195  
1196      lexer_->NextToken();  // eat ']'
1197  
1198      ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK);
1199  
1200      ir::Expression *typeAnnotation = nullptr;
1201      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1202          lexer_->NextToken();  // eat ':'
1203          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1204          typeAnnotation = ParseTsTypeAnnotation(&options);
1205      }
1206  
1207      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
1208          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1209          ThrowSyntaxError("';' expected");
1210      }
1211  
1212      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
1213          lexer_->NextToken();  // eat ';'
1214      }
1215  
1216      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1217          ThrowSyntaxError("'}' expected");
1218      }
1219  
1220      auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, nameKeyType, typeAnnotation, readonly, optional);
1221  
1222      mappedType->SetRange({startLoc, lexer_->GetToken().End()});
1223  
1224      lexer_->NextToken();  // eat '}'
1225  
1226      return mappedType;
1227  }
1228  
ParseTsTypePredicate()1229  ir::TSTypePredicate *ParserImpl::ParseTsTypePredicate()
1230  {
1231      auto pos = lexer_->Save();
1232      lexer::SourcePosition startPos = lexer_->GetToken().Start();
1233      bool isAsserts = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
1234      if (isAsserts) {
1235          lexer_->NextToken();  // eat 'asserts'
1236          if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) {
1237              isAsserts = false;
1238              lexer_->Rewind(pos);
1239          }
1240      }
1241  
1242      ir::Expression *parameterName = nullptr;
1243      if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1244          parameterName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1245      } else {
1246          parameterName = AllocNode<ir::TSThisType>();
1247      }
1248  
1249      parameterName->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()});
1250  
1251      lexer_->NextToken();
1252  
1253      ir::Expression *typeAnnotation = nullptr;
1254      lexer::SourcePosition endPos;
1255      ir::TSTypePredicate *result = nullptr;
1256  
1257      if (isAsserts && lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) {
1258          endPos = parameterName->End();
1259          result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
1260          result->SetRange({startPos, endPos});
1261          return result;
1262      }
1263  
1264      lexer_->NextToken();  // eat 'is'
1265  
1266      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1267      typeAnnotation = ParseTsTypeAnnotation(&options);
1268      endPos = typeAnnotation->End();
1269  
1270      result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
1271  
1272      result->SetRange({startPos, endPos});
1273  
1274      return result;
1275  }
1276  
ParseTsTypeLiteralOrInterfaceKey(bool * computed,bool * signature,bool * isIndexSignature)1277  ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceKey(bool *computed, bool *signature, bool *isIndexSignature)
1278  {
1279      ir::Expression *key = nullptr;
1280  
1281      if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1282          (lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_NEW ||
1283           (lexer_->Lookahead() != LEX_CHAR_LEFT_PAREN && lexer_->Lookahead() != LEX_CHAR_LESS_THAN))) {
1284          key = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1285          key->SetRange(lexer_->GetToken().Loc());
1286          lexer_->NextToken();
1287      } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER) {
1288          if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
1289              key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
1290          } else {
1291              key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
1292          }
1293  
1294          key->SetRange(lexer_->GetToken().Loc());
1295          lexer_->NextToken();
1296      } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) {
1297          key = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
1298          key->SetRange(lexer_->GetToken().Loc());
1299          lexer_->NextToken();
1300      } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1301          *computed = true;
1302          lexer_->NextToken();  // eat '['
1303  
1304          if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && lexer_->Lookahead() == LEX_CHAR_COLON) {
1305              *isIndexSignature = true;
1306              key = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1307              key->SetRange(lexer_->GetToken().Loc());
1308  
1309              lexer_->NextToken();  // eat param
1310  
1311              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1312                  ThrowSyntaxError("':' expected");
1313              }
1314  
1315              lexer_->NextToken();  // eat ':'
1316  
1317              TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1318              ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options);
1319  
1320              if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) {
1321                  ThrowSyntaxError(
1322                      "An index signature parameter type must be either "
1323                      "'string' or 'number'");
1324              }
1325  
1326              key->SetTsTypeAnnotation(typeAnnotation);
1327          } else {
1328              key = ParseExpression();
1329          }
1330  
1331          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1332              ThrowSyntaxError("']' expected");
1333          }
1334  
1335          lexer_->NextToken();  // eat ']'
1336      } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1337                 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN &&
1338                 lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_NEW) {
1339          ThrowSyntaxError("Unexpected token");
1340      } else {
1341          *signature = true;
1342      }
1343  
1344      return key;
1345  }
1346  
CreateTSVariableForProperty(ir::AstNode * node,const ir::Expression * key,binder::VariableFlags flags)1347  void ParserImpl::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, binder::VariableFlags flags)
1348  {
1349      binder::Variable *propVar = nullptr;
1350      bool isMethod = flags & binder::VariableFlags::METHOD;
1351      util::StringView propName = "__computed";
1352  
1353      switch (key->Type()) {
1354          case ir::AstNodeType::IDENTIFIER: {
1355              propName = key->AsIdentifier()->Name();
1356              break;
1357          }
1358          case ir::AstNodeType::NUMBER_LITERAL: {
1359              propName = key->AsNumberLiteral()->Str();
1360              flags |= binder::VariableFlags::NUMERIC_NAME;
1361              break;
1362          }
1363          case ir::AstNodeType::STRING_LITERAL: {
1364              propName = key->AsStringLiteral()->Str();
1365              break;
1366          }
1367          default: {
1368              flags |= binder::VariableFlags::COMPUTED;
1369              break;
1370          }
1371      }
1372  
1373      propVar = isMethod ? binder::Scope::CreateVar<binder::MethodDecl>(Allocator(), propName, flags, node)
1374                         : binder::Scope::CreateVar<binder::PropertyDecl>(Allocator(), propName, flags, node);
1375  
1376      node->SetVariable(propVar);
1377  }
1378  
ParseTsTypeLiteralOrInterfaceMember()1379  ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceMember()
1380  {
1381      bool computed = false;
1382      bool optional = false;
1383      bool signature = false;
1384      bool readonly = false;
1385      bool isConstructSignature = false;
1386      bool isIndexSignature = false;
1387      lexer::SourcePosition memberStartLoc = lexer_->GetToken().Start();
1388      char32_t nextToken = lexer_->Lookahead();
1389      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY && nextToken != LEX_CHAR_LEFT_PAREN &&
1390          nextToken != LEX_CHAR_COLON && nextToken != LEX_CHAR_COMMA && nextToken != LEX_CHAR_LESS_THAN &&
1391          nextToken != LEX_CHAR_SEMICOLON) {
1392          readonly = true;
1393          lexer_->NextToken();
1394      }
1395  
1396      ir::Expression *key = ParseTsTypeLiteralOrInterfaceKey(&computed, &signature, &isIndexSignature);
1397  
1398      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1399          if (isIndexSignature) {
1400              ThrowSyntaxError("';' expected");
1401          }
1402  
1403          optional = true;
1404          lexer_->NextToken();  // eat '?'
1405      }
1406  
1407      if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW && signature) {
1408          lexer_->NextToken();  // eat 'new'
1409  
1410          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1411              lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1412              ThrowSyntaxError("'(' expected");
1413          }
1414  
1415          isConstructSignature = true;
1416      }
1417  
1418      ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1419      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1420          if (isIndexSignature) {
1421              ThrowSyntaxError("';' expected");
1422          }
1423  
1424          typeParamDecl = ParseTsTypeParameterDeclaration();
1425  
1426          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1427              ThrowSyntaxError("'(' expected");
1428          }
1429      }
1430  
1431      ir::Expression *member = nullptr;
1432      ir::Expression *typeAnnotation = nullptr;
1433      binder::VariableFlags flags = binder::VariableFlags::NONE;
1434  
1435      if (optional) {
1436          flags |= binder::VariableFlags::OPTIONAL;
1437      }
1438  
1439      if (readonly) {
1440          flags |= binder::VariableFlags::READONLY;
1441      }
1442  
1443      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && !isIndexSignature) {
1444          FunctionParameterContext funcParamContext(&context_, Binder());
1445          auto *funcParamScope = funcParamContext.LexicalScope().GetScope();
1446          ArenaVector<ir::Expression *> params = ParseFunctionParams(true);
1447  
1448          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1449              lexer_->NextToken();  // eat ':'
1450              TypeAnnotationParsingOptions options =
1451                  TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1452              typeAnnotation = ParseTsTypeAnnotation(&options);
1453          }
1454  
1455          if (signature) {
1456              auto kind = isConstructSignature
1457                              ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE
1458                              : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE;
1459              member = AllocNode<ir::TSSignatureDeclaration>(funcParamScope, kind, typeParamDecl, std::move(params),
1460                                                             typeAnnotation);
1461              funcParamScope->BindNode(member);
1462          } else {
1463              member = AllocNode<ir::TSMethodSignature>(funcParamScope, key, typeParamDecl, std::move(params),
1464                                                        typeAnnotation, computed, optional);
1465              funcParamScope->BindNode(member);
1466              CreateTSVariableForProperty(member, key, flags | binder::VariableFlags::METHOD);
1467          }
1468      } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1469          lexer_->NextToken();  // eat ':'
1470          TypeAnnotationParsingOptions options =
1471              TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1472          typeAnnotation = ParseTsTypeAnnotation(&options);
1473      } else if (isIndexSignature) {
1474          ThrowSyntaxError("An index signature must have a type annotation.", memberStartLoc);
1475      }
1476  
1477      if (!member && isIndexSignature) {
1478          member = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, readonly);
1479      } else if (!member) {
1480          member = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, computed, optional, readonly);
1481          CreateTSVariableForProperty(member, key, flags | binder::VariableFlags::PROPERTY);
1482      } else if (readonly) {
1483          ThrowSyntaxError(
1484              "'readonly' modifier can only appear on a property "
1485              "declaration or index signature.",
1486              memberStartLoc);
1487      }
1488  
1489      member->SetRange({memberStartLoc, lexer_->GetToken().End()});
1490  
1491      return member;
1492  }
1493  
GetTSPropertyName(ir::Expression * key)1494  util::StringView GetTSPropertyName(ir::Expression *key)
1495  {
1496      switch (key->Type()) {
1497          case ir::AstNodeType::IDENTIFIER: {
1498              return key->AsIdentifier()->Name();
1499          }
1500          case ir::AstNodeType::NUMBER_LITERAL: {
1501              return key->AsNumberLiteral()->Str();
1502          }
1503          case ir::AstNodeType::STRING_LITERAL: {
1504              return key->AsStringLiteral()->Str();
1505          }
1506          default: {
1507              UNREACHABLE();
1508          }
1509      }
1510  }
1511  
CheckObjectTypeForDuplicatedProperties(ir::Expression * member,ArenaVector<ir::Expression * > const & members)1512  void ParserImpl::CheckObjectTypeForDuplicatedProperties(ir::Expression *member, ArenaVector<ir::Expression *> const &members)
1513  {
1514      ir::Expression *key = nullptr;
1515  
1516      if (member->IsTSPropertySignature()) {
1517          key = member->AsTSPropertySignature()->Key();
1518      } else if (member->IsTSMethodSignature()) {
1519          key = member->AsTSMethodSignature()->Key();
1520      } else {
1521          return;
1522      }
1523  
1524      if (!key->IsIdentifier() && !key->IsNumberLiteral() && !key->IsStringLiteral()) {
1525          return;
1526      }
1527  
1528      for (auto *it : members) {
1529          ir::Expression *compare = nullptr;
1530  
1531          switch (it->Type()) {
1532              case ir::AstNodeType::TS_PROPERTY_SIGNATURE: {
1533                  compare = it->AsTSPropertySignature()->Key();
1534                  break;
1535              }
1536              case ir::AstNodeType::TS_METHOD_SIGNATURE: {
1537                  compare = it->AsTSMethodSignature()->Key();
1538                  break;
1539              }
1540              default: {
1541                  continue;
1542              }
1543          }
1544  
1545          if (!compare->IsIdentifier() && !compare->IsNumberLiteral() && !compare->IsStringLiteral()) {
1546              continue;
1547          }
1548  
1549          if (member->IsTSMethodSignature() && it->Type() == ir::AstNodeType::TS_METHOD_SIGNATURE) {
1550              continue;
1551          }
1552  
1553          if (GetTSPropertyName(key) == GetTSPropertyName(compare)) {
1554              ThrowSyntaxError("Duplicated identifier", key->Start());
1555          }
1556      }
1557  }
1558  
ParseTsTypeLiteralOrInterface()1559  ArenaVector<ir::Expression *> ParserImpl::ParseTsTypeLiteralOrInterface()
1560  {
1561      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
1562  
1563      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
1564  
1565      ArenaVector<ir::Expression *> members(Allocator()->Adapter());
1566  
1567      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1568          ir::Expression *member = ParseTsTypeLiteralOrInterfaceMember();
1569  
1570          CheckObjectTypeForDuplicatedProperties(member, members);
1571  
1572          members.push_back(member);
1573  
1574          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1575              break;
1576          }
1577  
1578          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1579              lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
1580              if (!lexer_->GetToken().NewLine()) {
1581                  ThrowSyntaxError("',' expected");
1582              }
1583  
1584              if (lexer_->GetToken().IsKeyword()) {
1585                  lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
1586              }
1587  
1588              continue;
1589          }
1590  
1591          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1592      }
1593  
1594      return members;
1595  }
1596  
ParseTsArrayType(ir::Expression * elementType)1597  ir::TSArrayType *ParserImpl::ParseTsArrayType(ir::Expression *elementType)
1598  {
1599      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
1600      lexer_->NextToken();  // eat '['
1601  
1602      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1603          ThrowSyntaxError("']' expected");
1604      }
1605  
1606      lexer::SourcePosition endLoc = lexer_->GetToken().End();
1607      lexer_->NextToken();  // eat ']'
1608  
1609      lexer::SourcePosition startLoc = elementType->Start();
1610      auto *arrayType = AllocNode<ir::TSArrayType>(elementType);
1611      arrayType->SetRange({startLoc, endLoc});
1612  
1613      return arrayType;
1614  }
1615  
ParseTsUnionType(ir::Expression * type,bool restrictExtends)1616  ir::TSUnionType *ParserImpl::ParseTsUnionType(ir::Expression *type, bool restrictExtends)
1617  {
1618      ArenaVector<ir::Expression *> types(Allocator()->Adapter());
1619      lexer::SourcePosition startLoc;
1620  
1621      TypeAnnotationParsingOptions options =
1622          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::IN_UNION;
1623  
1624      if (restrictExtends) {
1625          options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
1626      }
1627  
1628      if (type) {
1629          startLoc = type->Start();
1630          types.push_back(type);
1631      } else {
1632          startLoc = lexer_->GetToken().Start();
1633      }
1634  
1635      while (true) {
1636          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
1637              break;
1638          }
1639  
1640          lexer_->NextToken();  // eat '|'
1641  
1642          types.push_back(ParseTsTypeAnnotation(&options));
1643      }
1644  
1645      lexer::SourcePosition endLoc = types.back()->End();
1646  
1647      auto *unionType = AllocNode<ir::TSUnionType>(std::move(types));
1648      auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, unionType);
1649      unionType->SetVariable(typeVar);
1650      unionType->SetRange({startLoc, endLoc});
1651  
1652      return unionType;
1653  }
1654  
ParseTsIntersectionType(ir::Expression * type,bool inUnion,bool restrictExtends)1655  ir::TSIntersectionType *ParserImpl::ParseTsIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends)
1656  {
1657      ArenaVector<ir::Expression *> types(Allocator()->Adapter());
1658      lexer::SourcePosition startLoc;
1659  
1660      TypeAnnotationParsingOptions options =
1661          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION;
1662  
1663      if (restrictExtends) {
1664          options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
1665      }
1666  
1667      if (inUnion) {
1668          options |= TypeAnnotationParsingOptions::IN_UNION;
1669      }
1670  
1671      if (type) {
1672          startLoc = type->Start();
1673          types.push_back(type);
1674      } else {
1675          startLoc = lexer_->GetToken().Start();
1676      }
1677  
1678      while (true) {
1679          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) {
1680              break;
1681          }
1682  
1683          lexer_->NextToken();  // eat '&'
1684  
1685          types.push_back(ParseTsTypeAnnotation(&options));
1686      }
1687  
1688      lexer::SourcePosition endLoc = types.back()->End();
1689  
1690      auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types));
1691      auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, intersectionType);
1692      intersectionType->SetVariable(typeVar);
1693      intersectionType->SetRange({startLoc, endLoc});
1694  
1695      return intersectionType;
1696  }
1697  
IsTsFunctionType()1698  bool ParserImpl::IsTsFunctionType()
1699  {
1700      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1701      const auto startPos = lexer_->Save();
1702      lexer_->NextToken();  // eat '('
1703      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS ||
1704          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1705          lexer_->Rewind(startPos);
1706          return true;
1707      }
1708  
1709      try {
1710          ParseModifiers();
1711          if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
1712              (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS)) {
1713              lexer_->NextToken();
1714          } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1715              ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1716          } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1717              ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
1718          } else {
1719              lexer_->Rewind(startPos);
1720              return false;
1721          }
1722      } catch ([[maybe_unused]] const class Error &e) {
1723          lexer_->Rewind(startPos);
1724          return false;
1725      }
1726  
1727      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
1728          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
1729          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON ||
1730          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL) {
1731          lexer_->Rewind(startPos);
1732          return true;
1733      }
1734  
1735      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1736          lexer_->NextToken();  // eat ')'
1737          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1738              lexer_->Rewind(startPos);
1739              return true;
1740          }
1741      }
1742      lexer_->Rewind(startPos);
1743      return false;
1744  }
1745  
ParseTsParenthesizedOrFunctionType(ir::Expression * typeAnnotation,bool throwError)1746  ir::Expression *ParserImpl::ParseTsParenthesizedOrFunctionType(ir::Expression *typeAnnotation, bool throwError)
1747  {
1748      if (typeAnnotation) {
1749          return nullptr;
1750      }
1751  
1752      lexer::SourcePosition typeStart = lexer_->GetToken().Start();
1753  
1754      bool abstractConstructor = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT;
1755      if (abstractConstructor) {
1756          lexer_->NextToken();  // eat 'abstract'
1757      }
1758  
1759      bool isConstructionType = false;
1760  
1761      if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_NEW) {
1762          lexer_->NextToken();  // eat 'new'
1763          isConstructionType = true;
1764  
1765          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1766              lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1767              if (!throwError) {
1768                  return nullptr;
1769              }
1770              ThrowSyntaxError("'(' expected");
1771          }
1772      }
1773  
1774      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) {
1775          return ParseTsFunctionType(typeStart, isConstructionType, throwError, abstractConstructor);
1776      }
1777  
1778      if (IsTsFunctionType()) {
1779          return ParseTsFunctionType(typeStart, false, throwError);
1780      }
1781  
1782      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1783      lexer_->NextToken();  // eat '('
1784  
1785      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
1786      ir::Expression *type = ParseTsTypeAnnotation(&options);
1787  
1788      if (throwError && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1789          ThrowSyntaxError("')' expected");
1790      }
1791  
1792      lexer::SourcePosition endLoc = lexer_->GetToken().End();
1793      lexer_->NextToken();  // eat ')'
1794  
1795      auto *result = AllocNode<ir::TSParenthesizedType>(type);
1796      result->SetRange({typeStart, endLoc});
1797  
1798      return result;
1799  }
1800  
ParseTsFunctionType(lexer::SourcePosition startLoc,bool isConstructionType,bool throwError,bool abstractConstructor)1801  ir::Expression *ParserImpl::ParseTsFunctionType(lexer::SourcePosition startLoc, bool isConstructionType,
1802                                                  bool throwError, bool abstractConstructor)
1803  {
1804      ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1805      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1806          typeParamDecl = ParseTsTypeParameterDeclaration(throwError);
1807  
1808          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1809              if (!throwError) {
1810                  return nullptr;
1811              }
1812  
1813              ThrowSyntaxError("'(' expected");
1814          }
1815      }
1816  
1817      FunctionParameterContext funcParamContext(&context_, Binder());
1818      auto *funcParamScope = funcParamContext.LexicalScope().GetScope();
1819  
1820      ArenaVector<ir::Expression *> params(Allocator()->Adapter());
1821      try {
1822          params = ParseFunctionParams(true);
1823      } catch (const Error &e) {
1824          if (!throwError) {
1825              return nullptr;
1826          }
1827          throw e;
1828      }
1829  
1830      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1831          ThrowSyntaxError("'=>' expected");
1832      }
1833  
1834      lexer_->NextToken();  // eat '=>'
1835  
1836      TypeAnnotationParsingOptions options =
1837          TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1838      ir::Expression *returnTypeAnnotation = ParseTsTypeAnnotation(&options);
1839  
1840      ir::Expression *funcType = nullptr;
1841  
1842      if (isConstructionType) {
1843          funcType = AllocNode<ir::TSConstructorType>(funcParamScope, std::move(params), typeParamDecl,
1844                                                      returnTypeAnnotation, abstractConstructor);
1845      } else {
1846          funcType =
1847              AllocNode<ir::TSFunctionType>(funcParamScope, std::move(params), typeParamDecl, returnTypeAnnotation);
1848      }
1849  
1850      funcType->SetRange({startLoc, returnTypeAnnotation->End()});
1851      funcParamScope->BindNode(funcType);
1852  
1853      return funcType;
1854  }
1855  
ParseTsBasicType(TypeAnnotationParsingOptions options)1856  ir::Expression *ParserImpl::ParseTsBasicType(TypeAnnotationParsingOptions options)
1857  {
1858      ir::Expression *typeAnnotation = nullptr;
1859  
1860      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) {
1861          lexer_->NextToken();
1862  
1863          if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) {
1864              if (options & TypeAnnotationParsingOptions::THROW_ERROR) {
1865                  ThrowSyntaxError("Type expected");
1866              } else {
1867                  return nullptr;
1868              }
1869          }
1870      }
1871      if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER) {
1872          if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
1873              auto *bigintNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
1874              bigintNode->SetRange(lexer_->GetToken().Loc());
1875  
1876              typeAnnotation = AllocNode<ir::TSLiteralType>(bigintNode);
1877          } else {
1878              auto *numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
1879              numberNode->SetRange(lexer_->GetToken().Loc());
1880  
1881              typeAnnotation = AllocNode<ir::TSLiteralType>(numberNode);
1882          }
1883      } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) {
1884          auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
1885          stringNode->SetRange(lexer_->GetToken().Loc());
1886  
1887          typeAnnotation = AllocNode<ir::TSLiteralType>(stringNode);
1888      } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE) {
1889          auto *booleanLiteral = AllocNode<ir::BooleanLiteral>(true);
1890          booleanLiteral->SetRange(lexer_->GetToken().Loc());
1891  
1892          typeAnnotation = AllocNode<ir::TSLiteralType>(booleanLiteral);
1893      } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE) {
1894          auto *booleanLiteral = AllocNode<ir::BooleanLiteral>(false);
1895          booleanLiteral->SetRange(lexer_->GetToken().Loc());
1896  
1897          typeAnnotation = AllocNode<ir::TSLiteralType>(booleanLiteral);
1898      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ANY) {
1899          typeAnnotation = AllocNode<ir::TSAnyKeyword>();
1900      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_BOOLEAN) {
1901          typeAnnotation = AllocNode<ir::TSBooleanKeyword>();
1902      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NUMBER) {
1903          typeAnnotation = AllocNode<ir::TSNumberKeyword>();
1904      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_STRING) {
1905          typeAnnotation = AllocNode<ir::TSStringKeyword>();
1906      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNKNOWN) {
1907          typeAnnotation = AllocNode<ir::TSUnknownKeyword>();
1908      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_VOID) {
1909          typeAnnotation = AllocNode<ir::TSVoidKeyword>();
1910      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::LITERAL_NULL) {
1911          typeAnnotation = AllocNode<ir::TSNullKeyword>();
1912      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNDEFINED) {
1913          typeAnnotation = AllocNode<ir::TSUndefinedKeyword>();
1914      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NEVER) {
1915          typeAnnotation = AllocNode<ir::TSNeverKeyword>();
1916      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_OBJECT) {
1917          typeAnnotation = AllocNode<ir::TSObjectKeyword>();
1918      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_BIGINT) {
1919          typeAnnotation = AllocNode<ir::TSBigintKeyword>();
1920      } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_SYMBOL) {
1921          typeAnnotation = AllocNode<ir::TSSymbolKeyword>();
1922      } else {
1923          ThrowSyntaxError("Unexpected type");
1924      }
1925  
1926      typeAnnotation->SetRange(lexer_->GetToken().Loc());
1927  
1928      lexer_->NextToken();
1929      return typeAnnotation;
1930  }
1931  
GetAccessability(ir::ModifierFlags modifiers)1932  static ir::ModifierFlags GetAccessability(ir::ModifierFlags modifiers)
1933  {
1934      if (modifiers & ir::ModifierFlags::PUBLIC) {
1935          return ir::ModifierFlags::PUBLIC;
1936      }
1937  
1938      if (modifiers & ir::ModifierFlags::PRIVATE) {
1939          return ir::ModifierFlags::PRIVATE;
1940      }
1941  
1942      if (modifiers & ir::ModifierFlags::PROTECTED) {
1943          return ir::ModifierFlags::PROTECTED;
1944      }
1945  
1946      return ir::ModifierFlags::NONE;
1947  }
1948  
IsModifierKind(const lexer::Token & token)1949  static bool IsModifierKind(const lexer::Token &token)
1950  {
1951      if (token.Type() == lexer::TokenType::LITERAL_IDENT) {
1952          switch (token.KeywordType()) {
1953              case lexer::TokenType::KEYW_PUBLIC:
1954              case lexer::TokenType::KEYW_PRIVATE:
1955              case lexer::TokenType::KEYW_PROTECTED:
1956              case lexer::TokenType::KEYW_STATIC:
1957              case lexer::TokenType::KEYW_ASYNC:
1958              case lexer::TokenType::KEYW_ABSTRACT:
1959              case lexer::TokenType::KEYW_DECLARE:
1960              case lexer::TokenType::KEYW_READONLY:
1961                  return true;
1962              default:
1963                  return false;
1964          }
1965      }
1966  
1967      return false;
1968  }
1969  
ParseModifiers()1970  ir::ModifierFlags ParserImpl::ParseModifiers()
1971  {
1972      ir::ModifierFlags resultStatus = ir::ModifierFlags::NONE;
1973      ir::ModifierFlags prevStatus = ir::ModifierFlags::ALL;
1974  
1975      while (IsModifierKind(lexer_->GetToken())) {
1976          char32_t nextCp = lexer_->Lookahead();
1977          if (!((Extension() == ScriptExtension::JS && nextCp != LEX_CHAR_LEFT_PAREN) ||
1978                (Extension() == ScriptExtension::TS && nextCp != LEX_CHAR_EQUALS && nextCp != LEX_CHAR_SEMICOLON &&
1979                 nextCp != LEX_CHAR_COMMA && nextCp != LEX_CHAR_LEFT_PAREN))) {
1980              break;
1981          }
1982  
1983          lexer::TokenFlags tokenFlags = lexer_->GetToken().Flags();
1984          if (tokenFlags & lexer::TokenFlags::HAS_ESCAPE) {
1985              ThrowSyntaxError("Keyword must not contain escaped characters");
1986          }
1987  
1988          ir::ModifierFlags actualStatus = ir::ModifierFlags::NONE;
1989          ir::ModifierFlags nextStatus = ir::ModifierFlags::NONE;
1990  
1991          switch (lexer_->GetToken().KeywordType()) {
1992              case lexer::TokenType::KEYW_PUBLIC: {
1993                  actualStatus = ir::ModifierFlags::PUBLIC;
1994                  nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY |
1995                               ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
1996                  break;
1997              }
1998              case lexer::TokenType::KEYW_PRIVATE: {
1999                  actualStatus = ir::ModifierFlags::PRIVATE;
2000                  nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY |
2001                               ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
2002                  break;
2003              }
2004              case lexer::TokenType::KEYW_PROTECTED: {
2005                  actualStatus = ir::ModifierFlags::PROTECTED;
2006                  nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY |
2007                               ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
2008                  break;
2009              }
2010              case lexer::TokenType::KEYW_STATIC: {
2011                  actualStatus = ir::ModifierFlags::STATIC;
2012                  nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE |
2013                               ir::ModifierFlags::ABSTRACT;
2014                  break;
2015              }
2016              case lexer::TokenType::KEYW_ASYNC: {
2017                  actualStatus = ir::ModifierFlags::ASYNC;
2018                  nextStatus = ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
2019                  break;
2020              }
2021              case lexer::TokenType::KEYW_ABSTRACT: {
2022                  actualStatus = ir::ModifierFlags::ABSTRACT;
2023                  nextStatus = ir::ModifierFlags::ACCESS | ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC |
2024                               ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE;
2025                  break;
2026              }
2027              case lexer::TokenType::KEYW_DECLARE: {
2028                  actualStatus = ir::ModifierFlags::DECLARE;
2029                  nextStatus = ir::ModifierFlags::ACCESS | ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC |
2030                               ir::ModifierFlags::READONLY;
2031                  break;
2032              }
2033              case lexer::TokenType::KEYW_READONLY: {
2034                  actualStatus = ir::ModifierFlags::READONLY;
2035                  nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
2036                  break;
2037              }
2038              default: {
2039                  UNREACHABLE();
2040              }
2041          }
2042  
2043          if (lexer_->Lookahead() == LEX_CHAR_COLON || lexer_->Lookahead() == LEX_CHAR_COMMA ||
2044              lexer_->Lookahead() == LEX_CHAR_RIGHT_PAREN || lexer_->Lookahead() == LEX_CHAR_QUESTION ||
2045              lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE || lexer_->Lookahead() == LEX_CHAR_LESS_THAN) {
2046              break;
2047          }
2048  
2049          auto pos = lexer_->Save();
2050          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2051  
2052          if ((prevStatus & actualStatus) == 0) {
2053              lexer_->Rewind(pos);
2054              ThrowSyntaxError("Unexpected modifier");
2055          }
2056  
2057          if ((resultStatus & actualStatus) != 0) {
2058              lexer_->Rewind(pos);
2059              ThrowSyntaxError("Duplicated modifier is not allowed");
2060          }
2061  
2062          if ((context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) &&
2063              (actualStatus & ~ir::ModifierFlags::ALLOWED_IN_CTOR_PARAMETER)) {
2064              lexer_->Rewind(pos);
2065              ThrowParameterModifierError(actualStatus);
2066          }
2067  
2068          resultStatus |= actualStatus;
2069          prevStatus = nextStatus;
2070      }
2071  
2072      return resultStatus;
2073  }
2074  
CheckAccessorPair(const ArenaVector<ir::Statement * > & properties,const ir::Expression * propName,ir::MethodDefinitionKind methodKind,ir::ModifierFlags access,bool hasDecorator,lexer::SourcePosition errorInfo)2075  void ParserImpl::CheckAccessorPair(const ArenaVector<ir::Statement *> &properties, const ir::Expression *propName,
2076                                     ir::MethodDefinitionKind methodKind, ir::ModifierFlags access, bool hasDecorator,
2077                                     lexer::SourcePosition errorInfo)
2078  {
2079      for (const auto &it : properties) {
2080          if (!it->IsMethodDefinition() || (!hasDecorator && it->AsMethodDefinition()->Kind() != methodKind)) {
2081              continue;
2082          }
2083  
2084          const ir::Expression *key = it->AsMethodDefinition()->Key();
2085  
2086          if (key->Type() != propName->Type()) {
2087              continue;
2088          }
2089  
2090          bool keyIsSame = false;
2091  
2092          if (key->IsIdentifier()) {
2093              const util::StringView &strName = propName->AsIdentifier()->Name();
2094              const util::StringView &compareName = (key->AsIdentifier()->Name());
2095  
2096              keyIsSame = strName == compareName;
2097          } else if (key->IsNumberLiteral()) {
2098              keyIsSame = *key->AsNumberLiteral() == *propName->AsNumberLiteral();
2099          } else if (key->IsStringLiteral()) {
2100              keyIsSame = *key->AsStringLiteral() == *propName->AsStringLiteral();
2101          }
2102  
2103          if (!keyIsSame) {
2104              continue;
2105          }
2106  
2107          if (hasDecorator &&
2108              (it->AsMethodDefinition()->Kind() == ir::MethodDefinitionKind::GET ||
2109               it->AsMethodDefinition()->Kind() == ir::MethodDefinitionKind::SET) &&
2110              !it->AsMethodDefinition()->Decorators().empty()) {
2111              ThrowSyntaxError("Decorators cannot be applied to multiple get/set accessors of the same name.", errorInfo);
2112          }
2113  
2114          if (it->AsMethodDefinition()->Kind() != methodKind) {
2115              continue;
2116          }
2117  
2118          ir::ModifierFlags getAccess = ir::ModifierFlags::NONE;
2119          ir::ModifierFlags setAccess = ir::ModifierFlags::NONE;
2120  
2121          if (methodKind == ir::MethodDefinitionKind::GET) {
2122              setAccess = access;
2123              getAccess = GetAccessability(it->AsMethodDefinition()->Modifiers());
2124          } else {
2125              getAccess = access;
2126              setAccess = GetAccessability(it->AsMethodDefinition()->Modifiers());
2127          }
2128  
2129          if ((setAccess == ir::ModifierFlags::NONE && getAccess > ir::ModifierFlags::PUBLIC) ||
2130              (setAccess != ir::ModifierFlags::NONE && getAccess > setAccess)) {
2131              ThrowSyntaxError("A get accessor must be at least as accessible as the setter", key->Start());
2132          }
2133      }
2134  }
2135  
ParseClassKeyModifiers(ClassElmentDescriptor * desc)2136  void ParserImpl::ParseClassKeyModifiers(ClassElmentDescriptor *desc)
2137  {
2138      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2139          return;
2140      }
2141  
2142      char32_t nextCp = lexer_->Lookahead();
2143  
2144      if ((Extension() == ScriptExtension::JS && nextCp != LEX_CHAR_LEFT_PAREN) ||
2145          (Extension() == ScriptExtension::TS &&
2146          nextCp != LEX_CHAR_EQUALS && nextCp != LEX_CHAR_SEMICOLON && nextCp != LEX_CHAR_LEFT_PAREN &&
2147          nextCp != LEX_CHAR_LESS_THAN && nextCp != LEX_CHAR_QUESTION && nextCp != LEX_CHAR_COLON)) {
2148          if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_GET) {
2149              if (desc->isPrivateIdent) {
2150                  ThrowSyntaxError("Private identifier can not be getter");
2151              }
2152  
2153              if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) {
2154                  ThrowSyntaxError("Keyword must not contain escaped characters");
2155              }
2156  
2157              desc->methodKind = ir::MethodDefinitionKind::GET;
2158              desc->methodStart = lexer_->GetToken().Start();
2159  
2160              lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2161          } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_SET) {
2162              if (desc->isPrivateIdent) {
2163                  ThrowSyntaxError("Private identifier can not be setter");
2164              }
2165  
2166              if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) {
2167                  ThrowSyntaxError("Keyword must not contain escaped characters");
2168              }
2169  
2170              desc->methodKind = ir::MethodDefinitionKind::SET;
2171              desc->methodStart = lexer_->GetToken().Start();
2172  
2173              lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2174          }
2175      }
2176  }
2177  
ThrowIfPrivateIdent(ClassElmentDescriptor * desc,const char * msg)2178  void ParserImpl::ThrowIfPrivateIdent(ClassElmentDescriptor *desc, const char *msg)
2179  {
2180      if (desc->isPrivateIdent) {
2181          ThrowSyntaxError(msg);
2182      }
2183  }
2184  
ValidateClassKey(ClassElmentDescriptor * desc,bool isDeclare)2185  void ParserImpl::ValidateClassKey(ClassElmentDescriptor *desc, bool isDeclare)
2186  {
2187      if ((desc->modifiers & ir::ModifierFlags::ASYNC) &&
2188          (desc->methodKind == ir::MethodDefinitionKind::GET || desc->methodKind == ir::MethodDefinitionKind::SET)) {
2189          ThrowSyntaxError("Async method can not be getter nor setter");
2190      }
2191  
2192      const util::StringView &propNameStr = lexer_->GetToken().Ident();
2193  
2194      if (propNameStr.Is("constructor")) {
2195          ThrowIfPrivateIdent(desc, "Private identifier can not be constructor");
2196  
2197          if (!(desc->modifiers & ir::ModifierFlags::STATIC)) {
2198              if ((desc->modifiers & ir::ModifierFlags::ASYNC) || desc->methodKind == ir::MethodDefinitionKind::GET ||
2199                  desc->methodKind == ir::MethodDefinitionKind::SET || desc->isGenerator) {
2200                  ThrowSyntaxError("Constructor can not be special method");
2201              }
2202  
2203              desc->methodKind = ir::MethodDefinitionKind::CONSTRUCTOR;
2204              desc->methodStart = lexer_->GetToken().Start();
2205              desc->newStatus |= ParserStatus::CONSTRUCTOR_FUNCTION;
2206  
2207              if (desc->hasSuperClass) {
2208                  desc->newStatus |= ParserStatus::ALLOW_SUPER_CALL;
2209              }
2210          } else if (Extension() == ScriptExtension::TS) {
2211              ThrowSyntaxError("Static modifier can not appear on a constructor");
2212          }
2213      } else if (!isDeclare && propNameStr.Is("prototype") && (desc->modifiers & ir::ModifierFlags::STATIC)) {
2214          ThrowSyntaxError("Classes may not have static property named prototype");
2215      }
2216  }
2217  
ParseClassKey(ClassElmentDescriptor * desc,bool isDeclare)2218  ir::Expression *ParserImpl::ParseClassKey(ClassElmentDescriptor *desc, bool isDeclare)
2219  {
2220      ir::Expression *propName = nullptr;
2221      if (lexer_->GetToken().IsKeyword()) {
2222          lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
2223      }
2224  
2225      switch (lexer_->GetToken().Type()) {
2226          case lexer::TokenType::LITERAL_IDENT: {
2227              ValidateClassKey(desc, isDeclare);
2228  
2229              propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
2230              propName->SetRange(lexer_->GetToken().Loc());
2231              break;
2232          }
2233          case lexer::TokenType::LITERAL_STRING: {
2234              ThrowIfPrivateIdent(desc, "Private identifier name can not be string");
2235  
2236              propName = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
2237              propName->SetRange(lexer_->GetToken().Loc());
2238              break;
2239          }
2240          case lexer::TokenType::LITERAL_NUMBER: {
2241              ThrowIfPrivateIdent(desc, "Private identifier name can not be number");
2242  
2243              if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
2244                  propName = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
2245              } else {
2246                  propName = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
2247              }
2248  
2249              propName->SetRange(lexer_->GetToken().Loc());
2250              break;
2251          }
2252          case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
2253              ThrowIfPrivateIdent(desc, "Unexpected character in private identifier");
2254  
2255              lexer_->NextToken();  // eat left square bracket
2256  
2257              if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
2258                  lexer_->Lookahead() == LEX_CHAR_COLON) {
2259                  desc->isIndexSignature = true;
2260  
2261                  propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
2262                  propName->SetRange(lexer_->GetToken().Loc());
2263  
2264                  lexer_->NextToken();  // eat param
2265  
2266                  if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2267                      ThrowSyntaxError("':' expected");
2268                  }
2269  
2270                  lexer_->NextToken();  // eat ':'
2271                  TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
2272                  ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options);
2273  
2274                  if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) {
2275                      ThrowSyntaxError(
2276                          "An index signature parameter type must be either "
2277                          "'string' or 'number'");
2278                  }
2279  
2280                  propName->SetTsTypeAnnotation(typeAnnotation);
2281  
2282                  if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2283                      ThrowSyntaxError("']' expected");
2284                  }
2285  
2286                  lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2287  
2288                  return propName;
2289              }
2290  
2291              desc->isComputed = true;
2292  
2293              propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
2294  
2295              if (Extension() == ScriptExtension::TS) {
2296                  // TODO(songqi): Determine whether MemberExpression is a symbol during type check.
2297                  desc->invalidComputedProperty = !propName->IsNumberLiteral() &&
2298                      util::Helpers::GetSignedNumberLiteral(propName) == util::SignedNumberLiteral::UNRECOGNIZED &&
2299                      !propName->IsStringLiteral() && !propName->IsMemberExpression() && !propName->IsIdentifier();
2300              }
2301  
2302              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2303                  ThrowSyntaxError("Unexpected token, expected ']'");
2304              }
2305              break;
2306          }
2307          default: {
2308              ThrowSyntaxError("Unexpected token in class property");
2309          }
2310      }
2311  
2312      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2313  
2314      return propName;
2315  }
2316  
ValidateClassMethodStart(ClassElmentDescriptor * desc,ir::Expression * typeAnnotation)2317  void ParserImpl::ValidateClassMethodStart(ClassElmentDescriptor *desc, ir::Expression *typeAnnotation)
2318  {
2319      if (Extension() == ScriptExtension::JS) {
2320          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
2321              return;
2322          }
2323          desc->classMethod = true;
2324      }
2325  
2326      if (Extension() == ScriptExtension::TS &&
2327          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) {
2328          ThrowSyntaxError("A method cannot be named with a private identifier");
2329      }
2330  
2331      if (Extension() == ScriptExtension::TS) {
2332          if (!typeAnnotation && (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
2333                                  lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
2334              if ((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY))) {
2335                  ThrowSyntaxError("Class method can not be declare nor readonly");
2336              }
2337              desc->classMethod = true;
2338          } else {
2339              if ((desc->modifiers & ir::ModifierFlags::ASYNC) || desc->isGenerator) {
2340                  ThrowSyntaxError("Expected '('");
2341              }
2342              desc->classField = true;
2343  
2344              if (desc->invalidComputedProperty) {
2345                  ThrowSyntaxError(
2346                      "Computed property name must refer to a symbol or "
2347                      "literal expression whos value is "
2348                      "number or string");
2349              }
2350          }
2351      }
2352  
2353      if (desc->modifiers & ir::ModifierFlags::ASYNC) {
2354          desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
2355      }
2356  
2357      if (desc->isGenerator) {
2358          desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
2359      }
2360  }
2361  
ValidateClassSetter(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::ScriptFunction * func,bool hasDecorator,lexer::SourcePosition errorInfo)2362  void ParserImpl::ValidateClassSetter(ClassElmentDescriptor *desc, const ArenaVector<ir::Statement *> &properties,
2363                                       ir::Expression *propName, ir::ScriptFunction *func, bool hasDecorator,
2364                                       lexer::SourcePosition errorInfo)
2365  {
2366      if (func->Params().size() != 1) {
2367          ThrowSyntaxError("Setter must have exactly one formal parameter");
2368      }
2369  
2370      if (Extension() == ScriptExtension::TS && !(desc->modifiers & ir::ModifierFlags::STATIC)) {
2371          ir::ModifierFlags access = GetAccessability(desc->modifiers);
2372          CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access, hasDecorator, errorInfo);
2373      }
2374  }
2375  
ValidateClassGetter(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::ScriptFunction * func,bool hasDecorator,lexer::SourcePosition errorInfo)2376  void ParserImpl::ValidateClassGetter(ClassElmentDescriptor *desc, const ArenaVector<ir::Statement *> &properties,
2377                                       ir::Expression *propName, ir::ScriptFunction *func, bool hasDecorator,
2378                                       lexer::SourcePosition errorInfo)
2379  {
2380      if (!func->Params().empty()) {
2381          ThrowSyntaxError("Getter must not have formal parameters");
2382      }
2383  
2384      if (Extension() == ScriptExtension::TS && !(desc->modifiers & ir::ModifierFlags::STATIC)) {
2385          ir::ModifierFlags access = GetAccessability(desc->modifiers);
2386  
2387          CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access, hasDecorator, errorInfo);
2388      }
2389  }
2390  
ParseClassMethod(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,lexer::SourcePosition * propEnd,ArenaVector<ir::Decorator * > && decorators,bool isDeclare)2391  ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElmentDescriptor *desc,
2392                                                     const ArenaVector<ir::Statement *> &properties,
2393                                                     ir::Expression *propName, lexer::SourcePosition *propEnd,
2394                                                     ArenaVector<ir::Decorator *> &&decorators, bool isDeclare)
2395  {
2396      if (Extension() == ScriptExtension::TS) {
2397          if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) {
2398              desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION;
2399          }
2400  
2401          desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION;
2402      }
2403  
2404      if (isDeclare && (desc->newStatus & ParserStatus::ASYNC_FUNCTION)) {
2405          ThrowSyntaxError("'async' modifier cannot be used in an ambient context.");
2406      }
2407  
2408      if (isDeclare && desc->isGenerator) {
2409          ThrowSyntaxError("Generators are not allowed in an ambient context.");
2410      }
2411  
2412      ArenaVector<ir::ParamDecorators> paramDecorators(Allocator()->Adapter());
2413      ir::ScriptFunction *func = ParseFunction(desc->newStatus, isDeclare, &paramDecorators);
2414      if (func->Body() != nullptr) {
2415          lexer_->NextToken();
2416      }
2417  
2418      if (func->IsOverload() && !decorators.empty()) {
2419          ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.",
2420                           decorators.front()->Start());
2421      }
2422  
2423      auto *funcExpr = AllocNode<ir::FunctionExpression>(func);
2424      funcExpr->SetRange(func->Range());
2425  
2426      lexer::SourcePosition errorInfo = decorators.empty() ? func->Start() : decorators[0]->Start();
2427  
2428      if (desc->methodKind == ir::MethodDefinitionKind::SET) {
2429          ValidateClassSetter(desc, properties, propName, func, !decorators.empty(), errorInfo);
2430      } else if (desc->methodKind == ir::MethodDefinitionKind::GET) {
2431          ValidateClassGetter(desc, properties, propName, func, !decorators.empty(), errorInfo);
2432      }
2433  
2434      *propEnd = func->End();
2435      func->AddFlag(ir::ScriptFunctionFlags::METHOD);
2436      auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(),
2437                                                     std::move(decorators), std::move(paramDecorators),
2438                                                     desc->isComputed);
2439      method->SetRange(funcExpr->Range());
2440      return method;
2441  }
2442  
ParseClassProperty(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::Expression * typeAnnotation,ArenaVector<ir::Decorator * > && decorators,bool isDeclare)2443  ir::Statement *ParserImpl::ParseClassProperty(ClassElmentDescriptor *desc,
2444                                                const ArenaVector<ir::Statement *> &properties, ir::Expression *propName,
2445                                                ir::Expression *typeAnnotation, ArenaVector<ir::Decorator *> &&decorators,
2446                                                bool isDeclare)
2447  {
2448      lexer::SourcePosition propEnd = propName->End();
2449      ir::Statement *property = nullptr;
2450  
2451      if (desc->classMethod) {
2452          property = ParseClassMethod(desc, properties, propName, &propEnd, std::move(decorators), isDeclare);
2453          property->SetRange({desc->propStart, propEnd});
2454          return property;
2455      }
2456  
2457      ir::Expression *value = nullptr;
2458  
2459      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2460          lexer_->NextToken();  // eat equals
2461  
2462          if (isDeclare) {
2463              ThrowSyntaxError("Initializers are not allowed in ambient contexts.");
2464          }
2465          // TODO(songqi):static classProperty's value can use super keyword in TypeScript4.4.
2466          // Currently only Parser is supported, Compiler support requires Transformer.
2467          context_.Status() |= ParserStatus::ALLOW_SUPER;
2468          value = ParseExpression();
2469          context_.Status() &= ~ParserStatus::ALLOW_SUPER;
2470          propEnd = value->End();
2471      }
2472  
2473      ir::Expression *privateId = nullptr;
2474  
2475      if (Extension() == ScriptExtension::JS) {
2476          if (desc->isPrivateIdent) {
2477              ThrowSyntaxError("Private js fields are not supported");
2478          }
2479      } else {
2480          if (desc->isPrivateIdent) {
2481              privateId = AllocNode<ir::TSPrivateIdentifier>(propName, value, typeAnnotation);
2482              privateId->SetRange({desc->propStart, propName->End()});
2483          }
2484      }
2485  
2486      property = AllocNode<ir::ClassProperty>(desc->isPrivateIdent ? privateId : propName, value, typeAnnotation,
2487                                              desc->modifiers, std::move(decorators), desc->isComputed,
2488                                              desc->modifiers & ir::ModifierFlags::DEFINITE);
2489  
2490      property->SetRange({desc->propStart, propEnd});
2491      return property;
2492  }
2493  
CheckClassGeneratorMethod(ClassElmentDescriptor * desc)2494  void ParserImpl::CheckClassGeneratorMethod(ClassElmentDescriptor *desc)
2495  {
2496      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2497          return;
2498      }
2499  
2500      ThrowIfPrivateIdent(desc, "Unexpected character in private identifier");
2501  
2502      desc->isGenerator = true;
2503      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2504  }
2505  
CheckClassPrivateIdentifier(ClassElmentDescriptor * desc)2506  void ParserImpl::CheckClassPrivateIdentifier(ClassElmentDescriptor *desc)
2507  {
2508      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_HASH_MARK) {
2509          return;
2510      }
2511  
2512      if (Extension() == ScriptExtension::JS) {
2513          ThrowSyntaxError("JS private class fields are not supported.");
2514      }
2515  
2516      if (Extension() == ScriptExtension::AS) {
2517          return;
2518      }
2519  
2520      if (desc->modifiers & ~ir::ModifierFlags::READONLY) {
2521          ThrowSyntaxError("Unexpected modifier on private identifier");
2522      }
2523  
2524      desc->isPrivateIdent = true;
2525      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2526  }
2527  
ParseClassKeyAnnotation()2528  ir::Expression *ParserImpl::ParseClassKeyAnnotation()
2529  {
2530      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
2531          lexer_->NextToken();  // eat ':'
2532          TypeAnnotationParsingOptions options =
2533              TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
2534          return ParseTsTypeAnnotation(&options);
2535      }
2536  
2537      return nullptr;
2538  }
2539  
ParseDecorator()2540  ir::Decorator *ParserImpl::ParseDecorator()
2541  {
2542      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
2543  
2544      lexer::SourcePosition start = lexer_->GetToken().Start();
2545      lexer_->NextToken();  // eat '@'
2546  
2547      ir::Expression *expr = ParseLeftHandSideExpression();
2548      auto *result = AllocNode<ir::Decorator>(expr);
2549      result->SetRange({start, expr->End()});
2550  
2551      return result;
2552  }
2553  
ParseDecorators()2554  ArenaVector<ir::Decorator *> ParserImpl::ParseDecorators()
2555  {
2556      ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter());
2557      auto savedStatus = context_.Status();
2558      context_.Status() |= ParserStatus::IN_DECORATOR;
2559  
2560      while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
2561          decorators.push_back(ParseDecorator());
2562      }
2563  
2564      if (!decorators.empty() && lexer_->GetToken().Type() != lexer::TokenType::KEYW_CLASS &&
2565          (context_.Status() & ParserStatus::IN_CLASS_BODY) == 0 &&
2566          lexer_->GetToken().Type() != lexer::TokenType::KEYW_EXPORT &&
2567          !(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
2568            (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE ||
2569             lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT))) {
2570          ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start());
2571      }
2572  
2573      context_.Status() = savedStatus;
2574      return decorators;
2575  }
2576  
ParseClassElement(const ArenaVector<ir::Statement * > & properties,ArenaVector<ir::TSIndexSignature * > * indexSignatures,bool hasSuperClass,bool isDeclare,bool isAbstractClass)2577  ir::Statement *ParserImpl::ParseClassElement(const ArenaVector<ir::Statement *> &properties,
2578                                               ArenaVector<ir::TSIndexSignature *> *indexSignatures, bool hasSuperClass,
2579                                               bool isDeclare, bool isAbstractClass)
2580  {
2581      ClassElmentDescriptor desc;
2582  
2583      desc.methodKind = ir::MethodDefinitionKind::METHOD;
2584      desc.newStatus = ParserStatus::ALLOW_SUPER;
2585      desc.hasSuperClass = hasSuperClass;
2586      desc.propStart = lexer_->GetToken().Start();
2587  
2588      auto decorators = ParseDecorators();
2589  
2590      desc.modifiers = ParseModifiers();
2591  
2592      if ((desc.modifiers & ir::ModifierFlags::ABSTRACT) && !isAbstractClass) {
2593          ThrowSyntaxError("Abstract methods can only appear within an abstract class.");
2594      }
2595  
2596      CheckClassPrivateIdentifier(&desc);
2597      CheckClassGeneratorMethod(&desc);
2598      ParseClassKeyModifiers(&desc);
2599  
2600      if (!(desc.modifiers & ir::ModifierFlags::STATIC)) {
2601          context_.Status() |= ParserStatus::ALLOW_THIS_TYPE;
2602      }
2603  
2604      ir::Expression *propName = ParseClassKey(&desc, isDeclare);
2605  
2606      if (desc.methodKind == ir::MethodDefinitionKind::CONSTRUCTOR && !decorators.empty()) {
2607          ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start());
2608      }
2609  
2610      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
2611          if (desc.isIndexSignature) {
2612              ThrowSyntaxError("';' expected");
2613          }
2614  
2615          if (desc.methodKind == ir::MethodDefinitionKind::CONSTRUCTOR) {
2616              ThrowSyntaxError("'(' expected");
2617          }
2618  
2619          desc.modifiers |= ir::ModifierFlags::OPTIONAL;
2620          lexer_->NextToken();
2621      } else if (Extension() == ScriptExtension::TS &&
2622                 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) {
2623          if (desc.isIndexSignature || lexer_->Lookahead() != LEX_CHAR_COLON) {
2624              ThrowSyntaxError("';' expected");
2625          }
2626  
2627          desc.modifiers |= ir::ModifierFlags::DEFINITE;
2628          lexer_->NextToken();
2629      }
2630  
2631      ir::Expression *typeAnnotation = ParseClassKeyAnnotation();
2632  
2633      ir::Statement *property = nullptr;
2634      if (desc.isIndexSignature) {
2635          if (!decorators.empty()) {
2636              ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start());
2637          }
2638  
2639          if (!typeAnnotation) {
2640              ThrowSyntaxError("An index signature must have a type annotation");
2641          }
2642  
2643          auto *indexSignature =
2644              AllocNode<ir::TSIndexSignature>(propName, typeAnnotation, desc.modifiers & ir::ModifierFlags::READONLY);
2645  
2646          indexSignature->SetRange({indexSignature->Param()->Start(), indexSignature->TypeAnnotation()->End()});
2647  
2648          indexSignatures->push_back(indexSignature);
2649  
2650          property = AllocNode<ir::EmptyStatement>();
2651      } else {
2652          ValidateClassMethodStart(&desc, typeAnnotation);
2653          property = ParseClassProperty(&desc, properties, propName, typeAnnotation, std::move(decorators),
2654                                        isDeclare || (desc.modifiers & ir::ModifierFlags::DECLARE));
2655      }
2656  
2657      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
2658          lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
2659          !(lexer_->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) &&
2660          !(property->IsMethodDefinition() && property->AsMethodDefinition()->Value()->Function()->Body())) {
2661          ThrowSyntaxError("';' expected.");
2662      }
2663  
2664      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
2665          lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2666      }
2667  
2668      context_.Status() &= ~ParserStatus::ALLOW_THIS_TYPE;
2669  
2670      return property;
2671  }
2672  
IsConstructor(ir::Statement * stmt)2673  static bool IsConstructor(ir::Statement *stmt)
2674  {
2675      if (!stmt->IsMethodDefinition()) {
2676          return false;
2677      }
2678  
2679      ir::MethodDefinition *def = stmt->AsMethodDefinition();
2680      return def->Kind() == ir::MethodDefinitionKind::CONSTRUCTOR;
2681  }
2682  
CreateImplicitConstructor(ir::Expression * superClass,bool hasSuperClass,bool isDeclare)2683  ir::MethodDefinition *ParserImpl::CreateImplicitConstructor(ir::Expression *superClass,
2684                                                              bool hasSuperClass, bool isDeclare)
2685  {
2686      ArenaVector<ir::Expression *> params(Allocator()->Adapter());
2687      ArenaVector<ir::Statement *> statements(Allocator()->Adapter());
2688  
2689      auto *paramScope = Binder()->Allocator()->New<binder::FunctionParamScope>(Allocator(), Binder()->GetScope());
2690      auto *scope = Binder()->Allocator()->New<binder::FunctionScope>(Allocator(), paramScope);
2691  
2692      if (hasSuperClass) {
2693          if (Extension() != ScriptExtension::TS || !superClass->IsNullLiteral()) {
2694              util::StringView argsStr = "args";
2695              params.push_back(AllocNode<ir::SpreadElement>(ir::AstNodeType::REST_ELEMENT,
2696                                                            AllocNode<ir::Identifier>(argsStr)));
2697              paramScope->AddParamDecl(Allocator(), params.back());
2698  
2699              ArenaVector<ir::Expression *> callArgs(Allocator()->Adapter());
2700              auto *superExpr = AllocNode<ir::SuperExpression>();
2701              callArgs.push_back(AllocNode<ir::SpreadElement>(ir::AstNodeType::SPREAD_ELEMENT,
2702                                                              AllocNode<ir::Identifier>(argsStr)));
2703  
2704              auto *callExpr = AllocNode<ir::CallExpression>(superExpr, std::move(callArgs), nullptr, false);
2705              statements.push_back(AllocNode<ir::ExpressionStatement>(callExpr));
2706          }
2707      }
2708  
2709      auto *body = AllocNode<ir::BlockStatement>(scope, std::move(statements));
2710      auto *func = AllocNode<ir::ScriptFunction>(scope, std::move(params), nullptr, isDeclare ? nullptr : body, nullptr,
2711                                                 ir::ScriptFunctionFlags::CONSTRUCTOR, isDeclare,
2712                                                 Extension() == ScriptExtension::TS);
2713      scope->BindNode(func);
2714      paramScope->BindNode(func);
2715      scope->BindParamScope(paramScope);
2716      paramScope->BindFunctionScope(scope);
2717  
2718      auto *funcExpr = AllocNode<ir::FunctionExpression>(func);
2719      auto *key = AllocNode<ir::Identifier>("constructor");
2720  
2721      ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter());
2722      ArenaVector<ir::ParamDecorators> paramDecorators(Allocator()->Adapter());
2723      auto *ctor = AllocNode<ir::MethodDefinition>(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr,
2724                                                   ir::ModifierFlags::NONE, Allocator(), std::move(decorators),
2725                                                   std::move(paramDecorators), false);
2726  
2727      return ctor;
2728  }
2729  
IsPropertyKeysAreSame(const ir::Expression * exp1,const ir::Expression * exp2)2730  bool ParserImpl::IsPropertyKeysAreSame(const ir::Expression *exp1, const ir::Expression *exp2)
2731  {
2732      if (exp1->IsIdentifier() && exp2->IsIdentifier()) {
2733          return exp1->AsIdentifier()->Name() == exp2->AsIdentifier()->Name();
2734      }
2735  
2736      if (exp1->IsIdentifier() && exp2->IsStringLiteral()) {
2737          return exp1->AsIdentifier()->Name() == exp2->AsStringLiteral()->Str();
2738      }
2739  
2740      if (exp1->IsStringLiteral() && exp2->IsStringLiteral()) {
2741          return *exp1->AsStringLiteral() == *exp2->AsStringLiteral();
2742      }
2743  
2744      if (exp1->IsStringLiteral() && exp2->IsIdentifier()) {
2745          return exp1->AsStringLiteral()->Str() == exp2->AsIdentifier()->Name();
2746      }
2747  
2748      if (exp1->IsStringLiteral() && exp2->IsNumberLiteral()) {
2749          std::string exp2String = std::to_string(exp2->AsNumberLiteral()->Number<double>());
2750          exp2String.erase(exp2String.find_last_not_of('0'), std::string::npos);
2751          return exp1->AsStringLiteral()->Str().Utf8() == exp2String;
2752      }
2753  
2754      if (exp1->IsNumberLiteral() && exp2->IsNumberLiteral()) {
2755          return exp1->AsNumberLiteral()->Number<double>() == exp2->AsNumberLiteral()->Number<double>();
2756      }
2757  
2758      if (exp1->IsNumberLiteral() && exp2->IsStringLiteral()) {
2759          std::string exp1String = std::to_string(exp1->AsNumberLiteral()->Number<double>());
2760          exp1String.erase(exp1String.find_last_not_of('0'), std::string::npos);
2761          return exp1String == exp2->AsStringLiteral()->Str().Utf8();
2762      }
2763  
2764      return false;
2765  }
2766  
IsMemberExpressionsAreSame(const ir::MemberExpression * mExp1,const ir::MemberExpression * mExp2)2767  bool ParserImpl::IsMemberExpressionsAreSame(const ir::MemberExpression *mExp1, const ir::MemberExpression *mExp2)
2768  {
2769      if (!IsPropertyKeysAreSame(mExp1->Property(), mExp2->Property())) {
2770          return false;
2771      }
2772  
2773      if (mExp1->Object()->IsMemberExpression() && mExp2->Object()->IsMemberExpression()) {
2774          return IsMemberExpressionsAreSame(mExp1->Object()->AsMemberExpression(), mExp2->Object()->AsMemberExpression());
2775      }
2776  
2777      return IsPropertyKeysAreSame(mExp1->Object(), mExp2->Object());
2778  }
2779  
IsMethodDefinitionsAreSame(const ir::MethodDefinition * property,ir::MethodDefinition * overload)2780  bool ParserImpl::IsMethodDefinitionsAreSame(const ir::MethodDefinition *property, ir::MethodDefinition *overload)
2781  {
2782      if (property->Kind() != overload->Kind() || property->IsStatic() != overload->IsStatic()) {
2783          return false;
2784      }
2785  
2786      if (property->Key()->IsMemberExpression() && overload->Key()->IsMemberExpression()) {
2787          return IsMemberExpressionsAreSame(property->Key()->AsMemberExpression(), overload->Key()->AsMemberExpression());
2788      }
2789  
2790      return IsPropertyKeysAreSame(property->Key(), overload->Key());
2791  }
2792  
SetIdentNodeInClassDefinition(bool isDeclare,binder::ConstDecl ** decl)2793  ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition(bool isDeclare, binder::ConstDecl **decl)
2794  {
2795      lexer::TokenType keywType = lexer_->GetToken().KeywordType();
2796      CheckStrictReservedWord();
2797  
2798      if (keywType == lexer::TokenType::KEYW_AWAIT && context_.IsModule()) {
2799          ThrowSyntaxError("Unexpected reserved word");
2800      }
2801  
2802      const util::StringView &identStr = lexer_->GetToken().Ident();
2803  
2804      *decl = Binder()->AddDecl<binder::ConstDecl>(lexer_->GetToken().Start(), isDeclare, identStr);
2805  
2806      auto *identNode = AllocNode<ir::Identifier>(identStr);
2807      identNode->SetRange(lexer_->GetToken().Loc());
2808  
2809      lexer_->NextToken();
2810  
2811      return identNode;
2812  }
2813  
ParseClassDefinition(bool isDeclaration,bool idRequired,bool isDeclare,bool isAbstract)2814  ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool idRequired, bool isDeclare,
2815                                                        bool isAbstract)
2816  {
2817      isDeclare = isDeclare | (context_.Status() & ParserStatus::IN_AMBIENT_CONTEXT);
2818      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2819      lexer_->NextToken();
2820  
2821      binder::ConstDecl *decl = nullptr;
2822      ir::Identifier *identNode = nullptr;
2823  
2824      auto classCtx = binder::LexicalScope<binder::LocalScope>(Binder());
2825  
2826      if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && (Extension() != ScriptExtension::TS ||
2827          lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_IMPLEMENTS)) {
2828          identNode = SetIdentNodeInClassDefinition(isDeclare, &decl);
2829      } else if (isDeclaration && idRequired) {
2830          ThrowSyntaxError("Unexpected token, expected an identifier.");
2831      }
2832  
2833      ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
2834      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
2835          typeParamDecl = ParseTsTypeParameterDeclaration();
2836      }
2837  
2838      // Parse SuperClass
2839      ir::Expression *superClass = nullptr;
2840      bool hasSuperClass = false;
2841  
2842      if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) {
2843          lexer_->NextToken();
2844          hasSuperClass = true;
2845          superClass = ParseLeftHandSideExpression();
2846      }
2847  
2848      ir::TSTypeParameterInstantiation *superTypeParams = nullptr;
2849      if (Extension() == ScriptExtension::TS && (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
2850                                                 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT)) {
2851          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
2852              lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
2853          }
2854  
2855          superTypeParams = ParseTsTypeParameterInstantiation();
2856      }
2857  
2858      ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
2859      if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IMPLEMENTS) {
2860          lexer_->NextToken();
2861  
2862          while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
2863              lexer::SourcePosition implStart = lexer_->GetToken().Start();
2864  
2865              if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2866                  ThrowSyntaxError("Identifier expected");
2867              }
2868  
2869              ir::Expression *expr = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
2870              expr->SetRange(lexer_->GetToken().Loc());
2871              expr->AsIdentifier()->SetReference();
2872  
2873              lexer_->NextToken();
2874  
2875              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
2876                  expr = ParseTsQualifiedReference(expr);
2877              }
2878  
2879              ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
2880              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
2881                  lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
2882              }
2883  
2884              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
2885                  lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
2886                  implTypeParams = ParseTsTypeParameterInstantiation();
2887              }
2888  
2889              auto *impl = AllocNode<ir::TSClassImplements>(expr, implTypeParams);
2890              impl->SetRange({implStart, lexer_->GetToken().End()});
2891              implements.push_back(impl);
2892  
2893              if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2894                  lexer_->NextToken();
2895                  continue;
2896              }
2897  
2898              if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
2899                  ThrowSyntaxError("',' expected");
2900              }
2901          }
2902  
2903          if (implements.empty()) {
2904              ThrowSyntaxError("Implements clause can not be empty");
2905          }
2906      }
2907  
2908      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
2909          ThrowSyntaxError("Unexpected token, expected '{'");
2910      }
2911  
2912      // Parse ClassBody
2913      auto savedStatus = context_.Status();
2914      context_.Status() |= ParserStatus::IN_CLASS_BODY;
2915      context_.Status() &= ~(ParserStatus::CONSTRUCTOR_FUNCTION);
2916      lexer::SourcePosition classBodyStartLoc = lexer_->GetToken().Start();
2917      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2918  
2919      ir::MethodDefinition *ctor = nullptr;
2920      ArenaVector<ir::Statement *> properties(Allocator()->Adapter());
2921      ArenaVector<ir::TSIndexSignature *> indexSignatures(Allocator()->Adapter());
2922      bool hasConstructorFuncBody = false;
2923      bool isCtorContinuousDefined = true;
2924  
2925      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2926          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
2927              lexer_->NextToken();
2928              continue;
2929          }
2930  
2931          ir::Statement *property = ParseClassElement(properties, &indexSignatures, hasSuperClass, isDeclare, isAbstract);
2932  
2933          if (property->IsEmptyStatement()) {
2934              continue;
2935          }
2936  
2937          if (IsConstructor(property)) {
2938              if (!isDeclare && !isCtorContinuousDefined) {
2939                  ThrowSyntaxError("Constructor implementation is missing.", property->Start());
2940              }
2941  
2942              if (hasConstructorFuncBody) {
2943                  ThrowSyntaxError("Multiple constructor implementations are not allowed.", property->Start());
2944              }
2945              ctor = property->AsMethodDefinition();
2946              hasConstructorFuncBody = ctor->Value()->Function()->Body() != nullptr;
2947              continue;
2948          }
2949          isCtorContinuousDefined = ctor == nullptr;
2950          properties.push_back(property);
2951      }
2952  
2953      context_.Status() = savedStatus;
2954  
2955      lexer::SourcePosition classBodyEndLoc = lexer_->GetToken().End();
2956      if (ctor == nullptr) {
2957          ctor = CreateImplicitConstructor(superClass, hasSuperClass, isDeclare);
2958          ctor->SetRange({startLoc, classBodyEndLoc});
2959          hasConstructorFuncBody = !isDeclare;
2960      }
2961      lexer_->NextToken();
2962  
2963      ValidateClassConstructor(ctor, properties, superClass, isDeclare, hasConstructorFuncBody, hasSuperClass);
2964  
2965      auto *classDefinition = AllocNode<ir::ClassDefinition>(
2966          classCtx.GetScope(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass,
2967          std::move(properties), std::move(indexSignatures), isDeclare, isAbstract);
2968  
2969      classDefinition->SetRange({classBodyStartLoc, classBodyEndLoc});
2970      if (decl != nullptr) {
2971          decl->BindNode(classDefinition);
2972      }
2973  
2974      return classDefinition;
2975  }
2976  
ValidateClassConstructor(ir::MethodDefinition * ctor,ArenaVector<ir::Statement * > & properties,ir::Expression * superClass,bool isDeclare,bool hasConstructorFuncBody,bool hasSuperClass)2977  void ParserImpl::ValidateClassConstructor(ir::MethodDefinition *ctor,
2978                                            ArenaVector<ir::Statement *> &properties,
2979                                            ir::Expression *superClass,
2980                                            bool isDeclare, bool hasConstructorFuncBody, bool hasSuperClass)
2981  {
2982      if (!hasConstructorFuncBody) {
2983          if (isDeclare) {
2984              return;
2985          }
2986          ThrowSyntaxError("Constructor implementation is missing.", ctor->Start());
2987      }
2988  
2989      if (Extension() != ScriptExtension::TS || !hasSuperClass) {
2990          return;
2991      }
2992  
2993      bool hasSuperCall = false;
2994      FindSuperCallInConstructor(ctor, &hasSuperCall);
2995      if (hasSuperCall) {
2996          if (superClass->IsNullLiteral()) {
2997              ThrowSyntaxError("A constructor cannot contain a super call when its class extends null.", ctor->Start());
2998          }
2999  
3000          if (SuperCallShouldBeFirst(ctor, properties)) {
3001              ir::Statement *firstStat = nullptr;
3002              ASSERT(ctor->Function()->Body()->IsBlockStatement());
3003              ir::BlockStatement *blockStat = ctor->Function()->Body()->AsBlockStatement();
3004              for (auto iter = blockStat->Statements().begin(); iter != blockStat->Statements().end();) {
3005                  if ((*iter)->IsExpressionStatement() &&
3006                      (*iter)->AsExpressionStatement()->GetExpression()->IsStringLiteral()) {
3007                      iter++;
3008                  } else {
3009                      firstStat = *iter;
3010                      break;
3011                  }
3012              }
3013  
3014              if (firstStat == nullptr || !firstStat->IsExpressionStatement() ||
3015                  !firstStat->AsExpressionStatement()->GetExpression()->IsCallExpression() ||
3016                  !firstStat->AsExpressionStatement()->GetExpression()->AsCallExpression()
3017                  ->Callee()->IsSuperExpression()) {
3018                  ThrowSyntaxError("A super call must be the first statement in the constructor when a class contains "
3019                                   "initialized properties, parameter properties, or private identifiers.",
3020                                   ctor->Start());
3021              }
3022          }
3023      } else if (!superClass->IsNullLiteral()) {
3024          ThrowSyntaxError("Constructors for derived classes must contain a super call.", ctor->Start());
3025      }
3026  }
3027  
SuperCallShouldBeFirst(ir::MethodDefinition * ctor,ArenaVector<ir::Statement * > & properties)3028  bool ParserImpl::SuperCallShouldBeFirst(ir::MethodDefinition *ctor, ArenaVector<ir::Statement *> &properties)
3029  {
3030      for (const auto *property : properties) {
3031          if (property->IsClassProperty() && (property->AsClassProperty()->Value() != nullptr ||
3032              property->AsClassProperty()->Key()->IsTSPrivateIdentifier())) {
3033              return true;
3034          }
3035      }
3036  
3037      for (const auto &param : ctor->Function()->Params()) {
3038          if (param->IsTSParameterProperty() &&
3039              (param->AsTSParameterProperty()->Accessibility() != ir::AccessibilityOption::NO_OPTS ||
3040              param->AsTSParameterProperty()->Readonly())) {
3041              return true;
3042          }
3043      }
3044      return false;
3045  }
3046  
FindSuperCallInConstructor(const ir::AstNode * parent,bool * hasSuperCall)3047  void ParserImpl::FindSuperCallInConstructor(const ir::AstNode *parent, bool *hasSuperCall)
3048  {
3049      parent->Iterate([this, hasSuperCall](auto *childNode) {
3050          FindSuperCallInConstructorChildNode(childNode, hasSuperCall);
3051      });
3052  }
3053  
FindSuperCallInConstructorChildNode(const ir::AstNode * childNode,bool * hasSuperCall)3054  void ParserImpl::FindSuperCallInConstructorChildNode(const ir::AstNode *childNode, bool *hasSuperCall)
3055  {
3056      if (*hasSuperCall) {
3057          return;
3058      }
3059      switch (childNode->Type()) {
3060          case ir::AstNodeType::CALL_EXPRESSION: {
3061              if (childNode->AsCallExpression()->Callee()->IsSuperExpression()) {
3062                  *hasSuperCall = true;
3063              }
3064              break;
3065          }
3066          case ir::AstNodeType::CLASS_DEFINITION: {
3067              break;
3068          }
3069          default: {
3070              FindSuperCallInConstructor(childNode, hasSuperCall);
3071              break;
3072          }
3073      }
3074  }
3075  
ParseEnumMembers(ir::Identifier * key,const lexer::SourcePosition & enumStart,bool isExport,bool isDeclare,bool isConst)3076  ir::TSEnumDeclaration *ParserImpl::ParseEnumMembers(ir::Identifier *key, const lexer::SourcePosition &enumStart,
3077                                                      bool isExport, bool isDeclare, bool isConst)
3078  {
3079      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
3080          ThrowSyntaxError("'{' expected");
3081      }
3082  
3083      ArenaVector<ir::TSEnumMember *> members(Allocator()->Adapter());
3084      lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
3085  
3086      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
3087          ir::Expression *memberKey = nullptr;
3088          const auto &keyStartLoc = lexer_->GetToken().Start();
3089          binder::EnumDecl *decl {};
3090  
3091          if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
3092              memberKey = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
3093              decl = Binder()->AddDecl<binder::EnumDecl>(keyStartLoc, isDeclare, lexer_->GetToken().Ident());
3094              memberKey->SetRange(lexer_->GetToken().Loc());
3095              lexer_->NextToken();
3096          } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) {
3097              memberKey = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
3098              decl = Binder()->AddDecl<binder::EnumDecl>(keyStartLoc, isDeclare, lexer_->GetToken().String());
3099              memberKey->SetRange(lexer_->GetToken().Loc());
3100              lexer_->NextToken();
3101          } else {
3102              ThrowSyntaxError("Unexpected token in enum member");
3103          }
3104  
3105          ir::Expression *memberInit = nullptr;
3106          lexer::SourcePosition initStart = lexer_->GetToken().Start();
3107  
3108          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
3109              lexer_->NextToken();  // eat '='
3110              initStart = lexer_->GetToken().Start();
3111              memberInit = ParseExpression();
3112          }
3113  
3114          auto *member = AllocNode<ir::TSEnumMember>(memberKey, memberInit);
3115          decl->BindNode(member);
3116          member->SetRange({initStart, lexer_->GetToken().End()});
3117          members.push_back(member);
3118  
3119          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
3120              lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat ','
3121          }
3122      }
3123  
3124      auto *enumDeclaration = AllocNode<ir::TSEnumDeclaration>(
3125          Binder()->GetScope()->AsTSEnumScope(), key, std::move(members), isExport, isDeclare, isConst);
3126      enumDeclaration->SetRange({enumStart, lexer_->GetToken().End()});
3127      Binder()->GetScope()->BindNode(enumDeclaration);
3128      lexer_->NextToken();  // eat '}'
3129  
3130      return enumDeclaration;
3131  }
3132  
ParseEnumDeclaration(bool isExport,bool isDeclare,bool isConst)3133  ir::TSEnumDeclaration *ParserImpl::ParseEnumDeclaration(bool isExport, bool isDeclare, bool isConst)
3134  {
3135      ASSERT(lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ENUM);
3136      lexer::SourcePosition enumStart = lexer_->GetToken().Start();
3137      lexer_->NextToken();  // eat enum keyword
3138  
3139      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
3140          ThrowSyntaxError("Identifier expected");
3141      }
3142  
3143      const util::StringView &ident = lexer_->GetToken().Ident();
3144      auto *currentScope = Binder()->GetScope();
3145      binder::Variable *res = currentScope->FindLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident);
3146      if (res == nullptr && isExport && currentScope->IsTSModuleScope()) {
3147          res = currentScope->AsTSModuleScope()->FindExportTSVariable<binder::TSBindingType::ENUMLITERAL>(ident);
3148          if (res != nullptr) {
3149              currentScope->AddLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident, res);
3150          }
3151      }
3152      if (res == nullptr) {
3153          Binder()->AddTsDecl<binder::EnumLiteralDecl>(lexer_->GetToken().Start(), isDeclare,
3154                                                       Allocator(), ident, isExport, isConst);
3155          res = currentScope->FindLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident);
3156          if (isExport && currentScope->IsTSModuleScope()) {
3157              currentScope->AsTSModuleScope()->AddExportTSVariable<binder::TSBindingType::ENUMLITERAL>(ident, res);
3158          }
3159          res->AsEnumLiteralVariable()->SetEnumMembers(Allocator()->New<binder::VariableMap>(Allocator()->Adapter()));
3160      }
3161      binder::VariableMap *enumMemberBindings = res->AsEnumLiteralVariable()->GetEnumMembers();
3162  
3163      auto *key = AllocNode<ir::Identifier>(ident);
3164      key->SetRange(lexer_->GetToken().Loc());
3165      key->SetReference();
3166      lexer_->NextToken();
3167  
3168      if (!res->Declaration()->IsEnumLiteralDecl() ||
3169          (isConst ^ res->Declaration()->AsEnumLiteralDecl()->IsConst())) {
3170          Binder()->ThrowRedeclaration(lexer_->GetToken().Start(), ident);
3171      }
3172  
3173      auto enumCtx = binder::LexicalScope<binder::TSEnumScope>(Binder(), enumMemberBindings);
3174      auto *enumDeclaration = ParseEnumMembers(key, enumStart, isExport, isDeclare, isConst);
3175      res->Declaration()->AsEnumLiteralDecl()->Add(enumDeclaration);
3176  
3177      return enumDeclaration;
3178  }
3179  
ValidateFunctionParam(const ArenaVector<ir::Expression * > & params,const ir::Expression * parameter,bool * seenOptional)3180  void ParserImpl::ValidateFunctionParam(const ArenaVector<ir::Expression *> &params, const ir::Expression *parameter,
3181                                         bool *seenOptional)
3182  {
3183      if (!parameter->IsIdentifier()) {
3184          context_.Status() |= ParserStatus::HAS_COMPLEX_PARAM;
3185          if (!parameter->IsRestElement()) {
3186              return;
3187          }
3188  
3189          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
3190              const char *msg = (Extension() == ScriptExtension::JS ? "Rest parameter must be last formal parameter"
3191                                                                    : "A rest parameter must be last in parameter list");
3192              ThrowSyntaxError(msg);
3193          }
3194          return;
3195      }
3196  
3197      if (Extension() != ScriptExtension::TS) {
3198          return;
3199      }
3200  
3201      bool currentIsOptinal = parameter->AsIdentifier()->IsOptional();
3202      if (*seenOptional && !currentIsOptinal) {
3203          ThrowSyntaxError("A required parameter cannot follow an optional parameter");
3204      }
3205  
3206      *seenOptional |= currentIsOptinal;
3207      const util::StringView &paramName = parameter->AsIdentifier()->Name();
3208  
3209      if (paramName.Is("this")) {
3210          if (!params.empty()) {
3211              ThrowSyntaxError("A 'this' parameter must be the first parameter");
3212          }
3213  
3214          if (context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) {
3215              ThrowSyntaxError("A constructor cannot have a 'this' parameter");
3216          }
3217  
3218          if (context_.Status() & ParserStatus::ARROW_FUNCTION) {
3219              ThrowSyntaxError("An arrow function cannot have a 'this' parameter");
3220          }
3221  
3222          if (context_.Status() & ParserStatus::ACCESSOR_FUNCTION) {
3223              ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters");
3224          }
3225      }
3226  
3227      if (paramName.Is("constructor") && (context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION)) {
3228          ThrowSyntaxError("'constructor' cannot be used as a parameter property name");
3229      }
3230  }
3231  
ParseFunctionParams(bool isDeclare,ArenaVector<ir::ParamDecorators> * paramDecorators)3232  ArenaVector<ir::Expression *> ParserImpl::ParseFunctionParams(bool isDeclare,
3233                                                                ArenaVector<ir::ParamDecorators> *paramDecorators)
3234  {
3235      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
3236      lexer_->NextToken();
3237  
3238      ArenaVector<ir::Expression *> params(Allocator()->Adapter());
3239      bool seenOptional = false;
3240  
3241      size_t index = 0;
3242      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
3243          if (context_.Status() & ParserStatus::IN_METHOD_DEFINITION) {
3244              auto decorators = ParseDecorators();
3245              if (!decorators.empty()) {
3246                  ASSERT(paramDecorators != nullptr);
3247                  paramDecorators->push_back({index, std::move(decorators)});
3248              }
3249          }
3250  
3251          ir::Expression *parameter = ParseFunctionParameter(isDeclare);
3252          ValidateFunctionParam(params, parameter, &seenOptional);
3253  
3254          params.push_back(parameter);
3255  
3256          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
3257              lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
3258              ThrowSyntaxError(", expected");
3259          }
3260  
3261          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
3262              lexer_->NextToken();
3263          }
3264  
3265          index++;
3266      }
3267  
3268      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
3269      lexer_->NextToken();
3270  
3271      return params;
3272  }
3273  
CheckTypeNameIsReserved(const util::StringView & paramName)3274  bool ParserImpl::CheckTypeNameIsReserved(const util::StringView &paramName)
3275  {
3276      return paramName.Is("number") || paramName.Is("any") || paramName.Is("unknown") || paramName.Is("never") ||
3277             paramName.Is("bigint") || paramName.Is("boolean") || paramName.Is("string") || paramName.Is("string") ||
3278             paramName.Is("void") || paramName.Is("object");
3279  }
3280  
ParseTsTypeParameter(bool throwError,bool addBinding)3281  ir::TSTypeParameter *ParserImpl::ParseTsTypeParameter(bool throwError, bool addBinding)
3282  {
3283      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
3284  
3285      if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
3286          if (!throwError) {
3287              return nullptr;
3288          }
3289  
3290          ThrowSyntaxError("Type parameter declaration expected");
3291      }
3292  
3293      const auto &ident = lexer_->GetToken().Ident();
3294  
3295      if (CheckTypeNameIsReserved(ident)) {
3296          if (!throwError) {
3297              return nullptr;
3298          }
3299  
3300          ThrowSyntaxError("Invalid type parameter name");
3301      }
3302  
3303      auto *paramIdent = AllocNode<ir::Identifier>(ident);
3304  
3305      if (addBinding) {
3306          Binder()->AddDecl<binder::LetDecl>(lexer_->GetToken().Start(), false, ident);
3307      }
3308  
3309      paramIdent->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()});
3310  
3311      lexer_->NextToken();
3312  
3313      TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
3314  
3315      if (throwError) {
3316          options |= TypeAnnotationParsingOptions::THROW_ERROR;
3317      }
3318  
3319      ir::Expression *constraint = nullptr;
3320      if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) {
3321          lexer_->NextToken();
3322          constraint = ParseTsTypeAnnotation(&options);
3323      }
3324  
3325      ir::Expression *defaultType = nullptr;
3326      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
3327          lexer_->NextToken();
3328          defaultType = ParseTsTypeAnnotation(&options);
3329      }
3330  
3331      auto *typeParam = AllocNode<ir::TSTypeParameter>(paramIdent, constraint, defaultType);
3332  
3333      typeParam->SetRange({startLoc, lexer_->GetToken().End()});
3334  
3335      return typeParam;
3336  }
3337  
ParseTsTypeParameterDeclaration(bool throwError)3338  ir::TSTypeParameterDeclaration *ParserImpl::ParseTsTypeParameterDeclaration(bool throwError)
3339  {
3340      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
3341  
3342      auto localCtx = binder::LexicalScope<binder::LocalScope>(Binder());
3343  
3344      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
3345      ArenaVector<ir::TSTypeParameter *> params(Allocator()->Adapter());
3346      bool seenDefault = false;
3347      size_t requiredParams = 0;
3348      lexer_->NextToken();  // eat '<'
3349  
3350      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
3351          ir::TSTypeParameter *currentParam = ParseTsTypeParameter(throwError, true);
3352  
3353          if (!currentParam) {
3354              ASSERT(!throwError);
3355              return nullptr;
3356          }
3357  
3358          if (currentParam->DefaultType()) {
3359              seenDefault = true;
3360          } else if (seenDefault) {
3361              ThrowSyntaxError("Required type parameters may not follow optional type parameters.");
3362          } else {
3363              requiredParams++;
3364          }
3365  
3366          params.push_back(currentParam);
3367  
3368          if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
3369              lexer_->NextToken();
3370              continue;
3371          }
3372  
3373          if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
3374              if (!throwError) {
3375                  return nullptr;
3376              }
3377  
3378              ThrowSyntaxError("'>' expected");
3379          }
3380      }
3381  
3382      if (params.empty()) {
3383          ThrowSyntaxError("Type parameter list cannot be empty.");
3384      }
3385  
3386      lexer::SourcePosition endLoc = lexer_->GetToken().End();
3387      lexer_->NextToken();  // eat '>'
3388  
3389      auto *typeParamDecl =
3390          AllocNode<ir::TSTypeParameterDeclaration>(localCtx.GetScope(), std::move(params), requiredParams);
3391      typeParamDecl->SetRange({startLoc, endLoc});
3392      localCtx.GetScope()->BindNode(typeParamDecl);
3393  
3394      return typeParamDecl;
3395  }
3396  
ParseTsTypeParameterInstantiation(bool throwError)3397  ir::TSTypeParameterInstantiation *ParserImpl::ParseTsTypeParameterInstantiation(bool throwError)
3398  {
3399      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
3400      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
3401      ArenaVector<ir::Expression *> params(Allocator()->Adapter());
3402      lexer_->NextToken();  // eat '<'
3403  
3404      while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
3405          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
3406  
3407          if (throwError) {
3408              options |= TypeAnnotationParsingOptions::THROW_ERROR;
3409          }
3410  
3411          ir::Expression *currentParam = ParseTsTypeAnnotation(&options);
3412  
3413          if (!currentParam) {
3414              return nullptr;
3415          }
3416  
3417          params.push_back(currentParam);
3418  
3419          switch (lexer_->GetToken().Type()) {
3420              case lexer::TokenType::PUNCTUATOR_COMMA: {
3421                  lexer_->NextToken();
3422                  continue;
3423              }
3424              case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: {
3425                  lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 1);
3426                  break;
3427              }
3428              case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
3429                  lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 2);
3430                  break;
3431              }
3432              case lexer::TokenType::PUNCTUATOR_GREATER_THAN: {
3433                  break;
3434              }
3435              default: {
3436                  if (throwError) {
3437                      ThrowSyntaxError("'>' expected");
3438                  }
3439  
3440                  return nullptr;
3441              }
3442          }
3443      }
3444  
3445      lexer::SourcePosition endLoc = lexer_->GetToken().End();
3446      lexer_->NextToken();
3447  
3448      auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
3449  
3450      typeParamInst->SetRange({startLoc, endLoc});
3451  
3452      return typeParamInst;
3453  }
3454  
ParseFunction(ParserStatus newStatus,bool isDeclare,ArenaVector<ir::ParamDecorators> * paramDecorators)3455  ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus,
3456                                                bool isDeclare,
3457                                                ArenaVector<ir::ParamDecorators> *paramDecorators)
3458  {
3459      FunctionContext functionContext(this, newStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_NEW_TARGET);
3460  
3461      FunctionParameterContext funcParamContext(&context_, Binder());
3462      auto *funcParamScope = funcParamContext.LexicalScope().GetScope();
3463  
3464      lexer::SourcePosition startLoc = lexer_->GetToken().Start();
3465  
3466      ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
3467      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
3468          typeParamDecl = ParseTsTypeParameterDeclaration();
3469      }
3470  
3471      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
3472          ThrowSyntaxError("Unexpected token, expected '('");
3473      }
3474  
3475      if (newStatus & (ParserStatus::ASYNC_FUNCTION | ParserStatus::FUNCTION_DECLARATION)) {
3476          context_.Status() |= ParserStatus::DISALLOW_AWAIT;
3477      }
3478  
3479      ArenaVector<ir::Expression *> params = ParseFunctionParams(isDeclare, paramDecorators);
3480  
3481      ir::Expression *returnTypeAnnotation = nullptr;
3482  
3483      if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
3484          lexer_->NextToken();  // eat ':'
3485          TypeAnnotationParsingOptions options =
3486              TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
3487          returnTypeAnnotation = ParseTsTypeAnnotation(&options);
3488      }
3489  
3490      auto functionCtx = binder::LexicalScope<binder::FunctionScope>(Binder());
3491      auto *functionScope = functionCtx.GetScope();
3492      functionScope->BindParamScope(funcParamScope);
3493      funcParamScope->BindFunctionScope(functionScope);
3494  
3495      ir::BlockStatement *body = nullptr;
3496      lexer::SourcePosition endLoc = lexer_->GetToken().End();
3497      bool letDeclare = true;
3498  
3499      if (newStatus & ParserStatus::ASYNC_FUNCTION) {
3500          context_.Status() &= ~ParserStatus::DISALLOW_AWAIT;
3501      } else {
3502          context_.Status() |= ParserStatus::DISALLOW_AWAIT;
3503      }
3504  
3505      if (newStatus & ParserStatus::GENERATOR_FUNCTION) {
3506          context_.Status() |= ParserStatus::ALLOW_YIELD;
3507      }
3508  
3509      if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
3510          if (Extension() == ScriptExtension::TS && (newStatus & ParserStatus::FUNCTION_DECLARATION)) {
3511              ValidateTsFunctionOverloadParams(params);
3512              functionContext.AddFlag(ir::ScriptFunctionFlags::OVERLOAD);
3513          } else if (!isDeclare && !(context_.Status() & ParserStatus::IN_METHOD_DEFINITION)) {
3514              ThrowSyntaxError("Unexpected token, expected '{'");
3515          } else {
3516              letDeclare = false;
3517              functionContext.AddFlag(ir::ScriptFunctionFlags::OVERLOAD);
3518          }
3519      } else if (isDeclare) {
3520          ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
3521      } else {
3522          body = ParseBlockStatement(functionScope);
3523          endLoc = body->End();
3524      }
3525  
3526      auto *funcNode =
3527          AllocNode<ir::ScriptFunction>(functionScope, std::move(params), typeParamDecl, body, returnTypeAnnotation,
3528                                        functionContext.Flags(), isDeclare && letDeclare,
3529                                        Extension() == ScriptExtension::TS);
3530      functionScope->BindNode(funcNode);
3531      funcParamScope->BindNode(funcNode);
3532      funcNode->SetRange({startLoc, endLoc});
3533  
3534      return funcNode;
3535  }
3536  
ValidateTsFunctionOverloadParams(const ArenaVector<ir::Expression * > & params)3537  void ParserImpl::ValidateTsFunctionOverloadParams(const ArenaVector<ir::Expression *> &params)
3538  {
3539      for (auto *it : params) {
3540          if (it->IsAssignmentPattern()) {
3541              ThrowSyntaxError(
3542                  "A parameter initializer is only allowed in a function "
3543                  "or constructor implementation.",
3544                  it->Start());
3545          }
3546      }
3547  }
3548  
ParseSpreadElement(ExpressionParseFlags flags)3549  ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags)
3550  {
3551      ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD);
3552      lexer::SourcePosition startLocation = lexer_->GetToken().Start();
3553      bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
3554      lexer_->NextToken();
3555  
3556      ir::Expression *argument {};
3557      if (inPattern) {
3558          argument = ParsePatternElement(ExpressionParseFlags::IN_REST);
3559          if ((flags & ExpressionParseFlags::OBJECT_PATTERN) && !argument->IsIdentifier()) {
3560              ThrowSyntaxError("RestParameter must be followed by an identifier in declaration contexts");
3561          }
3562      } else {
3563          argument = ParseExpression(flags);
3564      }
3565  
3566      ir::Expression *typeAnnotation = nullptr;
3567  
3568      if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
3569          lexer_->NextToken();  // eat ':'
3570          TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
3571          typeAnnotation = ParseTsTypeAnnotation(&options);
3572      }
3573  
3574      if (inPattern && argument->IsAssignmentExpression()) {
3575          ThrowSyntaxError("RestParameter does not support an initializer");
3576      }
3577  
3578      lexer::SourcePosition endLoc = typeAnnotation ? typeAnnotation->End() : argument->End();
3579  
3580      auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT;
3581      auto *spreadElementNode = AllocNode<ir::SpreadElement>(nodeType, argument);
3582      spreadElementNode->SetRange({startLocation, endLoc});
3583  
3584      if (typeAnnotation) {
3585          spreadElementNode->SetTsTypeAnnotation(typeAnnotation);
3586      }
3587  
3588      return spreadElementNode;
3589  }
3590  
CreateTsParameterProperty(ir::Expression * parameter,ir::ModifierFlags modifiers)3591  ir::TSParameterProperty *ParserImpl::CreateTsParameterProperty(ir::Expression *parameter, ir::ModifierFlags modifiers)
3592  {
3593      auto accessibility = ir::AccessibilityOption::NO_OPTS;
3594      bool readonly = false;
3595      bool isStatic = false;
3596      bool isExport = false;
3597  
3598      if (modifiers & ir::ModifierFlags::PRIVATE) {
3599          accessibility = ir::AccessibilityOption::PRIVATE;
3600      } else if ((modifiers & ir::ModifierFlags::PUBLIC)) {
3601          accessibility = ir::AccessibilityOption::PUBLIC;
3602      } else if (modifiers & ir::ModifierFlags::PROTECTED) {
3603          accessibility = ir::AccessibilityOption::PROTECTED;
3604      }
3605  
3606      if (modifiers & ir::ModifierFlags::READONLY) {
3607          readonly = true;
3608      }
3609  
3610      if (modifiers & ir::ModifierFlags::STATIC) {
3611          isStatic = true;
3612      }
3613  
3614      // TODO(Csaba Repasi): Handle export property of TSParameterProperty
3615  
3616      return AllocNode<ir::TSParameterProperty>(accessibility, parameter, readonly, isStatic, isExport);
3617  }
3618  
ParseFunctionParameter(bool isDeclare)3619  ir::Expression *ParserImpl::ParseFunctionParameter(bool isDeclare)
3620  {
3621      if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_THIS) {
3622          lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
3623      }
3624  
3625      lexer::SourcePosition parameterStart = lexer_->GetToken().Start();
3626      ir::ModifierFlags modifiers = ParseModifiers();
3627      // TODO(Csaba Repasi): throw error if using strick mode reserved keyword here
3628      if (!(context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) && modifiers != ir::ModifierFlags::NONE) {
3629          ThrowSyntaxError("A parameter property is only allowed in a constructor implementation.", parameterStart);
3630      }
3631  
3632      lexer::TokenType tokenType = lexer_->GetToken().Type();
3633      if (tokenType == lexer::TokenType::LITERAL_IDENT &&
3634          (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ARGUMENTS ||
3635           lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_EVAL)) {
3636          ThrowSyntaxError(
3637              "'eval' or 'arguments' can't be defined or assigned to "
3638              "in strict mode code",
3639              lexer_->GetToken().Start());
3640      }
3641  
3642      ir::Expression *functionParameter = ParsePatternElement(ExpressionParseFlags::NO_OPTS, true, isDeclare);
3643  
3644      if (modifiers != ir::ModifierFlags::NONE && functionParameter->IsRestElement()) {
3645          ThrowSyntaxError("A parameter property cannot be declared using a rest parameter.", parameterStart);
3646      }
3647  
3648      if (modifiers != ir::ModifierFlags::NONE &&
3649          (functionParameter->IsArrayPattern() || functionParameter->IsObjectPattern() ||
3650           (functionParameter->IsAssignmentPattern() &&
3651            (functionParameter->AsAssignmentPattern()->Left()->IsArrayPattern() ||
3652             functionParameter->AsAssignmentPattern()->Left()->IsObjectPattern())))) {
3653          ThrowSyntaxError("A parameter property may not be declared using a binding pattern.", parameterStart);
3654      }
3655  
3656      if (modifiers != ir::ModifierFlags::NONE) {
3657          functionParameter = CreateTsParameterProperty(functionParameter, modifiers);
3658          functionParameter->SetRange({parameterStart, functionParameter->AsTSParameterProperty()->Parameter()->End()});
3659      }
3660  
3661      Binder()->AddParamDecl(functionParameter);
3662  
3663      return functionParameter;
3664  }
3665  
ValidateLvalueAssignmentTarget(ir::Expression * node) const3666  void ParserImpl::ValidateLvalueAssignmentTarget(ir::Expression *node) const
3667  {
3668      switch (node->Type()) {
3669          case ir::AstNodeType::IDENTIFIER: {
3670              // Check the prevoius ident name
3671              if (node->AsIdentifier()->Name().Is("arguments")) {
3672                  ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid");
3673              } else if (node->AsIdentifier()->Name().Is("eval")) {
3674                  ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid");
3675              }
3676              break;
3677          }
3678          case ir::AstNodeType::MEMBER_EXPRESSION: {
3679              break;
3680          }
3681          case ir::AstNodeType::TS_AS_EXPRESSION: {
3682              ValidateLvalueAssignmentTarget(node->AsTSAsExpression()->Expr());
3683              break;
3684          }
3685          case ir::AstNodeType::TS_TYPE_ASSERTION: {
3686              ValidateLvalueAssignmentTarget(node->AsTSTypeAssertion()->GetExpression());
3687              break;
3688          }
3689          default: {
3690              ThrowSyntaxError("Invalid left-hand side in assignment expression");
3691          }
3692      }
3693  }
3694  
ValidateAssignmentTarget(ExpressionParseFlags flags,ir::Expression * node)3695  void ParserImpl::ValidateAssignmentTarget(ExpressionParseFlags flags, ir::Expression *node)
3696  {
3697      switch (node->Type()) {
3698          case ir::AstNodeType::ARRAY_PATTERN:
3699          case ir::AstNodeType::OBJECT_PATTERN: {
3700              break;
3701          }
3702          case ir::AstNodeType::ARRAY_EXPRESSION:
3703          case ir::AstNodeType::OBJECT_EXPRESSION: {
3704              if (flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) {
3705                  return;
3706              }
3707  
3708              [[fallthrough]];
3709          }
3710          default: {
3711              return ValidateLvalueAssignmentTarget(node);
3712          }
3713      }
3714  }
3715  
ValidateArrowParameterBindings(const ir::Expression * node)3716  void ParserImpl::ValidateArrowParameterBindings(const ir::Expression *node)
3717  {
3718      switch (node->Type()) {
3719          case ir::AstNodeType::IDENTIFIER: {
3720              const util::StringView &identifier = node->AsIdentifier()->Name();
3721  
3722              if (context_.IsAsync() && identifier.Is("await")) {
3723                  ThrowSyntaxError("'await' in formal parameter is invalid.", node->Start());
3724              }
3725              break;
3726          }
3727          case ir::AstNodeType::OMITTED_EXPRESSION: {
3728              break;
3729          }
3730          case ir::AstNodeType::REST_ELEMENT: {
3731              ValidateArrowParameterBindings(node->AsRestElement()->Argument());
3732              break;
3733          }
3734          case ir::AstNodeType::PROPERTY: {
3735              break;
3736          }
3737          case ir::AstNodeType::OBJECT_PATTERN: {
3738              const auto &props = node->AsObjectPattern()->Properties();
3739  
3740              for (auto *it : props) {
3741                  ValidateArrowParameterBindings(it);
3742              }
3743              break;
3744          }
3745          case ir::AstNodeType::ARRAY_PATTERN: {
3746              const auto &elements = node->AsArrayPattern()->Elements();
3747  
3748              for (auto *it : elements) {
3749                  ValidateArrowParameterBindings(it);
3750              }
3751              break;
3752          }
3753          case ir::AstNodeType::ASSIGNMENT_PATTERN: {
3754              ValidateArrowParameterBindings(node->AsAssignmentPattern()->Left());
3755              break;
3756          }
3757          default: {
3758              ThrowSyntaxError("Unexpected ArrowParameter element");
3759          }
3760      }
3761  }
3762  
CurrentTokenIsModifier(char32_t nextCp) const3763  bool ParserImpl::CurrentTokenIsModifier(char32_t nextCp) const
3764  {
3765      return (Extension() == ScriptExtension::TS &&
3766              (nextCp != LEX_CHAR_EQUALS || nextCp != LEX_CHAR_SEMICOLON || nextCp != LEX_CHAR_LEFT_PAREN));
3767  }
3768  
ThrowParameterModifierError(ir::ModifierFlags status) const3769  void ParserImpl::ThrowParameterModifierError(ir::ModifierFlags status) const
3770  {
3771      ThrowSyntaxError(
3772          {"'", (status & ir::ModifierFlags::STATIC) ? "static" : ((status & ir::ModifierFlags::ASYNC) ? "async" : "declare") ,
3773           "' modifier cannot appear on a parameter."},
3774          lexer_->GetToken().Start());
3775  }
3776  
ThrowSyntaxError(std::string_view errorMessage) const3777  void ParserImpl::ThrowSyntaxError(std::string_view errorMessage) const
3778  {
3779      ThrowSyntaxError(errorMessage, lexer_->GetToken().Start());
3780  }
3781  
ThrowSyntaxError(std::initializer_list<std::string_view> list) const3782  void ParserImpl::ThrowSyntaxError(std::initializer_list<std::string_view> list) const
3783  {
3784      ThrowSyntaxError(list, lexer_->GetToken().Start());
3785  }
3786  
ThrowSyntaxError(std::initializer_list<std::string_view> list,const lexer::SourcePosition & pos) const3787  void ParserImpl::ThrowSyntaxError(std::initializer_list<std::string_view> list, const lexer::SourcePosition &pos) const
3788  {
3789      std::stringstream ss;
3790  
3791      for (const auto &it : list) {
3792          ss << it;
3793      }
3794  
3795      std::string err = ss.str();
3796  
3797      ThrowSyntaxError(std::string_view {err}, pos);
3798  }
3799  
ThrowSyntaxError(std::string_view errorMessage,const lexer::SourcePosition & pos) const3800  void ParserImpl::ThrowSyntaxError(std::string_view errorMessage, const lexer::SourcePosition &pos) const
3801  {
3802      lexer::LineIndex index(program_.SourceCode());
3803      lexer::SourceLocation loc = index.GetLocation(pos);
3804  
3805      throw Error {ErrorType::SYNTAX, errorMessage, loc.line, loc.col};
3806  }
3807  
Extension() const3808  ScriptExtension ParserImpl::Extension() const
3809  {
3810      return program_.Extension();
3811  }
3812  
GetSourceTextModuleRecord()3813  parser::SourceTextModuleRecord *ParserImpl::GetSourceTextModuleRecord()
3814  {
3815      return Binder()->Program()->ModuleRecord();
3816  }
3817  
GetSourceTextTypeModuleRecord()3818  parser::SourceTextModuleRecord *ParserImpl::GetSourceTextTypeModuleRecord()
3819  {
3820      return Binder()->Program()->TypeModuleRecord();
3821  }
3822  
AddPatchFixHelper(util::PatchFix * patchFixHelper)3823  void ParserImpl::AddPatchFixHelper(util::PatchFix *patchFixHelper)
3824  {
3825      program_.AddPatchFixHelper(patchFixHelper);
3826  }
3827  
IsDtsFile() const3828  bool ParserImpl::IsDtsFile() const
3829  {
3830      return program_.IsDtsFile();
3831  }
3832  
CheckStrictReservedWord() const3833  void ParserImpl::CheckStrictReservedWord() const
3834  {
3835      if (Extension() == ScriptExtension::JS) {
3836          if (lexer_->GetToken().IsJsStrictReservedWord()) {
3837              ThrowSyntaxError("Unexpected reserved word in strict mode.");
3838          }
3839      } else {
3840          if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_ARGUMENTS) {
3841              ThrowSyntaxError("Unexpected reserved word in strict mode.");
3842          }
3843      }
3844  }
3845  
3846  }  // namespace panda::es2panda::parser
3847