1/**
2 * Copyright (c) 2021-2024 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 "ASparser.h"
17
18#include "parser/parserStatusContext.h"
19#include "parserFlags.h"
20#include "util/helpers.h"
21#include "varbinder/privateBinding.h"
22#include "varbinder/scope.h"
23#include "varbinder/tsBinding.h"
24#include "lexer/ASLexer.h"
25#include "ir/base/decorator.h"
26#include "ir/base/property.h"
27#include "ir/base/spreadElement.h"
28#include "ir/base/classElement.h"
29#include "ir/base/classDefinition.h"
30#include "ir/base/methodDefinition.h"
31#include "ir/base/scriptFunction.h"
32#include "ir/module/importDefaultSpecifier.h"
33#include "ir/module/exportDefaultDeclaration.h"
34#include "ir/module/exportNamedDeclaration.h"
35#include "ir/module/importDeclaration.h"
36#include "ir/expressions/arrowFunctionExpression.h"
37#include "ir/expressions/templateLiteral.h"
38#include "ir/expressions/callExpression.h"
39#include "ir/expressions/taggedTemplateExpression.h"
40#include "ir/expressions/assignmentExpression.h"
41#include "ir/expressions/identifier.h"
42#include "ir/expressions/memberExpression.h"
43#include "ir/expressions/functionExpression.h"
44#include "ir/expressions/sequenceExpression.h"
45#include "ir/expressions/literals/stringLiteral.h"
46#include "ir/expressions/literals/numberLiteral.h"
47#include "ir/expressions/literals/bigIntLiteral.h"
48#include "ir/statements/emptyStatement.h"
49#include "ir/statements/blockStatement.h"
50#include "ir/statements/ifStatement.h"
51#include "ir/statements/doWhileStatement.h"
52#include "ir/statements/whileStatement.h"
53#include "ir/statements/tryStatement.h"
54#include "ir/statements/breakStatement.h"
55#include "ir/statements/continueStatement.h"
56#include "ir/statements/throwStatement.h"
57#include "ir/statements/switchStatement.h"
58#include "ir/statements/returnStatement.h"
59#include "ir/statements/debuggerStatement.h"
60#include "ir/statements/classDeclaration.h"
61#include "ir/statements/labelledStatement.h"
62#include "ir/statements/variableDeclarator.h"
63#include "ir/statements/functionDeclaration.h"
64#include "ir/as/namedType.h"
65#include "ir/as/prefixAssertionExpression.h"
66#include "ir/ts/tsFunctionType.h"
67#include "ir/ts/tsNonNullExpression.h"
68#include "ir/ts/tsAsExpression.h"
69#include "ir/ts/tsEnumDeclaration.h"
70#include "ir/ts/tsInterfaceDeclaration.h"
71#include "ir/ts/tsTypeAliasDeclaration.h"
72#include "ir/ts/tsModuleDeclaration.h"
73#include "ir/ts/tsInterfaceHeritage.h"
74#include "ir/base/tsIndexSignature.h"
75#include "ir/base/tsMethodSignature.h"
76#include "ir/base/tsPropertySignature.h"
77#include "ir/ts/tsClassImplements.h"
78#include "ir/ts/tsTypeParameterInstantiation.h"
79
80namespace ark::es2panda::parser {
81std::unique_ptr<lexer::Lexer> ASParser::InitLexer(const SourceFile &sourceFile)
82{
83    GetProgram()->SetSource(sourceFile);
84    auto lexer = std::make_unique<lexer::ASLexer>(&GetContext());
85    SetLexer(lexer.get());
86    return lexer;
87}
88
89ir::Decorator *ASParser::ParseDecorator()
90{
91    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
92
93    lexer::SourcePosition start = Lexer()->GetToken().Start();
94    Lexer()->NextToken();  // eat '@'
95
96    auto *expr = ParseLeftHandSideExpression();
97    auto *decorator = AllocNode<ir::Decorator>(expr);
98    decorator->SetRange({start, expr->End()});
99    return decorator;
100}
101
102void ASParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
103{
104    if (decorators.empty()) {
105        return;
106    }
107
108    if (!node->CanHaveDecorator(false)) {
109        ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
110    }
111
112    node->AddDecorators(std::move(decorators));
113}
114
115ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration()
116{
117    ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
118    lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
119    Lexer()->NextToken();  // eat type keyword
120
121    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
122        ThrowSyntaxError("Identifier expected");
123    }
124
125    const util::StringView &ident = Lexer()->GetToken().Ident();
126
127    auto *id = AllocNode<ir::Identifier>(ident, Allocator());
128    id->SetRange(Lexer()->GetToken().Loc());
129    Lexer()->NextToken();
130
131    ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
132    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
133        auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
134        typeParamDecl = ParseTypeParameterDeclaration(&options);
135    }
136
137    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
138        ThrowSyntaxError("'=' expected");
139    }
140
141    Lexer()->NextToken();  // eat '='
142
143    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
144        Lexer()->NextToken();  // eat '|'
145    }
146
147    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
148    ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
149
150    auto *typeAliasDecl =
151        AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext());
152    typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()});
153
154    return typeAliasDecl;
155}
156
157// NOLINTNEXTLINE(google-default-arguments)
158ir::Statement *ASParser::ParseStatement(StatementParsingFlags flags)
159{
160    return ParseDeclareAndDecorators(flags);
161}
162
163void ASParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool inRest)
164{
165    bool isOptional = false;
166
167    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
168        if (inRest) {
169            ThrowSyntaxError("A rest parameter cannot be optional");
170        }
171
172        ASSERT(returnNode->IsIdentifier());
173        returnNode->AsIdentifier()->SetOptional(true);
174
175        isOptional = true;
176        Lexer()->NextToken();  // eat '?'
177    }
178
179    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
180        Lexer()->NextToken();  // eat ':'
181        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
182        returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
183    } else if (!isOptional) {
184        ThrowSyntaxError("':' expected");
185    }
186
187    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
188        return;
189    }
190
191    if (inRest) {
192        ThrowSyntaxError("A rest parameter cannot have an initializer");
193    }
194
195    if (returnNode->IsIdentifier() && isOptional) {
196        ThrowSyntaxError("Parameter cannot have question mark and initializer");
197    }
198}
199
200ParserStatus ASParser::ValidateArrowExprIdentifier(ir::Expression *expr, bool *seenOptional)
201{
202    const util::StringView &identifier = expr->AsIdentifier()->Name();
203    bool isOptional = expr->AsIdentifier()->IsOptional();
204    if ((*seenOptional) != isOptional) {
205        ThrowSyntaxError("A required parameter cannot follow an optional parameter.", expr->Start());
206    }
207
208    (*seenOptional) |= isOptional;
209
210    if (expr->AsIdentifier()->TypeAnnotation() == nullptr) {
211        ThrowSyntaxError("':' expected", expr->End());
212    }
213
214    if (identifier.Is("arguments")) {
215        ThrowSyntaxError("Binding 'arguments' in strict mode is invalid");
216    } else if (identifier.Is("eval")) {
217        ThrowSyntaxError("Binding 'eval' in strict mode is invalid");
218    }
219
220    ValidateArrowParameterBindings(expr);
221    return ParserStatus::NO_OPTS;
222}
223
224ParserStatus ASParser::ValidateArrowAssignmentExpr(ir::Expression *expr)
225{
226    auto *assignmentExpr = expr->AsAssignmentExpression();
227    if (assignmentExpr->Right()->IsYieldExpression()) {
228        ThrowSyntaxError("yield is not allowed in arrow function parameters");
229    }
230
231    if (assignmentExpr->Right()->IsAwaitExpression()) {
232        ThrowSyntaxError("await is not allowed in arrow function parameters");
233    }
234
235    if (!assignmentExpr->ConvertibleToAssignmentPattern()) {
236        ThrowSyntaxError("Invalid destructuring assignment target");
237    }
238
239    if (assignmentExpr->Left()->IsIdentifier() && assignmentExpr->Left()->AsIdentifier()->IsOptional()) {
240        ThrowSyntaxError("Parameter cannot have question mark and initializer.", expr->Start());
241    }
242
243    ValidateArrowParameterBindings(expr);
244    return ParserStatus::HAS_COMPLEX_PARAM;
245}
246
247ParserStatus ASParser::ValidateArrowParameter(ir::Expression *expr, bool *seenOptional)
248{
249    switch (expr->Type()) {
250        case ir::AstNodeType::SPREAD_ELEMENT: {
251            if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
252                ThrowSyntaxError("Invalid rest element.");
253            }
254
255            [[fallthrough]];
256        }
257        case ir::AstNodeType::REST_ELEMENT: {
258            if (expr->AsRestElement()->IsOptional()) {
259                ThrowSyntaxError("A rest parameter cannot be optional.", expr->Start());
260            }
261
262            ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
263            return ParserStatus::HAS_COMPLEX_PARAM;
264        }
265        case ir::AstNodeType::IDENTIFIER: {
266            return ValidateArrowExprIdentifier(expr, seenOptional);
267        }
268        case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
269            return ValidateArrowAssignmentExpr(expr);
270        }
271        default: {
272            break;
273        }
274    }
275    ThrowSyntaxError("Insufficient formal parameter in arrow function.");
276    return ParserStatus::NO_OPTS;
277}
278
279ArrowFunctionDescriptor ASParser::ConvertToArrowParameter(ir::Expression *expr, bool isAsync)
280{
281    auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
282    ArenaVector<ir::Expression *> params(Allocator()->Adapter());
283
284    if (expr == nullptr) {
285        return ArrowFunctionDescriptor {std::move(params), Lexer()->GetToken().Start(), arrowStatus};
286    }
287
288    bool seenOptional = false;
289
290    switch (expr->Type()) {
291        case ir::AstNodeType::REST_ELEMENT:
292        case ir::AstNodeType::IDENTIFIER:
293        case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
294            arrowStatus |= ValidateArrowParameter(expr, &seenOptional);
295
296            params.push_back(expr);
297            break;
298        }
299        case ir::AstNodeType::SEQUENCE_EXPRESSION: {
300            auto &sequence = expr->AsSequenceExpression()->Sequence();
301
302            for (auto *it : sequence) {
303                arrowStatus |= ValidateArrowParameter(it, &seenOptional);
304            }
305
306            params.swap(sequence);
307            break;
308        }
309        case ir::AstNodeType::CALL_EXPRESSION: {
310            if (isAsync) {
311                auto &arguments = expr->AsCallExpression()->Arguments();
312
313                for (auto *it : arguments) {
314                    arrowStatus |= ValidateArrowParameter(it, &seenOptional);
315                }
316
317                params.swap(arguments);
318                break;
319            }
320
321            [[fallthrough]];
322        }
323        default: {
324            ThrowSyntaxError("Unexpected token, arrow (=>)");
325        }
326    }
327
328    return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus};
329}
330
331// NOLINTNEXTLINE(google-default-arguments)
332std::tuple<ir::AnnotatedExpression *, bool> ASParser::ParsePatternElementToken(ExpressionParseFlags flags)
333{
334    ir::AnnotatedExpression *returnNode = nullptr;
335    bool isOptional = false;
336
337    switch (Lexer()->GetToken().Type()) {
338        case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
339            if ((flags & ExpressionParseFlags::IN_REST) != 0) {
340                ThrowSyntaxError("Unexpected token");
341            }
342
343            returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
344            break;
345        }
346        case lexer::TokenType::LITERAL_IDENT: {
347            returnNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
348            returnNode->AsIdentifier()->SetReference();
349            returnNode->SetRange(Lexer()->GetToken().Loc());
350            Lexer()->NextToken();
351
352            bool questionMark = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK;
353            if (questionMark && ((flags & ExpressionParseFlags::IN_REST) != 0)) {
354                ThrowSyntaxError("A rest parameter cannot be optional");
355            }
356
357            if (questionMark) {
358                isOptional = true;
359
360                returnNode->AsIdentifier()->SetOptional(true);
361                Lexer()->NextToken();
362            }
363
364            if (!isOptional && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
365                ThrowSyntaxError("':' expected");
366            } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
367                Lexer()->NextToken();  // eat ':'
368                TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
369                returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
370            }
371
372            break;
373        }
374        default: {
375            ThrowSyntaxError("Identifier expected");
376        }
377    }
378    return {returnNode, isOptional};
379}
380
381ir::Expression *ASParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
382{
383    ir::AnnotatedExpression *returnNode = nullptr;
384    bool isOptional = false;
385    std::tie(returnNode, isOptional) = ParsePatternElementToken(flags);
386
387    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
388        return returnNode;
389    }
390
391    if ((flags & ExpressionParseFlags::IN_REST) != 0) {
392        ThrowSyntaxError("A rest parameter cannot have an initializer.");
393    }
394
395    if (!allowDefault) {
396        ThrowSyntaxError("Invalid destructuring assignment target");
397    }
398
399    if (isOptional) {
400        ThrowSyntaxError("Parameter cannot have question mark and initializer");
401    }
402
403    Lexer()->NextToken();
404
405    if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) &&
406        Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
407        ThrowSyntaxError("Yield is not allowed in generator parameters");
408    }
409
410    ir::Expression *rightNode = ParseExpression();
411
412    auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
413        ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
414    assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
415
416    return assignmentExpression;
417}
418
419// NOLINTNEXTLINE(google-default-arguments)
420ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)
421{
422    Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
423
424    ir::Expression *key = nullptr;
425
426    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
427        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
428            ThrowSyntaxError("Identifier expected");
429        }
430
431        key = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
432    } else {
433        key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
434    }
435
436    key->SetRange(Lexer()->GetToken().Loc());
437
438    Lexer()->NextToken();
439
440    ir::Expression *value = nullptr;
441
442    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
443        Lexer()->NextToken();
444        value = ParseExpression();
445    } else if (!key->IsStringLiteral()) {
446        value = key;
447    } else {
448        ThrowSyntaxError("':' expected");
449    }
450
451    auto *property = AllocNode<ir::Property>(key, value);
452    property->SetRange({key->Start(), value->End()});
453    return property;
454}
455
456bool ASParser::CurrentIsBasicType()
457{
458    switch (Lexer()->GetToken().Type()) {
459        case lexer::TokenType::LITERAL_STRING:
460        case lexer::TokenType::LITERAL_FALSE:
461        case lexer::TokenType::LITERAL_TRUE:
462        case lexer::TokenType::LITERAL_NULL:
463        case lexer::TokenType::KEYW_VOID: {
464            return true;
465        }
466        case lexer::TokenType::LITERAL_IDENT: {
467            switch (Lexer()->GetToken().KeywordType()) {
468                case lexer::TokenType::KEYW_I8:
469                case lexer::TokenType::KEYW_I16:
470                case lexer::TokenType::KEYW_I32:
471                case lexer::TokenType::KEYW_I64:
472                case lexer::TokenType::KEYW_ISIZE:
473                case lexer::TokenType::KEYW_U8:
474                case lexer::TokenType::KEYW_U16:
475                case lexer::TokenType::KEYW_U32:
476                case lexer::TokenType::KEYW_U64:
477                case lexer::TokenType::KEYW_USIZE:
478                case lexer::TokenType::KEYW_F32:
479                case lexer::TokenType::KEYW_F64:
480                case lexer::TokenType::KEYW_V128:
481                case lexer::TokenType::KEYW_FUNCREF:
482                case lexer::TokenType::KEYW_EXTERNREF:
483                case lexer::TokenType::KEYW_ANYREF:
484                case lexer::TokenType::KEYW_EQREF:
485                case lexer::TokenType::KEYW_I31REF:
486                case lexer::TokenType::KEYW_DATAREF: {
487                    return true;
488                }
489                default: {
490                    break;
491                }
492            }
493
494            break;
495        }
496        default: {
497            break;
498        }
499    }
500    return false;
501}
502
503ir::TypeNode *ASParser::ParseFunctionType(lexer::SourcePosition startLoc)
504{
505    auto params = ParseFunctionParams();
506
507    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
508        ThrowSyntaxError("'=>' expected");
509    }
510
511    Lexer()->NextToken();  // eat '=>'
512
513    TypeAnnotationParsingOptions options =
514        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
515    ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
516
517    auto signature = ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation);
518    auto funcType = AllocNode<ir::TSFunctionType>(std::move(signature));
519
520    funcType->SetRange({startLoc, returnTypeAnnotation->End()});
521
522    return funcType;
523}
524
525ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError)
526{
527    lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
528    const auto startPos = Lexer()->Save();
529    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
530    Lexer()->NextToken();  // eat '('
531
532    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
533    ir::TypeNode *type = ParseTypeAnnotation(&options);
534
535    if (type == nullptr) {
536        Lexer()->Rewind(startPos);
537
538        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
539            if (throwError) {
540                ThrowSyntaxError("Identifier expected");
541            }
542
543            return nullptr;
544        }
545
546        return ParseFunctionType(typeStart);
547    }
548
549    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
550        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
551        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
552        Lexer()->Rewind(startPos);
553        return ParseFunctionType(typeStart);
554    }
555
556    if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
557        ThrowSyntaxError("')' expected");
558    }
559
560    lexer::SourcePosition endLoc = Lexer()->GetToken().End();
561    Lexer()->NextToken();  // eat ')'
562
563    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
564        Lexer()->Rewind(startPos);
565
566        return ParseFunctionType(typeStart);
567    }
568
569    type->SetRange({typeStart, endLoc});
570    return type;
571}
572
573ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)
574{
575    auto *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
576    typeName->SetRange(Lexer()->GetToken().Loc());
577    type = AllocNode<ir::NamedType>(typeName);
578    type->SetRange(Lexer()->GetToken().Loc());
579    Lexer()->NextToken();
580
581    ir::NamedType *current = type->AsNamedType();
582    while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
583        Lexer()->NextToken();
584
585        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
586            ThrowSyntaxError("Identifier expected");
587        }
588
589        typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
590        typeName->SetRange(Lexer()->GetToken().Loc());
591        auto *next = AllocNode<ir::NamedType>(typeName);
592        current->SetRange(Lexer()->GetToken().Loc());
593        current->SetNext(next);
594        current = next;
595        Lexer()->NextToken();
596    }
597
598    ir::TSTypeParameterInstantiation *typeParams = nullptr;
599    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
600        typeParams = ParseTypeParameterInstantiation(options);
601        if (typeParams == nullptr) {
602            return nullptr;
603        }
604
605        type->AsNamedType()->SetTypeParams(typeParams);
606    }
607    return type;
608}
609
610ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError,
611                                                  TypeAnnotationParsingOptions *options)
612{
613    util::StringView name = "";
614    switch (Lexer()->GetToken().Type()) {
615        case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
616            return ParseParenthesizedOrFunctionType(throwError);
617        }
618        case lexer::TokenType::KEYW_VOID: {
619            name = "void";
620            break;
621        }
622        case lexer::TokenType::KEYW_THIS: {
623            name = "this";
624            break;
625        }
626        case lexer::TokenType::LITERAL_FALSE:
627        case lexer::TokenType::LITERAL_TRUE: {
628            name = "bool";
629            break;
630        }
631        case lexer::TokenType::LITERAL_NULL: {
632            name = "null";
633            break;
634        }
635        case lexer::TokenType::LITERAL_STRING: {
636            name = "string";
637            break;
638        }
639        case lexer::TokenType::LITERAL_IDENT: {
640            return ParseTypeAnnotationLiteralIdentHelper(type, options);
641        }
642        default: {
643            if (throwError) {
644                ThrowSyntaxError("Type expected");
645            }
646
647            return nullptr;
648        }
649    }
650
651    auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
652    typeName->SetRange(Lexer()->GetToken().Loc());
653    type = AllocNode<ir::NamedType>(typeName);
654    type->SetRange(Lexer()->GetToken().Loc());
655    Lexer()->NextToken();
656    return type;
657}
658
659ir::TypeNode *ASParser::ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)
660{
661    while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
662        Lexer()->NextToken();
663
664        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL) {
665            if (throwError) {
666                ThrowSyntaxError("'null' expected");
667            }
668
669            return nullptr;
670        }
671
672        if (!isNullable) {
673            isNullable = true;
674            if (type->IsTSFunctionType()) {
675                type->AsTSFunctionType()->SetNullable(isNullable);
676            } else {
677                ASSERT(type->IsNamedType());
678                type->AsNamedType()->SetNullable(isNullable);
679            }
680        }
681
682        type->SetEnd(Lexer()->GetToken().End());
683        Lexer()->NextToken();
684    }
685    return type;
686}
687
688ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)
689{
690    while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
691        Lexer()->NextToken();
692
693        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
694            if (throwError) {
695                ThrowSyntaxError("']' expected");
696            }
697
698            return nullptr;
699        }
700
701        Lexer()->NextToken();
702
703        isNullable = false;
704
705        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
706            Lexer()->NextToken();
707
708            bool isLiteralNull = Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL;
709            if (isLiteralNull && throwError) {
710                ThrowSyntaxError("'null' expected");
711            }
712            if (isLiteralNull) {
713                return nullptr;
714            }
715
716            isNullable = true;
717        }
718
719        const lexer::SourcePosition &startPos = type->Start();
720
721        util::StringView name = "Array";
722        auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
723        typeName->SetRange(Lexer()->GetToken().Loc());
724
725        ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
726        params.push_back(type);
727        auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
728
729        type = AllocNode<ir::NamedType>(typeName);
730        type->AsNamedType()->SetTypeParams(typeParamInst);
731        type->AsNamedType()->SetNullable(isNullable);
732        type->SetRange({startPos, Lexer()->GetToken().End()});
733
734        if (isNullable) {
735            Lexer()->NextToken();
736            break;
737        }
738    }
739    return type;
740}
741
742ir::TypeNode *ASParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
743{
744    bool reportError = (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
745    ir::TypeNode *type = ParseTypeAnnotationTokens(nullptr, reportError, options);
746    if (type == nullptr) {
747        return nullptr;
748    }
749
750    bool isNullable = false;
751    type = ParseTypeAnnotationTokensBitwiseOr(type, reportError, isNullable);
752    if (type == nullptr) {
753        return nullptr;
754    }
755
756    type = ParseTypeAnnotationTokenLeftSquareBracket(type, reportError, isNullable);
757    return type;
758}
759
760ir::ArrowFunctionExpression *ASParser::ParsePotentialArrowExpression(
761    [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)
762{
763    return nullptr;
764}
765
766bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
767{
768    if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
769        return true;
770    }
771
772    *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
773    (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
774    Lexer()->NextToken();
775    return false;
776}
777
778bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
779                                                 const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
780{
781    if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
782        (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
783        return true;
784    }
785
786    const auto savedPos = Lexer()->Save();
787
788    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
789        Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
790    }
791
792    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
793    ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
794
795    if (typeParams == nullptr) {
796        Lexer()->Rewind(savedPos);
797        return true;
798    }
799
800    if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
801        ThrowSyntaxError("'(' or '`' expected");
802    }
803
804    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
805        if (!ignoreCallExpression) {
806            *returnExpression = ParseCallExpression(*returnExpression, false);
807            (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
808            return false;
809        }
810
811        return true;
812    }
813
814    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
815        ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
816        lexer::SourcePosition endLoc = propertyNode->End();
817
818        *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
819        (*returnExpression)->SetRange({startLoc, endLoc});
820        return false;
821    }
822
823    Lexer()->Rewind(savedPos);
824    return true;
825}
826
827bool ASParser::IsNamedFunctionExpression()
828{
829    return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
830           Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
831}
832
833ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpression)
834{
835    if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
836        return nullptr;
837    }
838
839    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
840    Lexer()->NextToken();
841    ir::TypeNode *type = ParseTypeAnnotation(&options);
842    auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpression, type, false);
843    return asExpression;
844}
845
846ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
847{
848    auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
849    identNode->SetReference();
850    identNode->SetRange(Lexer()->GetToken().Loc());
851
852    Lexer()->NextToken();
853
854    ParsePotentialOptionalFunctionParameter(identNode);
855
856    return identNode;
857}
858
859void ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
860{
861    ParseOptionalFunctionParameter(restElement, true);
862
863    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
864        ThrowSyntaxError("')' expected");
865    }
866}
867
868ArenaVector<ir::TSInterfaceHeritage *> ASParser::ParseInterfaceExtendsClause()
869{
870    Lexer()->NextToken();  // eat extends keyword
871
872    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
873        ThrowSyntaxError("Identifier expected");
874    }
875
876    const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
877    lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
878    auto *extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
879    extendsName->SetRange(Lexer()->GetToken().Loc());
880    auto *extendsClause = AllocNode<ir::NamedType>(extendsName);
881    extendsClause->SetRange(Lexer()->GetToken().Loc());
882    Lexer()->NextToken();
883
884    ir::NamedType *current = extendsClause->AsNamedType();
885    while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
886        Lexer()->NextToken();
887
888        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
889            ThrowSyntaxError("Identifier expected");
890        }
891
892        extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
893        extendsName->SetRange(Lexer()->GetToken().Loc());
894        auto *next = AllocNode<ir::NamedType>(extendsName);
895        current->SetRange(Lexer()->GetToken().Loc());
896        current->SetNext(next);
897        current = next;
898        heritageEnd = Lexer()->GetToken().End();
899        Lexer()->NextToken();
900    }
901
902    if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
903        Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
904    } else {
905        Lexer()->NextToken();
906    }
907
908    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
909        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
910        extendsClause->AsNamedType()->SetTypeParams(ParseTypeParameterInstantiation(&options));
911        heritageEnd = Lexer()->GetToken().End();
912    }
913
914    extendsClause->SetRange({heritageStart, heritageEnd});
915
916    if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
917        ThrowSyntaxError("Interface declaration cannot have 'implements' clause");
918    }
919
920    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
921        ThrowSyntaxError("'{' expected");
922    }
923
924    ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
925    auto *heritage = AllocNode<ir::TSInterfaceHeritage>(extendsClause);
926    heritage->SetRange(extendsClause->Range());
927    extends.push_back(heritage);
928    return extends;
929}
930
931// NOLINTNEXTLINE(google-default-arguments)
932ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
933{
934    Lexer()->NextToken();  // eat '['
935
936    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
937        ThrowSyntaxError("Identifier expected.");
938    }
939
940    if (!Lexer()->GetToken().Ident().Is("key")) {
941        ThrowSyntaxError("'key' expected.");
942    }
943
944    auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
945    key->SetRange(Lexer()->GetToken().Loc());
946
947    Lexer()->NextToken();  // eat key
948
949    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
950        ThrowSyntaxError("':' expected.");
951    }
952
953    Lexer()->NextToken();  // eat ':'
954
955    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
956    ir::TypeNode *keyType = ParseTypeAnnotation(&options);
957    key->SetTsTypeAnnotation(keyType);
958
959    if (!keyType->IsNamedType()) {
960        ThrowSyntaxError("Type expected.");
961    }
962
963    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
964        ThrowSyntaxError("']' expected.");
965    }
966
967    Lexer()->NextToken();  // eat ']'
968
969    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
970        ThrowSyntaxError("':' expected.");
971    }
972
973    Lexer()->NextToken();  // eat ':'
974
975    ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
976
977    if (!typeAnnotation->IsNamedType()) {
978        ThrowSyntaxError("Identifier expected.");
979    }
980
981    auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
982    indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
983    return indexSignature;
984}
985
986std::tuple<ir::Expression *, bool> ASParser::ParseInterfacePropertyKey()
987{
988    ir::Expression *key = nullptr;
989
990    switch (Lexer()->GetToken().Type()) {
991        case lexer::TokenType::LITERAL_IDENT: {
992            const util::StringView &ident = Lexer()->GetToken().Ident();
993            key = AllocNode<ir::Identifier>(ident, Allocator());
994            key->SetRange(Lexer()->GetToken().Loc());
995            break;
996        }
997        case lexer::TokenType::LITERAL_STRING: {
998            const util::StringView &string = Lexer()->GetToken().String();
999            key = AllocNode<ir::StringLiteral>(string);
1000            key->SetRange(Lexer()->GetToken().Loc());
1001            break;
1002        }
1003        case lexer::TokenType::LITERAL_NUMBER: {
1004            if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1005                key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1006            } else {
1007                key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1008            }
1009
1010            key->SetRange(Lexer()->GetToken().Loc());
1011            break;
1012        }
1013        default: {
1014            ThrowSyntaxError("Unexpected token in property key");
1015        }
1016    }
1017
1018    Lexer()->NextToken();
1019    return {key, false};
1020}
1021
1022ir::AstNode *ASParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1023{
1024    auto [key, isComputed] = ParseInterfacePropertyKey();
1025
1026    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1027        ThrowSyntaxError("Optional properties are not supported.");
1028    }
1029
1030    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1031        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1032        ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1033
1034        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1035            auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1036            typeParamDecl = ParseTypeParameterDeclaration(&options);
1037        }
1038
1039        FunctionParameterContext funcParamContext(&GetContext());
1040        auto params = ParseFunctionParams();
1041
1042        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1043            ThrowSyntaxError("Type expected.");
1044        }
1045
1046        Lexer()->NextToken();  // eat ':'
1047        TypeAnnotationParsingOptions options =
1048            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1049        ir::TypeNode *returnType = ParseTypeAnnotation(&options);
1050
1051        auto signature = ir::FunctionSignature(typeParamDecl, std::move(params), returnType);
1052        auto *methodSignature = AllocNode<ir::TSMethodSignature>(key, std::move(signature), isComputed, false);
1053        methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1054        return methodSignature;
1055    }
1056
1057    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1058        ThrowSyntaxError("Type expected.");
1059    }
1060
1061    Lexer()->NextToken();  // eat ':'
1062    TypeAnnotationParsingOptions options =
1063        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1064    ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1065
1066    auto *propertySignature = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, false, isReadonly);
1067    propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1068    return propertySignature;
1069}
1070
1071ir::AstNode *ASParser::ParseTypeLiteralOrInterfaceMember()
1072{
1073    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1074        ThrowSyntaxError("Decorators are not allowed here");
1075    }
1076
1077    char32_t nextCp = Lexer()->Lookahead();
1078    lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1079    bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1080                      nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON;
1081    if (isReadonly) {
1082        Lexer()->NextToken();  // eat 'readonly"
1083    }
1084
1085    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1086        return ParseIndexSignature(startLoc, isReadonly);
1087    }
1088
1089    return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1090}
1091
1092ArenaVector<ir::TSClassImplements *> ASParser::ParseClassImplementClause()
1093{
1094    ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
1095
1096    while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1097        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1098            ThrowSyntaxError("Identifier expected");
1099        }
1100
1101        const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start();
1102        auto *implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1103        implementsName->SetRange(Lexer()->GetToken().Loc());
1104        auto *implementsClause = AllocNode<ir::NamedType>(implementsName);
1105        implementsClause->SetRange(Lexer()->GetToken().Loc());
1106        Lexer()->NextToken();
1107
1108        ir::NamedType *current = implementsClause->AsNamedType();
1109        while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1110            Lexer()->NextToken();
1111
1112            if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1113                ThrowSyntaxError("Identifier expected");
1114            }
1115
1116            implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1117            implementsName->SetRange(Lexer()->GetToken().Loc());
1118            auto *next = AllocNode<ir::NamedType>(implementsName);
1119            current->SetRange(Lexer()->GetToken().Loc());
1120            current->SetNext(next);
1121            current = next;
1122            Lexer()->NextToken();
1123        }
1124
1125        ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
1126        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1127            Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1128        }
1129
1130        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
1131            Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1132            TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1133            implTypeParams = ParseTypeParameterInstantiation(&options);
1134        }
1135
1136        auto *impl = AllocNode<ir::TSClassImplements>(current, implTypeParams);
1137        impl->SetRange({implementStart, Lexer()->GetToken().End()});
1138        implements.push_back(impl);
1139
1140        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1141            Lexer()->NextToken();
1142            continue;
1143        }
1144        ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
1145    }
1146
1147    if (implements.empty()) {
1148        ThrowSyntaxError("Implements clause can not be empty");
1149    }
1150
1151    return implements;
1152}
1153
1154ir::TypeNode *ASParser::ParseClassKeyAnnotation()
1155{
1156    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1157        Lexer()->NextToken();  // eat ':'
1158        TypeAnnotationParsingOptions options =
1159            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1160        return ParseTypeAnnotation(&options);
1161    }
1162
1163    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1164        Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1165        ThrowSyntaxError("Type expected");
1166    }
1167
1168    return nullptr;
1169}
1170
1171void ASParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1172{
1173    if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1174                                      Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1175        if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) {
1176            ThrowSyntaxError("'declare' modifier cannot appear on class elements of this kind");
1177        }
1178
1179        desc->classMethod = true;
1180    } else {
1181        if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1182            ThrowSyntaxError("Expected '('");
1183        }
1184        desc->classField = true;
1185
1186        if (desc->invalidComputedProperty) {
1187            ThrowSyntaxError(
1188                "Computed property name must refer to a symbol or "
1189                "literal expression whose value is "
1190                "number or string");
1191        }
1192    }
1193
1194    if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1195        desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1196    }
1197
1198    if (desc->isGenerator) {
1199        desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1200    }
1201}
1202
1203void ASParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1204                                   ir::Expression *propName, ir::ScriptFunction *func)
1205{
1206    if (func->Params().size() != 1) {
1207        ThrowSyntaxError("Setter must have exactly one formal parameter");
1208    }
1209
1210    if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1211        ir::ModifierFlags access = GetAccessability(desc->modifiers);
1212        CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1213    }
1214}
1215
1216void ASParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1217                                   ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)
1218{
1219    if ((desc->modifiers & ir::ModifierFlags::STATIC) != 0) {
1220        ir::ModifierFlags access = GetAccessability(desc->modifiers);
1221
1222        CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1223    }
1224}
1225
1226ir::ClassElement *ASParser::ParseClassStaticBlock()
1227{
1228    ThrowSyntaxError("Unexpected token");
1229    return nullptr;
1230}
1231
1232void ASParser::ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)
1233{
1234    ThrowSyntaxError("Optional properties are not supported");
1235}
1236
1237void ASParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1238{
1239    if (typeAnnotation == nullptr) {
1240        ThrowSyntaxError("':' expected");
1241    }
1242
1243    if (!typeAnnotation->IsNamedType()) {
1244        ThrowSyntaxError("Identifier expected");
1245    }
1246}
1247
1248bool ASParser::IsModifierKind(const lexer::Token &token)
1249{
1250    switch (token.KeywordType()) {
1251        case lexer::TokenType::KEYW_PUBLIC:
1252        case lexer::TokenType::KEYW_PRIVATE:
1253        case lexer::TokenType::KEYW_PROTECTED:
1254        case lexer::TokenType::KEYW_STATIC:
1255        case lexer::TokenType::KEYW_ASYNC:
1256        case lexer::TokenType::KEYW_DECLARE:
1257        case lexer::TokenType::KEYW_READONLY:
1258            return true;
1259        default:
1260            break;
1261    }
1262
1263    return false;
1264}
1265
1266void ASParser::ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc,
1267                                             [[maybe_unused]] char32_t *nextCp)
1268{
1269    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1270        ThrowSyntaxError("Invalid character");
1271    }
1272}
1273
1274std::tuple<bool, bool, bool> ASParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1275{
1276    Lexer()->NextToken();  // eat left square bracket
1277
1278    if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1279        Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1280        if (!Lexer()->GetToken().Ident().Is("key")) {
1281            ThrowSyntaxError("'key' expected.");
1282        }
1283
1284        auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1285        id->SetRange(Lexer()->GetToken().Loc());
1286
1287        Lexer()->NextToken();  // eat param
1288
1289        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1290            ThrowSyntaxError("':' expected");
1291        }
1292
1293        Lexer()->NextToken();  // eat ':'
1294        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1295        ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1296
1297        if (!typeAnnotation->IsNamedType()) {
1298            ThrowSyntaxError("Type expected");
1299        }
1300
1301        id->SetTsTypeAnnotation(typeAnnotation);
1302        *propName = id;
1303
1304        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1305            ThrowSyntaxError("']' expected");
1306        }
1307
1308        Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1309
1310        return {false, false, true};
1311    }
1312
1313    *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1314
1315    bool invalidComputedProperty =
1316        !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
1317        !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
1318          (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
1319
1320    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1321        ThrowSyntaxError("Unexpected token, expected ']'");
1322    }
1323
1324    return {true, invalidComputedProperty, false};
1325}
1326
1327std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> ASParser::ParseFunctionBody(
1328    [[maybe_unused]] const ArenaVector<ir::Expression *> &params, [[maybe_unused]] ParserStatus newStatus,
1329    ParserStatus contextStatus)
1330{
1331    bool isDeclare = InAmbientContext();
1332    bool isOverload = false;
1333    bool letDeclare = true;
1334    ir::BlockStatement *body = nullptr;
1335    lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1336
1337    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1338        if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
1339            ThrowSyntaxError("Unexpected token, expected '{'");
1340        } else {
1341            letDeclare = false;
1342        }
1343
1344        isOverload = true;
1345    } else if (isDeclare) {
1346        ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
1347    } else {
1348        body = ParseBlockStatement();
1349        endLoc = body->End();
1350    }
1351
1352    return {letDeclare, body, endLoc, isOverload};
1353}
1354
1355ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1356{
1357    ir::Identifier *local = ParseNamedImport(Lexer()->GetToken());
1358    Lexer()->NextToken();  // eat local name
1359
1360    auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1361    specifier->SetRange(specifier->Local()->Range());
1362    specifiers->push_back(specifier);
1363
1364    return nullptr;
1365}
1366
1367ir::Expression *ASParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
1368{
1369    ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1370
1371    restElement->SetGrouped();
1372    restElement->SetStart(start);
1373
1374    ValidateArrowFunctionRestParameter(restElement);
1375
1376    Lexer()->NextToken();
1377
1378    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1379        ThrowSyntaxError(":' expected");
1380    }
1381
1382    Lexer()->NextToken();  // eat ':'
1383
1384    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1385    ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1386
1387    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1388        ThrowSyntaxError("'=>' expected");
1389    }
1390
1391    return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
1392}
1393
1394ir::Expression *ASParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
1395{
1396    Lexer()->NextToken();
1397
1398    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1399        ThrowSyntaxError(":' expected");
1400    }
1401
1402    Lexer()->NextToken();  // eat ':'
1403
1404    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1405    ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1406
1407    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1408        ThrowSyntaxError("'=>' expected");
1409    }
1410
1411    auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
1412    arrowExpr->SetStart(start);
1413    arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
1414
1415    return arrowExpr;
1416}
1417
1418// NOLINTNEXTLINE(google-default-arguments)
1419ir::Expression *ASParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
1420    [[maybe_unused]] ExpressionParseFlags flags)
1421{
1422    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1423    lexer::SourcePosition start = Lexer()->GetToken().Start();
1424    Lexer()->NextToken();
1425    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1426
1427    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1428        return ParseArrowFunctionRestParameter(start);
1429    }
1430
1431    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1432        return ParseArrowFunctionNoParameter(start);
1433    }
1434
1435    ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
1436                                           ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
1437
1438    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1439        ThrowSyntaxError("')' expected");
1440    }
1441
1442    expr->SetGrouped();
1443    expr->SetRange({start, Lexer()->GetToken().End()});
1444    Lexer()->NextToken();
1445
1446    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1447        ThrowSyntaxError("':' expected.");
1448    }
1449
1450    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1451        auto savedPos = Lexer()->Save();
1452        Lexer()->NextToken();  // eat ':'
1453        options = TypeAnnotationParsingOptions::NO_OPTS;
1454        ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1455
1456        if (returnTypeAnnotation == nullptr) {
1457            Lexer()->Rewind(savedPos);
1458            return expr;
1459        }
1460
1461        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1462            Lexer()->Rewind(savedPos);
1463            return expr;
1464        }
1465
1466        return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
1467    }
1468
1469    return expr;
1470}
1471
1472ir::Expression *ASParser::ParsePrefixAssertionExpression()
1473{
1474    lexer::SourcePosition startPos = Lexer()->GetToken().Start();
1475    Lexer()->NextToken();  // eat <
1476    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1477    ir::TypeNode *type = ParseTypeAnnotation(&options);
1478
1479    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1480        ThrowSyntaxError("'>' expected");
1481    }
1482
1483    Lexer()->NextToken();  // eat >
1484
1485    ir::Expression *expr = ParseExpression();
1486
1487    auto *node = AllocNode<ir::PrefixAssertionExpression>(expr, type);
1488    node->SetRange({startPos, Lexer()->GetToken().End()});
1489    return node;
1490}
1491
1492ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags)
1493{
1494    lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
1495    Lexer()->NextToken();
1496
1497    if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1498        return ParseEnumDeclaration(true);
1499    }
1500
1501    if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
1502        ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
1503    }
1504
1505    auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
1506    variableDecl->SetStart(constVarStar);
1507    ConsumeSemicolon(variableDecl);
1508
1509    return variableDecl;
1510}
1511
1512ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
1513{
1514    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1515        ThrowSyntaxError("Identifier expected");
1516    }
1517
1518    ValidateDeclaratorId();
1519
1520    const util::StringView &identStr = Lexer()->GetToken().Ident();
1521    auto init = AllocNode<ir::Identifier>(identStr, Allocator());
1522    init->SetRange(Lexer()->GetToken().Loc());
1523    Lexer()->NextToken();
1524
1525    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1526        Lexer()->NextToken();  // eat ':'
1527        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1528        init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1529    } else if (((flags & VariableParsingFlags::IN_FOR) == 0) &&
1530               Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1531        ThrowSyntaxError("Type expected");
1532    }
1533
1534    return init;
1535}
1536
1537ir::Statement *ASParser::ParsePotentialConstEnum(VariableParsingFlags flags)
1538{
1539    if ((flags & VariableParsingFlags::CONST) == 0) {
1540        ThrowSyntaxError("Variable declaration expected.");
1541    }
1542
1543    return ParseEnumDeclaration(true);
1544}
1545
1546// NOLINTNEXTLINE(google-default-arguments)
1547ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1548                                                                      bool isExportEquals)
1549{
1550    Lexer()->NextToken();  // eat `default` keyword or `=`
1551
1552    ir::AstNode *declNode = nullptr;
1553    bool eatSemicolon = false;
1554
1555    switch (Lexer()->GetToken().Type()) {
1556        case lexer::TokenType::KEYW_FUNCTION: {
1557            declNode = ParseFunctionDeclaration(true);
1558            break;
1559        }
1560        case lexer::TokenType::KEYW_CLASS: {
1561            declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1562            break;
1563        }
1564        case lexer::TokenType::KEYW_INTERFACE: {
1565            declNode = ParseInterfaceDeclaration(false);
1566            break;
1567        }
1568        case lexer::TokenType::KEYW_NAMESPACE: {
1569            Lexer()->NextToken();  // eat 'namespace'
1570            declNode = ParseModuleOrNamespaceDeclaration(startLoc);
1571            break;
1572        }
1573        case lexer::TokenType::KEYW_ENUM: {
1574            declNode = ParseEnumDeclaration();
1575            break;
1576        }
1577        case lexer::TokenType::KEYW_ASYNC: {
1578            if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1579                Lexer()->NextToken();  // eat `async`
1580                declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1581                break;
1582            }
1583
1584            [[fallthrough]];
1585        }
1586        default: {
1587            declNode = ParseExpression();
1588            eatSemicolon = true;
1589            break;
1590        }
1591    }
1592
1593    lexer::SourcePosition endLoc = declNode->End();
1594    auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1595    exportDeclaration->SetRange({startLoc, endLoc});
1596
1597    if (eatSemicolon) {
1598        ConsumeSemicolon(exportDeclaration);
1599    }
1600
1601    return exportDeclaration;
1602}
1603
1604class ASParser::ParseNamedExportDeclarationHelper {
1605    friend ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc);
1606
1607private:
1608    static ir::Statement *GetParsedDeclaration(ASParser *parser, lexer::TokenType type)
1609    {
1610        ir::ModifierFlags flags = ir::ModifierFlags::NONE;
1611        if (parser->Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1612            parser->Lexer()->NextToken();  // eat 'abstract'
1613            flags = ir::ModifierFlags::ABSTRACT;
1614        }
1615
1616        switch (type) {
1617            case lexer::TokenType::KEYW_VAR: {
1618                return parser->ParseVariableDeclaration(VariableParsingFlags::VAR);
1619            }
1620            case lexer::TokenType::KEYW_CONST: {
1621                return parser->ParseVariableDeclaration(VariableParsingFlags::CONST);
1622            }
1623            case lexer::TokenType::KEYW_LET: {
1624                return parser->ParseVariableDeclaration(VariableParsingFlags::LET);
1625            }
1626            case lexer::TokenType::KEYW_FUNCTION: {
1627                return parser->ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1628            }
1629            case lexer::TokenType::KEYW_CLASS: {
1630                return parser->ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED, flags);
1631            }
1632            case lexer::TokenType::KEYW_ENUM: {
1633                return parser->ParseEnumDeclaration();
1634            }
1635            case lexer::TokenType::KEYW_INTERFACE: {
1636                return parser->ParseInterfaceDeclaration(false);
1637            }
1638            case lexer::TokenType::KEYW_TYPE: {
1639                return parser->ParseTypeAliasDeclaration();
1640            }
1641            case lexer::TokenType::KEYW_GLOBAL:
1642            case lexer::TokenType::KEYW_MODULE:
1643            case lexer::TokenType::KEYW_NAMESPACE: {
1644                return parser->ParseModuleDeclaration();
1645            }
1646            default: {
1647                parser->ExpectToken(lexer::TokenType::KEYW_ASYNC);
1648                return parser->ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1649            }
1650        }
1651    }
1652};
1653
1654ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1655{
1656    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1657        CheckDeclare();
1658    }
1659
1660    ir::Statement *decl =
1661        ParseNamedExportDeclarationHelper::GetParsedDeclaration(this, Lexer()->GetToken().KeywordType());
1662
1663    if (decl->IsVariableDeclaration()) {
1664        ConsumeSemicolon(decl);
1665    }
1666
1667    ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1668    auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1669    exportDeclaration->SetRange({startLoc, decl->End()});
1670
1671    return exportDeclaration;
1672}
1673
1674ir::AstNode *ASParser::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1675{
1676    ASSERT(specifiers->empty());
1677
1678    if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1679        ParseImportDefaultSpecifier(specifiers);
1680        return nullptr;
1681    }
1682
1683    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1684        ParseNameSpaceImport(specifiers);
1685    } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1686        ParseNamedImportSpecifiers(specifiers);
1687    }
1688
1689    return nullptr;
1690}
1691
1692ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
1693{
1694    char32_t nextChar = Lexer()->Lookahead();
1695    if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
1696        return ParseExpressionStatement();
1697    }
1698
1699    lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1700    Lexer()->NextToken();  // eat import
1701
1702    ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
1703
1704    ir::StringLiteral *source = nullptr;
1705
1706    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1707        ParseImportSpecifiers(&specifiers);
1708        source = ParseFromClause(true);
1709    } else {
1710        source = ParseFromClause(false);
1711    }
1712
1713    lexer::SourcePosition endLoc = source->End();
1714    auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
1715    importDeclaration->SetRange({startLoc, endLoc});
1716
1717    ConsumeSemicolon(importDeclaration);
1718
1719    return importDeclaration;
1720}
1721
1722void ASParser::ThrowIllegalBreakError()
1723{
1724    ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement");
1725}
1726
1727void ASParser::ThrowIllegalContinueError()
1728{
1729    ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
1730}
1731
1732}  // namespace ark::es2panda::parser
1733