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