13af6ab5fSopenharmony_ci/**
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#include "TSparser.h"
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci#include "parser/parserStatusContext.h"
193af6ab5fSopenharmony_ci#include "macros.h"
203af6ab5fSopenharmony_ci#include "parserFlags.h"
213af6ab5fSopenharmony_ci#include "util/helpers.h"
223af6ab5fSopenharmony_ci#include "varbinder/privateBinding.h"
233af6ab5fSopenharmony_ci#include "varbinder/scope.h"
243af6ab5fSopenharmony_ci#include "varbinder/tsBinding.h"
253af6ab5fSopenharmony_ci#include "lexer/TSLexer.h"
263af6ab5fSopenharmony_ci#include "ir/base/spreadElement.h"
273af6ab5fSopenharmony_ci#include "ir/base/decorator.h"
283af6ab5fSopenharmony_ci#include "ir/base/classElement.h"
293af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h"
303af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h"
313af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h"
323af6ab5fSopenharmony_ci#include "ir/module/importDefaultSpecifier.h"
333af6ab5fSopenharmony_ci#include "ir/module/exportDefaultDeclaration.h"
343af6ab5fSopenharmony_ci#include "ir/module/exportAllDeclaration.h"
353af6ab5fSopenharmony_ci#include "ir/module/exportNamedDeclaration.h"
363af6ab5fSopenharmony_ci#include "ir/module/importDeclaration.h"
373af6ab5fSopenharmony_ci#include "ir/expressions/memberExpression.h"
383af6ab5fSopenharmony_ci#include "ir/expressions/sequenceExpression.h"
393af6ab5fSopenharmony_ci#include "ir/expressions/templateLiteral.h"
403af6ab5fSopenharmony_ci#include "ir/expressions/taggedTemplateExpression.h"
413af6ab5fSopenharmony_ci#include "ir/expressions/callExpression.h"
423af6ab5fSopenharmony_ci#include "ir/expressions/functionExpression.h"
433af6ab5fSopenharmony_ci#include "ir/expressions/arrowFunctionExpression.h"
443af6ab5fSopenharmony_ci#include "ir/expressions/yieldExpression.h"
453af6ab5fSopenharmony_ci#include "ir/expressions/assignmentExpression.h"
463af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h"
473af6ab5fSopenharmony_ci#include "ir/expressions/objectExpression.h"
483af6ab5fSopenharmony_ci#include "ir/expressions/arrayExpression.h"
493af6ab5fSopenharmony_ci#include "ir/expressions/literals/bigIntLiteral.h"
503af6ab5fSopenharmony_ci#include "ir/expressions/literals/booleanLiteral.h"
513af6ab5fSopenharmony_ci#include "ir/expressions/literals/nullLiteral.h"
523af6ab5fSopenharmony_ci#include "ir/expressions/literals/numberLiteral.h"
533af6ab5fSopenharmony_ci#include "ir/expressions/literals/stringLiteral.h"
543af6ab5fSopenharmony_ci#include "ir/statements/emptyStatement.h"
553af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h"
563af6ab5fSopenharmony_ci#include "ir/statements/ifStatement.h"
573af6ab5fSopenharmony_ci#include "ir/statements/doWhileStatement.h"
583af6ab5fSopenharmony_ci#include "ir/statements/whileStatement.h"
593af6ab5fSopenharmony_ci#include "ir/statements/tryStatement.h"
603af6ab5fSopenharmony_ci#include "ir/statements/breakStatement.h"
613af6ab5fSopenharmony_ci#include "ir/statements/continueStatement.h"
623af6ab5fSopenharmony_ci#include "ir/statements/throwStatement.h"
633af6ab5fSopenharmony_ci#include "ir/statements/switchStatement.h"
643af6ab5fSopenharmony_ci#include "ir/statements/returnStatement.h"
653af6ab5fSopenharmony_ci#include "ir/statements/debuggerStatement.h"
663af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h"
673af6ab5fSopenharmony_ci#include "ir/statements/labelledStatement.h"
683af6ab5fSopenharmony_ci#include "ir/statements/variableDeclarator.h"
693af6ab5fSopenharmony_ci#include "ir/statements/functionDeclaration.h"
703af6ab5fSopenharmony_ci#include "ir/ts/tsLiteralType.h"
713af6ab5fSopenharmony_ci#include "ir/ts/tsMappedType.h"
723af6ab5fSopenharmony_ci#include "ir/ts/tsImportType.h"
733af6ab5fSopenharmony_ci#include "ir/ts/tsThisType.h"
743af6ab5fSopenharmony_ci#include "ir/ts/tsConditionalType.h"
753af6ab5fSopenharmony_ci#include "ir/ts/tsTypeOperator.h"
763af6ab5fSopenharmony_ci#include "ir/ts/tsInferType.h"
773af6ab5fSopenharmony_ci#include "ir/ts/tsTupleType.h"
783af6ab5fSopenharmony_ci#include "ir/ts/tsNamedTupleMember.h"
793af6ab5fSopenharmony_ci#include "ir/ts/tsQualifiedName.h"
803af6ab5fSopenharmony_ci#include "ir/ts/tsIndexedAccessType.h"
813af6ab5fSopenharmony_ci#include "ir/ts/tsTypeQuery.h"
823af6ab5fSopenharmony_ci#include "ir/ts/tsTypeReference.h"
833af6ab5fSopenharmony_ci#include "ir/ts/tsTypePredicate.h"
843af6ab5fSopenharmony_ci#include "ir/ts/tsTypeLiteral.h"
853af6ab5fSopenharmony_ci#include "ir/ts/tsArrayType.h"
863af6ab5fSopenharmony_ci#include "ir/ts/tsUnionType.h"
873af6ab5fSopenharmony_ci#include "ir/ts/tsIntersectionType.h"
883af6ab5fSopenharmony_ci#include "ir/ts/tsAnyKeyword.h"
893af6ab5fSopenharmony_ci#include "ir/ts/tsUndefinedKeyword.h"
903af6ab5fSopenharmony_ci#include "ir/ts/tsVoidKeyword.h"
913af6ab5fSopenharmony_ci#include "ir/ts/tsNumberKeyword.h"
923af6ab5fSopenharmony_ci#include "ir/ts/tsStringKeyword.h"
933af6ab5fSopenharmony_ci#include "ir/ts/tsBooleanKeyword.h"
943af6ab5fSopenharmony_ci#include "ir/ts/tsBigintKeyword.h"
953af6ab5fSopenharmony_ci#include "ir/ts/tsUnknownKeyword.h"
963af6ab5fSopenharmony_ci#include "ir/ts/tsNullKeyword.h"
973af6ab5fSopenharmony_ci#include "ir/ts/tsNeverKeyword.h"
983af6ab5fSopenharmony_ci#include "ir/ts/tsObjectKeyword.h"
993af6ab5fSopenharmony_ci#include "ir/ts/tsFunctionType.h"
1003af6ab5fSopenharmony_ci#include "ir/ts/tsConstructorType.h"
1013af6ab5fSopenharmony_ci#include "ir/ts/tsParenthesizedType.h"
1023af6ab5fSopenharmony_ci#include "ir/ts/tsTypeAssertion.h"
1033af6ab5fSopenharmony_ci#include "ir/ts/tsAsExpression.h"
1043af6ab5fSopenharmony_ci#include "ir/ts/tsNonNullExpression.h"
1053af6ab5fSopenharmony_ci#include "ir/ts/tsEnumDeclaration.h"
1063af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceDeclaration.h"
1073af6ab5fSopenharmony_ci#include "ir/ts/tsTypeAliasDeclaration.h"
1083af6ab5fSopenharmony_ci#include "ir/ts/tsModuleDeclaration.h"
1093af6ab5fSopenharmony_ci#include "ir/ts/tsTypeParameterInstantiation.h"
1103af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceHeritage.h"
1113af6ab5fSopenharmony_ci#include "ir/base/tsSignatureDeclaration.h"
1123af6ab5fSopenharmony_ci#include "ir/base/tsIndexSignature.h"
1133af6ab5fSopenharmony_ci#include "ir/base/tsMethodSignature.h"
1143af6ab5fSopenharmony_ci#include "ir/base/tsPropertySignature.h"
1153af6ab5fSopenharmony_ci#include "ir/ts/tsParameterProperty.h"
1163af6ab5fSopenharmony_ci#include "ir/ts/tsClassImplements.h"
1173af6ab5fSopenharmony_ci#include "ir/ts/tsImportEqualsDeclaration.h"
1183af6ab5fSopenharmony_ci#include "ir/ts/tsExternalModuleReference.h"
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_cinamespace ark::es2panda::parser {
1213af6ab5fSopenharmony_cistd::unique_ptr<lexer::Lexer> TSParser::InitLexer(const SourceFile &sourceFile)
1223af6ab5fSopenharmony_ci{
1233af6ab5fSopenharmony_ci    GetProgram()->SetSource(sourceFile);
1243af6ab5fSopenharmony_ci    auto lexer = std::make_unique<lexer::TSLexer>(&GetContext());
1253af6ab5fSopenharmony_ci    SetLexer(lexer.get());
1263af6ab5fSopenharmony_ci    return lexer;
1273af6ab5fSopenharmony_ci}
1283af6ab5fSopenharmony_ci
1293af6ab5fSopenharmony_ciir::Decorator *TSParser::ParseDecorator()
1303af6ab5fSopenharmony_ci{
1313af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
1323af6ab5fSopenharmony_ci
1333af6ab5fSopenharmony_ci    lexer::SourcePosition start = Lexer()->GetToken().Start();
1343af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '@'
1353af6ab5fSopenharmony_ci
1363af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1373af6ab5fSopenharmony_ci        ThrowSyntaxError("Identifier expected");
1383af6ab5fSopenharmony_ci    }
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_ci    ir::Expression *expr = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1413af6ab5fSopenharmony_ci    expr->SetRange(Lexer()->GetToken().Loc());
1423af6ab5fSopenharmony_ci    Lexer()->NextToken();
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_ci    while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1453af6ab5fSopenharmony_ci        Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1483af6ab5fSopenharmony_ci            ThrowSyntaxError("Identifier expected");
1493af6ab5fSopenharmony_ci        }
1503af6ab5fSopenharmony_ci
1513af6ab5fSopenharmony_ci        auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1523af6ab5fSopenharmony_ci        identNode->SetRange(Lexer()->GetToken().Loc());
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci        expr =
1553af6ab5fSopenharmony_ci            AllocNode<ir::MemberExpression>(expr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false);
1563af6ab5fSopenharmony_ci        Lexer()->NextToken();
1573af6ab5fSopenharmony_ci    }
1583af6ab5fSopenharmony_ci
1593af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1603af6ab5fSopenharmony_ci        expr = ParseCallExpression(expr);
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    auto *result = AllocNode<ir::Decorator>(expr);
1643af6ab5fSopenharmony_ci    result->SetRange({start, expr->End()});
1653af6ab5fSopenharmony_ci
1663af6ab5fSopenharmony_ci    return result;
1673af6ab5fSopenharmony_ci}
1683af6ab5fSopenharmony_ci
1693af6ab5fSopenharmony_civoid TSParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
1703af6ab5fSopenharmony_ci{
1713af6ab5fSopenharmony_ci    if (decorators.empty()) {
1723af6ab5fSopenharmony_ci        return;
1733af6ab5fSopenharmony_ci    }
1743af6ab5fSopenharmony_ci
1753af6ab5fSopenharmony_ci    if (!node->CanHaveDecorator(true)) {
1763af6ab5fSopenharmony_ci        ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
1773af6ab5fSopenharmony_ci    }
1783af6ab5fSopenharmony_ci
1793af6ab5fSopenharmony_ci    node->AddDecorators(std::move(decorators));
1803af6ab5fSopenharmony_ci}
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ciir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration()
1833af6ab5fSopenharmony_ci{
1843af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
1853af6ab5fSopenharmony_ci    lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
1863af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat type keyword
1873af6ab5fSopenharmony_ci
1883af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1893af6ab5fSopenharmony_ci        ThrowSyntaxError("Identifier expected");
1903af6ab5fSopenharmony_ci    }
1913af6ab5fSopenharmony_ci
1923af6ab5fSopenharmony_ci    if (Lexer()->GetToken().IsReservedTypeName()) {
1933af6ab5fSopenharmony_ci        std::string errMsg("Type alias name cannot be '");
1943af6ab5fSopenharmony_ci        errMsg.append(TokenToString(Lexer()->GetToken().KeywordType()));
1953af6ab5fSopenharmony_ci        errMsg.append("'");
1963af6ab5fSopenharmony_ci        ThrowSyntaxError(errMsg.c_str());
1973af6ab5fSopenharmony_ci    }
1983af6ab5fSopenharmony_ci
1993af6ab5fSopenharmony_ci    const util::StringView &ident = Lexer()->GetToken().Ident();
2003af6ab5fSopenharmony_ci
2013af6ab5fSopenharmony_ci    auto *id = AllocNode<ir::Identifier>(ident, Allocator());
2023af6ab5fSopenharmony_ci    id->SetRange(Lexer()->GetToken().Loc());
2033af6ab5fSopenharmony_ci    Lexer()->NextToken();
2043af6ab5fSopenharmony_ci
2053af6ab5fSopenharmony_ci    ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
2063af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
2073af6ab5fSopenharmony_ci        auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
2083af6ab5fSopenharmony_ci        typeParamDecl = ParseTypeParameterDeclaration(&options);
2093af6ab5fSopenharmony_ci    }
2103af6ab5fSopenharmony_ci
2113af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2123af6ab5fSopenharmony_ci        ThrowSyntaxError("'=' expected");
2133af6ab5fSopenharmony_ci    }
2143af6ab5fSopenharmony_ci
2153af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '='
2163af6ab5fSopenharmony_ci
2173af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
2183af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
2193af6ab5fSopenharmony_ci
2203af6ab5fSopenharmony_ci    auto *typeAliasDecl =
2213af6ab5fSopenharmony_ci        AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext());
2223af6ab5fSopenharmony_ci    typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()});
2233af6ab5fSopenharmony_ci
2243af6ab5fSopenharmony_ci    return typeAliasDecl;
2253af6ab5fSopenharmony_ci}
2263af6ab5fSopenharmony_ci
2273af6ab5fSopenharmony_cibool TSParser::CurrentLiteralIsBasicType() const
2283af6ab5fSopenharmony_ci{
2293af6ab5fSopenharmony_ci    switch (Lexer()->GetToken().KeywordType()) {
2303af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_ANY:
2313af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_BOOLEAN:
2323af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_NUMBER:
2333af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_STRING:
2343af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_UNKNOWN:
2353af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_UNDEFINED:
2363af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_NEVER:
2373af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_OBJECT:
2383af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_BIGINT: {
2393af6ab5fSopenharmony_ci            return true;
2403af6ab5fSopenharmony_ci        }
2413af6ab5fSopenharmony_ci        default: {
2423af6ab5fSopenharmony_ci            break;
2433af6ab5fSopenharmony_ci        }
2443af6ab5fSopenharmony_ci    }
2453af6ab5fSopenharmony_ci
2463af6ab5fSopenharmony_ci    return false;
2473af6ab5fSopenharmony_ci}
2483af6ab5fSopenharmony_ci
2493af6ab5fSopenharmony_cibool TSParser::CurrentIsBasicType()
2503af6ab5fSopenharmony_ci{
2513af6ab5fSopenharmony_ci    switch (Lexer()->GetToken().Type()) {
2523af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_NUMBER:
2533af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_STRING:
2543af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_FALSE:
2553af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_TRUE:
2563af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_NULL:
2573af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_THIS:
2583af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_VOID: {
2593af6ab5fSopenharmony_ci            return true;
2603af6ab5fSopenharmony_ci        }
2613af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_IDENT: {
2623af6ab5fSopenharmony_ci            return CurrentLiteralIsBasicType();
2633af6ab5fSopenharmony_ci        }
2643af6ab5fSopenharmony_ci        default: {
2653af6ab5fSopenharmony_ci            break;
2663af6ab5fSopenharmony_ci        }
2673af6ab5fSopenharmony_ci    }
2683af6ab5fSopenharmony_ci
2693af6ab5fSopenharmony_ci    return false;
2703af6ab5fSopenharmony_ci}
2713af6ab5fSopenharmony_ci
2723af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
2733af6ab5fSopenharmony_ci{
2743af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = nullptr;
2753af6ab5fSopenharmony_ci
2763af6ab5fSopenharmony_ci    while (true) {
2773af6ab5fSopenharmony_ci        ir::TypeNode *element = ParseTypeAnnotationElement(typeAnnotation, options);
2783af6ab5fSopenharmony_ci
2793af6ab5fSopenharmony_ci        *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
2803af6ab5fSopenharmony_ci
2813af6ab5fSopenharmony_ci        if (element == nullptr) {
2823af6ab5fSopenharmony_ci            break;
2833af6ab5fSopenharmony_ci        }
2843af6ab5fSopenharmony_ci
2853af6ab5fSopenharmony_ci        typeAnnotation = element;
2863af6ab5fSopenharmony_ci
2873af6ab5fSopenharmony_ci        if ((((*options) & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) != 0) && Lexer()->GetToken().NewLine()) {
2883af6ab5fSopenharmony_ci            break;
2893af6ab5fSopenharmony_ci        }
2903af6ab5fSopenharmony_ci    }
2913af6ab5fSopenharmony_ci
2923af6ab5fSopenharmony_ci    return typeAnnotation;
2933af6ab5fSopenharmony_ci}
2943af6ab5fSopenharmony_ci
2953af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseIdentifierReference()
2963af6ab5fSopenharmony_ci{
2973af6ab5fSopenharmony_ci    if (CurrentLiteralIsBasicType() && Lexer()->Lookahead() != lexer::LEX_CHAR_DOT) {
2983af6ab5fSopenharmony_ci        return ParseBasicType();
2993af6ab5fSopenharmony_ci    }
3003af6ab5fSopenharmony_ci
3013af6ab5fSopenharmony_ci    return ParseTypeReferenceOrQuery();
3023af6ab5fSopenharmony_ci}
3033af6ab5fSopenharmony_ci
3043af6ab5fSopenharmony_cibool TSParser::IsStartOfMappedType() const
3053af6ab5fSopenharmony_ci{
3063af6ab5fSopenharmony_ci    auto pos = Lexer()->Save();
3073af6ab5fSopenharmony_ci    Lexer()->NextToken();
3083af6ab5fSopenharmony_ci    bool result = false;
3093af6ab5fSopenharmony_ci
3103af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
3113af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
3123af6ab5fSopenharmony_ci        Lexer()->NextToken();
3133af6ab5fSopenharmony_ci        result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY;
3143af6ab5fSopenharmony_ci        Lexer()->Rewind(pos);
3153af6ab5fSopenharmony_ci        return result;
3163af6ab5fSopenharmony_ci    }
3173af6ab5fSopenharmony_ci
3183af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
3193af6ab5fSopenharmony_ci        Lexer()->NextToken();
3203af6ab5fSopenharmony_ci    }
3213af6ab5fSopenharmony_ci
3223af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
3233af6ab5fSopenharmony_ci        Lexer()->Rewind(pos);
3243af6ab5fSopenharmony_ci        return false;
3253af6ab5fSopenharmony_ci    }
3263af6ab5fSopenharmony_ci
3273af6ab5fSopenharmony_ci    Lexer()->NextToken();
3283af6ab5fSopenharmony_ci
3293af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
3303af6ab5fSopenharmony_ci        Lexer()->Rewind(pos);
3313af6ab5fSopenharmony_ci        return false;
3323af6ab5fSopenharmony_ci    }
3333af6ab5fSopenharmony_ci
3343af6ab5fSopenharmony_ci    Lexer()->NextToken();
3353af6ab5fSopenharmony_ci
3363af6ab5fSopenharmony_ci    result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IN;
3373af6ab5fSopenharmony_ci
3383af6ab5fSopenharmony_ci    Lexer()->Rewind(pos);
3393af6ab5fSopenharmony_ci    return result;
3403af6ab5fSopenharmony_ci}
3413af6ab5fSopenharmony_ci
3423af6ab5fSopenharmony_cibool TSParser::IsStartOfTypePredicate() const
3433af6ab5fSopenharmony_ci{
3443af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
3453af6ab5fSopenharmony_ci           Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS);
3463af6ab5fSopenharmony_ci
3473af6ab5fSopenharmony_ci    auto pos = Lexer()->Save();
3483af6ab5fSopenharmony_ci    bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
3493af6ab5fSopenharmony_ci    if (isAsserts) {
3503af6ab5fSopenharmony_ci        Lexer()->NextToken();
3513af6ab5fSopenharmony_ci    }
3523af6ab5fSopenharmony_ci
3533af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT &&
3543af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() != lexer::TokenType::KEYW_THIS) {
3553af6ab5fSopenharmony_ci        Lexer()->Rewind(pos);
3563af6ab5fSopenharmony_ci        return false;
3573af6ab5fSopenharmony_ci    }
3583af6ab5fSopenharmony_ci
3593af6ab5fSopenharmony_ci    if (isAsserts) {
3603af6ab5fSopenharmony_ci        Lexer()->Rewind(pos);
3613af6ab5fSopenharmony_ci        return true;
3623af6ab5fSopenharmony_ci    }
3633af6ab5fSopenharmony_ci
3643af6ab5fSopenharmony_ci    Lexer()->NextToken();
3653af6ab5fSopenharmony_ci
3663af6ab5fSopenharmony_ci    bool result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS;
3673af6ab5fSopenharmony_ci    Lexer()->Rewind(pos);
3683af6ab5fSopenharmony_ci    return result;
3693af6ab5fSopenharmony_ci}
3703af6ab5fSopenharmony_ci
3713af6ab5fSopenharmony_cibool TSParser::IsStartOfAbstractConstructorType() const
3723af6ab5fSopenharmony_ci{
3733af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) {
3743af6ab5fSopenharmony_ci        return false;
3753af6ab5fSopenharmony_ci    }
3763af6ab5fSopenharmony_ci
3773af6ab5fSopenharmony_ci    lexer::LexerPosition pos = Lexer()->Save();
3783af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat 'abstract'
3793af6ab5fSopenharmony_ci    bool result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW;
3803af6ab5fSopenharmony_ci
3813af6ab5fSopenharmony_ci    Lexer()->Rewind(pos);
3823af6ab5fSopenharmony_ci
3833af6ab5fSopenharmony_ci    return result;
3843af6ab5fSopenharmony_ci}
3853af6ab5fSopenharmony_ci
3863af6ab5fSopenharmony_ciir::TSImportType *TSParser::ParseImportType(const lexer::SourcePosition &startLoc, bool isTypeof)
3873af6ab5fSopenharmony_ci{
3883af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT);
3893af6ab5fSopenharmony_ci
3903af6ab5fSopenharmony_ci    Lexer()->NextToken();
3913af6ab5fSopenharmony_ci
3923af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
3933af6ab5fSopenharmony_ci        ThrowSyntaxError("'(' expected");
3943af6ab5fSopenharmony_ci    }
3953af6ab5fSopenharmony_ci
3963af6ab5fSopenharmony_ci    Lexer()->NextToken();
3973af6ab5fSopenharmony_ci
3983af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
3993af6ab5fSopenharmony_ci    ir::TypeNode *param = ParseTypeAnnotation(&options);
4003af6ab5fSopenharmony_ci
4013af6ab5fSopenharmony_ci    if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) {
4023af6ab5fSopenharmony_ci        ThrowSyntaxError("String literal expected");
4033af6ab5fSopenharmony_ci    }
4043af6ab5fSopenharmony_ci
4053af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
4063af6ab5fSopenharmony_ci        ThrowSyntaxError("')' expected");
4073af6ab5fSopenharmony_ci    }
4083af6ab5fSopenharmony_ci
4093af6ab5fSopenharmony_ci    Lexer()->NextToken();
4103af6ab5fSopenharmony_ci
4113af6ab5fSopenharmony_ci    ir::Expression *qualifier = nullptr;
4123af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
4133af6ab5fSopenharmony_ci        Lexer()->NextToken();
4143af6ab5fSopenharmony_ci        qualifier = ParseQualifiedName();
4153af6ab5fSopenharmony_ci    }
4163af6ab5fSopenharmony_ci
4173af6ab5fSopenharmony_ci    ir::TSTypeParameterInstantiation *typeParams = nullptr;
4183af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT ||
4193af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
4203af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
4213af6ab5fSopenharmony_ci            Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
4223af6ab5fSopenharmony_ci        }
4233af6ab5fSopenharmony_ci
4243af6ab5fSopenharmony_ci        typeParams = ParseTypeParameterInstantiation(&options);
4253af6ab5fSopenharmony_ci    }
4263af6ab5fSopenharmony_ci
4273af6ab5fSopenharmony_ci    auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof);
4283af6ab5fSopenharmony_ci
4293af6ab5fSopenharmony_ci    importType->SetRange({startLoc, Lexer()->GetToken().End()});
4303af6ab5fSopenharmony_ci
4313af6ab5fSopenharmony_ci    return importType;
4323af6ab5fSopenharmony_ci}
4333af6ab5fSopenharmony_ci
4343af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseThisType(bool throwError)
4353af6ab5fSopenharmony_ci{
4363af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS);
4373af6ab5fSopenharmony_ci
4383af6ab5fSopenharmony_ci    if (throwError && ((GetContext().Status() & ParserStatus::ALLOW_THIS_TYPE) == 0)) {
4393af6ab5fSopenharmony_ci        ThrowSyntaxError(
4403af6ab5fSopenharmony_ci            "A 'this' type is available only in a non-static member "
4413af6ab5fSopenharmony_ci            "of a class or interface.");
4423af6ab5fSopenharmony_ci    }
4433af6ab5fSopenharmony_ci
4443af6ab5fSopenharmony_ci    auto *returnType = AllocNode<ir::TSThisType>();
4453af6ab5fSopenharmony_ci    returnType->SetRange(Lexer()->GetToken().Loc());
4463af6ab5fSopenharmony_ci
4473af6ab5fSopenharmony_ci    Lexer()->NextToken();
4483af6ab5fSopenharmony_ci
4493af6ab5fSopenharmony_ci    return returnType;
4503af6ab5fSopenharmony_ci}
4513af6ab5fSopenharmony_ci
4523af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseConditionalType(ir::Expression *checkType, bool restrictExtends)
4533af6ab5fSopenharmony_ci{
4543af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
4553af6ab5fSopenharmony_ci    if (restrictExtends) {
4563af6ab5fSopenharmony_ci        ThrowSyntaxError("'?' expected.");
4573af6ab5fSopenharmony_ci    }
4583af6ab5fSopenharmony_ci
4593af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc = checkType->Start();
4603af6ab5fSopenharmony_ci
4613af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat 'extends'
4623af6ab5fSopenharmony_ci
4633af6ab5fSopenharmony_ci    ParserStatus savedStatus = GetContext().Status();
4643af6ab5fSopenharmony_ci    GetContext().Status() |= ParserStatus::IN_EXTENDS;
4653af6ab5fSopenharmony_ci
4663af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options =
4673af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
4683af6ab5fSopenharmony_ci    auto *extendsType = ParseTypeAnnotation(&options);
4693af6ab5fSopenharmony_ci
4703af6ab5fSopenharmony_ci    GetContext().Status() = savedStatus;
4713af6ab5fSopenharmony_ci
4723af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
4733af6ab5fSopenharmony_ci        ThrowSyntaxError("'?' expected.");
4743af6ab5fSopenharmony_ci    }
4753af6ab5fSopenharmony_ci
4763af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '?'
4773af6ab5fSopenharmony_ci
4783af6ab5fSopenharmony_ci    options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
4793af6ab5fSopenharmony_ci    auto *trueType = ParseTypeAnnotation(&options);
4803af6ab5fSopenharmony_ci
4813af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
4823af6ab5fSopenharmony_ci        ThrowSyntaxError("':' expected.");
4833af6ab5fSopenharmony_ci    }
4843af6ab5fSopenharmony_ci
4853af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ':'
4863af6ab5fSopenharmony_ci
4873af6ab5fSopenharmony_ci    auto *falseType = ParseTypeAnnotation(&options);
4883af6ab5fSopenharmony_ci
4893af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = falseType->End();
4903af6ab5fSopenharmony_ci
4913af6ab5fSopenharmony_ci    auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType);
4923af6ab5fSopenharmony_ci
4933af6ab5fSopenharmony_ci    conditionalType->SetRange({startLoc, endLoc});
4943af6ab5fSopenharmony_ci
4953af6ab5fSopenharmony_ci    return conditionalType;
4963af6ab5fSopenharmony_ci}
4973af6ab5fSopenharmony_ci
4983af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference()
4993af6ab5fSopenharmony_ci{
5003af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
5013af6ab5fSopenharmony_ci
5023af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
5033af6ab5fSopenharmony_ci        lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start();
5043af6ab5fSopenharmony_ci        Lexer()->NextToken();
5053af6ab5fSopenharmony_ci
5063af6ab5fSopenharmony_ci        ir::TypeNode *type = ParseTypeAnnotation(&options);
5073af6ab5fSopenharmony_ci
5083af6ab5fSopenharmony_ci        if (!type->IsTSArrayType() && !type->IsTSTupleType()) {
5093af6ab5fSopenharmony_ci            ThrowSyntaxError(
5103af6ab5fSopenharmony_ci                "'readonly' type modifier is only permitted on array "
5113af6ab5fSopenharmony_ci                "and tuple literal types.");
5123af6ab5fSopenharmony_ci        }
5133af6ab5fSopenharmony_ci
5143af6ab5fSopenharmony_ci        auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY);
5153af6ab5fSopenharmony_ci
5163af6ab5fSopenharmony_ci        typeOperator->SetRange({typeOperatorStart, type->End()});
5173af6ab5fSopenharmony_ci
5183af6ab5fSopenharmony_ci        return typeOperator;
5193af6ab5fSopenharmony_ci    }
5203af6ab5fSopenharmony_ci
5213af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) {
5223af6ab5fSopenharmony_ci        lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start();
5233af6ab5fSopenharmony_ci        Lexer()->NextToken();
5243af6ab5fSopenharmony_ci
5253af6ab5fSopenharmony_ci        ir::TypeNode *type = ParseTypeAnnotation(&options);
5263af6ab5fSopenharmony_ci
5273af6ab5fSopenharmony_ci        auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF);
5283af6ab5fSopenharmony_ci
5293af6ab5fSopenharmony_ci        typeOperator->SetRange({typeOperatorStart, type->End()});
5303af6ab5fSopenharmony_ci
5313af6ab5fSopenharmony_ci        return typeOperator;
5323af6ab5fSopenharmony_ci    }
5333af6ab5fSopenharmony_ci
5343af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) {
5353af6ab5fSopenharmony_ci        if ((GetContext().Status() & ParserStatus::IN_EXTENDS) == 0) {
5363af6ab5fSopenharmony_ci            ThrowSyntaxError(
5373af6ab5fSopenharmony_ci                "'infer' declarations are only permitted in the "
5383af6ab5fSopenharmony_ci                "'extends' clause of a conditional type.");
5393af6ab5fSopenharmony_ci        }
5403af6ab5fSopenharmony_ci
5413af6ab5fSopenharmony_ci        lexer::SourcePosition inferStart = Lexer()->GetToken().Start();
5423af6ab5fSopenharmony_ci        Lexer()->NextToken();
5433af6ab5fSopenharmony_ci
5443af6ab5fSopenharmony_ci        ir::TSTypeParameter *typeParam = ParseTypeParameter(&options);
5453af6ab5fSopenharmony_ci
5463af6ab5fSopenharmony_ci        auto *inferType = AllocNode<ir::TSInferType>(typeParam);
5473af6ab5fSopenharmony_ci
5483af6ab5fSopenharmony_ci        inferType->SetRange({inferStart, Lexer()->GetToken().End()});
5493af6ab5fSopenharmony_ci
5503af6ab5fSopenharmony_ci        return inferType;
5513af6ab5fSopenharmony_ci    }
5523af6ab5fSopenharmony_ci
5533af6ab5fSopenharmony_ci    return ParseIdentifierReference();
5543af6ab5fSopenharmony_ci}
5553af6ab5fSopenharmony_ci
5563af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTupleElement(ir::TSTupleKind *kind, bool *seenOptional)
5573af6ab5fSopenharmony_ci{
5583af6ab5fSopenharmony_ci    lexer::SourcePosition elementStart = Lexer()->GetToken().Start();
5593af6ab5fSopenharmony_ci    ir::TypeNode *element = nullptr;
5603af6ab5fSopenharmony_ci    bool isOptional = false;
5613af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
5623af6ab5fSopenharmony_ci
5633af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !CurrentLiteralIsBasicType()) {
5643af6ab5fSopenharmony_ci        auto *elementIdent = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
5653af6ab5fSopenharmony_ci        elementIdent->SetRange(Lexer()->GetToken().Loc());
5663af6ab5fSopenharmony_ci
5673af6ab5fSopenharmony_ci        if (Lexer()->Lookahead() == lexer::LEX_CHAR_COLON || Lexer()->Lookahead() == lexer::LEX_CHAR_QUESTION) {
5683af6ab5fSopenharmony_ci            if (*kind == ir::TSTupleKind::DEFAULT) {
5693af6ab5fSopenharmony_ci                ThrowSyntaxError("Tuple members must all have names or all not have names");
5703af6ab5fSopenharmony_ci            }
5713af6ab5fSopenharmony_ci
5723af6ab5fSopenharmony_ci            Lexer()->NextToken();  // eat ident
5733af6ab5fSopenharmony_ci
5743af6ab5fSopenharmony_ci            if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
5753af6ab5fSopenharmony_ci                Lexer()->NextToken();  // eat '?'
5763af6ab5fSopenharmony_ci                isOptional = true;
5773af6ab5fSopenharmony_ci                *seenOptional = true;
5783af6ab5fSopenharmony_ci            } else if (*seenOptional) {
5793af6ab5fSopenharmony_ci                ThrowSyntaxError("A required element cannot follow an optional element");
5803af6ab5fSopenharmony_ci            }
5813af6ab5fSopenharmony_ci
5823af6ab5fSopenharmony_ci            if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
5833af6ab5fSopenharmony_ci                ThrowSyntaxError("':' expected");
5843af6ab5fSopenharmony_ci            }
5853af6ab5fSopenharmony_ci
5863af6ab5fSopenharmony_ci            Lexer()->NextToken();  // eat ':'
5873af6ab5fSopenharmony_ci            auto *elementType = ParseTypeAnnotation(&options);
5883af6ab5fSopenharmony_ci            *kind = ir::TSTupleKind::NAMED;
5893af6ab5fSopenharmony_ci
5903af6ab5fSopenharmony_ci            element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional);
5913af6ab5fSopenharmony_ci        } else {
5923af6ab5fSopenharmony_ci            element = ParseTypeReferenceOrQuery();
5933af6ab5fSopenharmony_ci        }
5943af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
5953af6ab5fSopenharmony_ci            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
5963af6ab5fSopenharmony_ci            element = ParseTypeAnnotationElement(element, &options);
5973af6ab5fSopenharmony_ci        }
5983af6ab5fSopenharmony_ci    } else {
5993af6ab5fSopenharmony_ci        if (*kind == ir::TSTupleKind::NAMED) {
6003af6ab5fSopenharmony_ci            ThrowSyntaxError("Tuple members must all have names or all not have names");
6013af6ab5fSopenharmony_ci        }
6023af6ab5fSopenharmony_ci
6033af6ab5fSopenharmony_ci        *kind = ir::TSTupleKind::DEFAULT;
6043af6ab5fSopenharmony_ci        element = ParseTypeAnnotation(&options);
6053af6ab5fSopenharmony_ci    }
6063af6ab5fSopenharmony_ci
6073af6ab5fSopenharmony_ci    if (element != nullptr) {
6083af6ab5fSopenharmony_ci        element->SetRange({elementStart, Lexer()->GetToken().End()});
6093af6ab5fSopenharmony_ci    }
6103af6ab5fSopenharmony_ci    return element;
6113af6ab5fSopenharmony_ci}
6123af6ab5fSopenharmony_ci
6133af6ab5fSopenharmony_ciir::TSTupleType *TSParser::ParseTupleType()
6143af6ab5fSopenharmony_ci{
6153af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
6163af6ab5fSopenharmony_ci    lexer::SourcePosition tupleStart = Lexer()->GetToken().Start();
6173af6ab5fSopenharmony_ci    ArenaVector<ir::TypeNode *> elements(Allocator()->Adapter());
6183af6ab5fSopenharmony_ci    ir::TSTupleKind kind = ir::TSTupleKind::NONE;
6193af6ab5fSopenharmony_ci    bool seenOptional = false;
6203af6ab5fSopenharmony_ci
6213af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '['
6223af6ab5fSopenharmony_ci
6233af6ab5fSopenharmony_ci    while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
6243af6ab5fSopenharmony_ci        ir::TypeNode *element = ParseTupleElement(&kind, &seenOptional);
6253af6ab5fSopenharmony_ci        elements.push_back(element);
6263af6ab5fSopenharmony_ci
6273af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
6283af6ab5fSopenharmony_ci            break;
6293af6ab5fSopenharmony_ci        }
6303af6ab5fSopenharmony_ci
6313af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
6323af6ab5fSopenharmony_ci            ThrowSyntaxError("',' expected.");
6333af6ab5fSopenharmony_ci        }
6343af6ab5fSopenharmony_ci
6353af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ','
6363af6ab5fSopenharmony_ci    }
6373af6ab5fSopenharmony_ci
6383af6ab5fSopenharmony_ci    lexer::SourcePosition tupleEnd = Lexer()->GetToken().End();
6393af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ']'
6403af6ab5fSopenharmony_ci
6413af6ab5fSopenharmony_ci    auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements));
6423af6ab5fSopenharmony_ci    tupleType->SetRange({tupleStart, tupleEnd});
6433af6ab5fSopenharmony_ci    return tupleType;
6443af6ab5fSopenharmony_ci}
6453af6ab5fSopenharmony_ci
6463af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseIndexAccessType(ir::TypeNode *typeName)
6473af6ab5fSopenharmony_ci{
6483af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
6493af6ab5fSopenharmony_ci
6503af6ab5fSopenharmony_ci    do {
6513af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat '['
6523af6ab5fSopenharmony_ci
6533af6ab5fSopenharmony_ci        ir::TypeNode *indexType = ParseTypeAnnotation(&options);
6543af6ab5fSopenharmony_ci
6553af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
6563af6ab5fSopenharmony_ci            ThrowSyntaxError("']' expected");
6573af6ab5fSopenharmony_ci        }
6583af6ab5fSopenharmony_ci
6593af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ']'
6603af6ab5fSopenharmony_ci
6613af6ab5fSopenharmony_ci        typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType);
6623af6ab5fSopenharmony_ci        typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), Lexer()->GetToken().End()});
6633af6ab5fSopenharmony_ci    } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
6643af6ab5fSopenharmony_ci             Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE);
6653af6ab5fSopenharmony_ci
6663af6ab5fSopenharmony_ci    return typeName;
6673af6ab5fSopenharmony_ci}
6683af6ab5fSopenharmony_ci
6693af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery)
6703af6ab5fSopenharmony_ci{
6713af6ab5fSopenharmony_ci    lexer::SourcePosition referenceStartLoc = Lexer()->GetToken().Start();
6723af6ab5fSopenharmony_ci
6733af6ab5fSopenharmony_ci    if (parseQuery) {
6743af6ab5fSopenharmony_ci        ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF);
6753af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'typeof'
6763af6ab5fSopenharmony_ci
6773af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) {
6783af6ab5fSopenharmony_ci            lexer::SourcePosition &startLoc = referenceStartLoc;
6793af6ab5fSopenharmony_ci            return ParseImportType(startLoc, true);
6803af6ab5fSopenharmony_ci        }
6813af6ab5fSopenharmony_ci
6823af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
6833af6ab5fSopenharmony_ci            ThrowSyntaxError("Identifier expected.");
6843af6ab5fSopenharmony_ci        }
6853af6ab5fSopenharmony_ci    }
6863af6ab5fSopenharmony_ci
6873af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
6883af6ab5fSopenharmony_ci           Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
6893af6ab5fSopenharmony_ci
6903af6ab5fSopenharmony_ci    ir::Expression *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
6913af6ab5fSopenharmony_ci    typeName->SetRange(Lexer()->GetToken().Loc());
6923af6ab5fSopenharmony_ci    typeName->AsIdentifier()->SetReference();
6933af6ab5fSopenharmony_ci
6943af6ab5fSopenharmony_ci    if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
6953af6ab5fSopenharmony_ci        Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
6963af6ab5fSopenharmony_ci    } else {
6973af6ab5fSopenharmony_ci        Lexer()->NextToken();
6983af6ab5fSopenharmony_ci    }
6993af6ab5fSopenharmony_ci
7003af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
7013af6ab5fSopenharmony_ci        typeName = ParseQualifiedReference(typeName);
7023af6ab5fSopenharmony_ci    }
7033af6ab5fSopenharmony_ci
7043af6ab5fSopenharmony_ci    ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
7053af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
7063af6ab5fSopenharmony_ci        if (parseQuery) {
7073af6ab5fSopenharmony_ci            ThrowSyntaxError("Unexpected token.");
7083af6ab5fSopenharmony_ci        }
7093af6ab5fSopenharmony_ci
7103af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
7113af6ab5fSopenharmony_ci        typeParamInst = ParseTypeParameterInstantiation(&options);
7123af6ab5fSopenharmony_ci    }
7133af6ab5fSopenharmony_ci
7143af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
7153af6ab5fSopenharmony_ci        Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE) {
7163af6ab5fSopenharmony_ci        ir::TypeNode *typeRef = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode()
7173af6ab5fSopenharmony_ci                                           : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode();
7183af6ab5fSopenharmony_ci
7193af6ab5fSopenharmony_ci        typeRef->SetRange({referenceStartLoc, Lexer()->GetToken().End()});
7203af6ab5fSopenharmony_ci
7213af6ab5fSopenharmony_ci        return ParseIndexAccessType(typeRef);
7223af6ab5fSopenharmony_ci    }
7233af6ab5fSopenharmony_ci
7243af6ab5fSopenharmony_ci    ir::TypeNode *returnNode = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode()
7253af6ab5fSopenharmony_ci                                          : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode();
7263af6ab5fSopenharmony_ci
7273af6ab5fSopenharmony_ci    returnNode->SetRange({referenceStartLoc, typeName->End()});
7283af6ab5fSopenharmony_ci
7293af6ab5fSopenharmony_ci    return returnNode;
7303af6ab5fSopenharmony_ci}
7313af6ab5fSopenharmony_ci
7323af6ab5fSopenharmony_ciir::TSTypeParameter *TSParser::ParseMappedTypeParameter()
7333af6ab5fSopenharmony_ci{
7343af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
7353af6ab5fSopenharmony_ci
7363af6ab5fSopenharmony_ci    auto *paramName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
7373af6ab5fSopenharmony_ci    paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()});
7383af6ab5fSopenharmony_ci
7393af6ab5fSopenharmony_ci    Lexer()->NextToken();
7403af6ab5fSopenharmony_ci
7413af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat 'in'
7423af6ab5fSopenharmony_ci
7433af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
7443af6ab5fSopenharmony_ci    ir::TypeNode *constraint = ParseTypeAnnotation(&options);
7453af6ab5fSopenharmony_ci
7463af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = constraint->End();
7473af6ab5fSopenharmony_ci
7483af6ab5fSopenharmony_ci    auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr);
7493af6ab5fSopenharmony_ci
7503af6ab5fSopenharmony_ci    typeParameter->SetRange({startLoc, endLoc});
7513af6ab5fSopenharmony_ci
7523af6ab5fSopenharmony_ci    return typeParameter;
7533af6ab5fSopenharmony_ci}
7543af6ab5fSopenharmony_ci
7553af6ab5fSopenharmony_ciir::MappedOption TSParser::ParseMappedOption(lexer::TokenType tokenType)
7563af6ab5fSopenharmony_ci{
7573af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS &&
7583af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS &&
7593af6ab5fSopenharmony_ci        Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) {
7603af6ab5fSopenharmony_ci        return ir::MappedOption::NO_OPTS;
7613af6ab5fSopenharmony_ci    }
7623af6ab5fSopenharmony_ci
7633af6ab5fSopenharmony_ci    auto result = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS
7643af6ab5fSopenharmony_ci                                                                                   : ir::MappedOption::PLUS;
7653af6ab5fSopenharmony_ci
7663af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
7673af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
7683af6ab5fSopenharmony_ci        Lexer()->NextToken();
7693af6ab5fSopenharmony_ci    }
7703af6ab5fSopenharmony_ci
7713af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) {
7723af6ab5fSopenharmony_ci        ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."});
7733af6ab5fSopenharmony_ci    }
7743af6ab5fSopenharmony_ci
7753af6ab5fSopenharmony_ci    Lexer()->NextToken();
7763af6ab5fSopenharmony_ci
7773af6ab5fSopenharmony_ci    return result;
7783af6ab5fSopenharmony_ci}
7793af6ab5fSopenharmony_ci
7803af6ab5fSopenharmony_ciir::TSMappedType *TSParser::ParseMappedType()
7813af6ab5fSopenharmony_ci{
7823af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
7833af6ab5fSopenharmony_ci
7843af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
7853af6ab5fSopenharmony_ci    Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
7863af6ab5fSopenharmony_ci
7873af6ab5fSopenharmony_ci    ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY);
7883af6ab5fSopenharmony_ci
7893af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '['
7903af6ab5fSopenharmony_ci
7913af6ab5fSopenharmony_ci    ir::TSTypeParameter *typeParameter = ParseMappedTypeParameter();
7923af6ab5fSopenharmony_ci
7933af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
7943af6ab5fSopenharmony_ci        ThrowSyntaxError("']' expected");
7953af6ab5fSopenharmony_ci    }
7963af6ab5fSopenharmony_ci
7973af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ']'
7983af6ab5fSopenharmony_ci
7993af6ab5fSopenharmony_ci    ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK);
8003af6ab5fSopenharmony_ci
8013af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = nullptr;
8023af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
8033af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
8043af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
8053af6ab5fSopenharmony_ci        typeAnnotation = ParseTypeAnnotation(&options);
8063af6ab5fSopenharmony_ci    }
8073af6ab5fSopenharmony_ci
8083af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
8093af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
8103af6ab5fSopenharmony_ci        ThrowSyntaxError("';' expected");
8113af6ab5fSopenharmony_ci    }
8123af6ab5fSopenharmony_ci
8133af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
8143af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ';'
8153af6ab5fSopenharmony_ci    }
8163af6ab5fSopenharmony_ci
8173af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
8183af6ab5fSopenharmony_ci        ThrowSyntaxError("'}' expected");
8193af6ab5fSopenharmony_ci    }
8203af6ab5fSopenharmony_ci
8213af6ab5fSopenharmony_ci    auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, typeAnnotation, readonly, optional);
8223af6ab5fSopenharmony_ci
8233af6ab5fSopenharmony_ci    mappedType->SetRange({startLoc, Lexer()->GetToken().End()});
8243af6ab5fSopenharmony_ci
8253af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '}'
8263af6ab5fSopenharmony_ci
8273af6ab5fSopenharmony_ci    return mappedType;
8283af6ab5fSopenharmony_ci}
8293af6ab5fSopenharmony_ci
8303af6ab5fSopenharmony_ciir::TSTypePredicate *TSParser::ParseTypePredicate()
8313af6ab5fSopenharmony_ci{
8323af6ab5fSopenharmony_ci    auto pos = Lexer()->Save();
8333af6ab5fSopenharmony_ci    lexer::SourcePosition startPos = Lexer()->GetToken().Start();
8343af6ab5fSopenharmony_ci    bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
8353af6ab5fSopenharmony_ci    if (isAsserts) {
8363af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'asserts'
8373af6ab5fSopenharmony_ci        if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) {
8383af6ab5fSopenharmony_ci            isAsserts = false;
8393af6ab5fSopenharmony_ci            Lexer()->Rewind(pos);
8403af6ab5fSopenharmony_ci        }
8413af6ab5fSopenharmony_ci    }
8423af6ab5fSopenharmony_ci
8433af6ab5fSopenharmony_ci    ir::Expression *parameterName = nullptr;
8443af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
8453af6ab5fSopenharmony_ci        parameterName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
8463af6ab5fSopenharmony_ci    } else {
8473af6ab5fSopenharmony_ci        parameterName = AllocNode<ir::TSThisType>();
8483af6ab5fSopenharmony_ci    }
8493af6ab5fSopenharmony_ci
8503af6ab5fSopenharmony_ci    parameterName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()});
8513af6ab5fSopenharmony_ci
8523af6ab5fSopenharmony_ci    Lexer()->NextToken();
8533af6ab5fSopenharmony_ci
8543af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = nullptr;
8553af6ab5fSopenharmony_ci    lexer::SourcePosition endPos;
8563af6ab5fSopenharmony_ci    ir::TSTypePredicate *result = nullptr;
8573af6ab5fSopenharmony_ci
8583af6ab5fSopenharmony_ci    if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) {
8593af6ab5fSopenharmony_ci        endPos = parameterName->End();
8603af6ab5fSopenharmony_ci        result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
8613af6ab5fSopenharmony_ci        result->SetRange({startPos, endPos});
8623af6ab5fSopenharmony_ci        return result;
8633af6ab5fSopenharmony_ci    }
8643af6ab5fSopenharmony_ci
8653af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat 'is'
8663af6ab5fSopenharmony_ci
8673af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
8683af6ab5fSopenharmony_ci    typeAnnotation = ParseTypeAnnotation(&options);
8693af6ab5fSopenharmony_ci    endPos = typeAnnotation->End();
8703af6ab5fSopenharmony_ci
8713af6ab5fSopenharmony_ci    result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
8723af6ab5fSopenharmony_ci
8733af6ab5fSopenharmony_ci    result->SetRange({startPos, endPos});
8743af6ab5fSopenharmony_ci
8753af6ab5fSopenharmony_ci    return result;
8763af6ab5fSopenharmony_ci}
8773af6ab5fSopenharmony_ci
8783af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotation)
8793af6ab5fSopenharmony_ci{
8803af6ab5fSopenharmony_ci    if (typeAnnotation != nullptr) {
8813af6ab5fSopenharmony_ci        return nullptr;
8823af6ab5fSopenharmony_ci    }
8833af6ab5fSopenharmony_ci
8843af6ab5fSopenharmony_ci    if (IsStartOfMappedType()) {
8853af6ab5fSopenharmony_ci        return ParseMappedType();
8863af6ab5fSopenharmony_ci    }
8873af6ab5fSopenharmony_ci
8883af6ab5fSopenharmony_ci    lexer::SourcePosition bodyStart = Lexer()->GetToken().Start();
8893af6ab5fSopenharmony_ci    auto members = ParseTypeLiteralOrInterface();
8903af6ab5fSopenharmony_ci    lexer::SourcePosition bodyEnd = Lexer()->GetToken().End();
8913af6ab5fSopenharmony_ci    Lexer()->NextToken();
8923af6ab5fSopenharmony_ci
8933af6ab5fSopenharmony_ci    auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members));
8943af6ab5fSopenharmony_ci    auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType);
8953af6ab5fSopenharmony_ci    literalType->SetVariable(typeVar);
8963af6ab5fSopenharmony_ci    literalType->SetRange({bodyStart, bodyEnd});
8973af6ab5fSopenharmony_ci    return literalType;
8983af6ab5fSopenharmony_ci}
8993af6ab5fSopenharmony_ci
9003af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeReferenceOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate)
9013af6ab5fSopenharmony_ci{
9023af6ab5fSopenharmony_ci    if (typeAnnotation != nullptr) {
9033af6ab5fSopenharmony_ci        return nullptr;
9043af6ab5fSopenharmony_ci    }
9053af6ab5fSopenharmony_ci
9063af6ab5fSopenharmony_ci    if (canBeTsTypePredicate && IsStartOfTypePredicate()) {
9073af6ab5fSopenharmony_ci        return ParseTypePredicate();
9083af6ab5fSopenharmony_ci    }
9093af6ab5fSopenharmony_ci
9103af6ab5fSopenharmony_ci    return ParseTypeOperatorOrTypeReference();
9113af6ab5fSopenharmony_ci}
9123af6ab5fSopenharmony_ci
9133af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseThisTypeOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate,
9143af6ab5fSopenharmony_ci                                                     bool throwError)
9153af6ab5fSopenharmony_ci{
9163af6ab5fSopenharmony_ci    if (typeAnnotation != nullptr) {
9173af6ab5fSopenharmony_ci        return nullptr;
9183af6ab5fSopenharmony_ci    }
9193af6ab5fSopenharmony_ci
9203af6ab5fSopenharmony_ci    if (canBeTsTypePredicate && IsStartOfTypePredicate()) {
9213af6ab5fSopenharmony_ci        return ParseTypePredicate();
9223af6ab5fSopenharmony_ci    }
9233af6ab5fSopenharmony_ci
9243af6ab5fSopenharmony_ci    return ParseThisType(throwError);
9253af6ab5fSopenharmony_ci}
9263af6ab5fSopenharmony_ci
9273af6ab5fSopenharmony_ciir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType)
9283af6ab5fSopenharmony_ci{
9293af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
9303af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '['
9313af6ab5fSopenharmony_ci
9323af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
9333af6ab5fSopenharmony_ci        ThrowSyntaxError("']' expected");
9343af6ab5fSopenharmony_ci    }
9353af6ab5fSopenharmony_ci
9363af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = Lexer()->GetToken().End();
9373af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ']'
9383af6ab5fSopenharmony_ci
9393af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc = elementType->Start();
9403af6ab5fSopenharmony_ci    auto *arrayType = AllocNode<ir::TSArrayType>(elementType);
9413af6ab5fSopenharmony_ci    arrayType->SetRange({startLoc, endLoc});
9423af6ab5fSopenharmony_ci
9433af6ab5fSopenharmony_ci    return arrayType;
9443af6ab5fSopenharmony_ci}
9453af6ab5fSopenharmony_ci
9463af6ab5fSopenharmony_ciir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExtends)
9473af6ab5fSopenharmony_ci{
9483af6ab5fSopenharmony_ci    ArenaVector<ir::TypeNode *> types(Allocator()->Adapter());
9493af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc;
9503af6ab5fSopenharmony_ci
9513af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options =
9523af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_UNION;
9533af6ab5fSopenharmony_ci
9543af6ab5fSopenharmony_ci    if (restrictExtends) {
9553af6ab5fSopenharmony_ci        options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
9563af6ab5fSopenharmony_ci    }
9573af6ab5fSopenharmony_ci
9583af6ab5fSopenharmony_ci    if (type != nullptr) {
9593af6ab5fSopenharmony_ci        startLoc = type->Start();
9603af6ab5fSopenharmony_ci        types.push_back(type);
9613af6ab5fSopenharmony_ci    } else {
9623af6ab5fSopenharmony_ci        startLoc = Lexer()->GetToken().Start();
9633af6ab5fSopenharmony_ci    }
9643af6ab5fSopenharmony_ci
9653af6ab5fSopenharmony_ci    while (true) {
9663af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
9673af6ab5fSopenharmony_ci            break;
9683af6ab5fSopenharmony_ci        }
9693af6ab5fSopenharmony_ci
9703af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat '|'
9713af6ab5fSopenharmony_ci
9723af6ab5fSopenharmony_ci        types.push_back(ParseTypeAnnotation(&options));
9733af6ab5fSopenharmony_ci    }
9743af6ab5fSopenharmony_ci
9753af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = types.back()->End();
9763af6ab5fSopenharmony_ci
9773af6ab5fSopenharmony_ci    auto *unionType = AllocNode<ir::TSUnionType>(std::move(types));
9783af6ab5fSopenharmony_ci    auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType);
9793af6ab5fSopenharmony_ci    unionType->SetVariable(typeVar);
9803af6ab5fSopenharmony_ci    unionType->SetRange({startLoc, endLoc});
9813af6ab5fSopenharmony_ci
9823af6ab5fSopenharmony_ci    return unionType;
9833af6ab5fSopenharmony_ci}
9843af6ab5fSopenharmony_ci
9853af6ab5fSopenharmony_ciir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends)
9863af6ab5fSopenharmony_ci{
9873af6ab5fSopenharmony_ci    ArenaVector<ir::Expression *> types(Allocator()->Adapter());
9883af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc;
9893af6ab5fSopenharmony_ci
9903af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options =
9913af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION;
9923af6ab5fSopenharmony_ci
9933af6ab5fSopenharmony_ci    if (restrictExtends) {
9943af6ab5fSopenharmony_ci        options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
9953af6ab5fSopenharmony_ci    }
9963af6ab5fSopenharmony_ci
9973af6ab5fSopenharmony_ci    if (inUnion) {
9983af6ab5fSopenharmony_ci        options |= TypeAnnotationParsingOptions::IN_UNION;
9993af6ab5fSopenharmony_ci    }
10003af6ab5fSopenharmony_ci
10013af6ab5fSopenharmony_ci    if (type != nullptr) {
10023af6ab5fSopenharmony_ci        startLoc = type->Start();
10033af6ab5fSopenharmony_ci        types.push_back(type);
10043af6ab5fSopenharmony_ci    } else {
10053af6ab5fSopenharmony_ci        startLoc = Lexer()->GetToken().Start();
10063af6ab5fSopenharmony_ci    }
10073af6ab5fSopenharmony_ci
10083af6ab5fSopenharmony_ci    while (true) {
10093af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) {
10103af6ab5fSopenharmony_ci            break;
10113af6ab5fSopenharmony_ci        }
10123af6ab5fSopenharmony_ci
10133af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat '&'
10143af6ab5fSopenharmony_ci
10153af6ab5fSopenharmony_ci        types.push_back(ParseTypeAnnotation(&options));
10163af6ab5fSopenharmony_ci    }
10173af6ab5fSopenharmony_ci
10183af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = types.back()->End();
10193af6ab5fSopenharmony_ci
10203af6ab5fSopenharmony_ci    auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types));
10213af6ab5fSopenharmony_ci    auto *typeVar =
10223af6ab5fSopenharmony_ci        varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType);
10233af6ab5fSopenharmony_ci    intersectionType->SetVariable(typeVar);
10243af6ab5fSopenharmony_ci    intersectionType->SetRange({startLoc, endLoc});
10253af6ab5fSopenharmony_ci
10263af6ab5fSopenharmony_ci    return intersectionType;
10273af6ab5fSopenharmony_ci}
10283af6ab5fSopenharmony_ci
10293af6ab5fSopenharmony_ciclass TSParser::ParseBasicTypeHelper {
10303af6ab5fSopenharmony_ci    friend ir::TypeNode *TSParser::ParseBasicType();
10313af6ab5fSopenharmony_ci
10323af6ab5fSopenharmony_ciprivate:
10333af6ab5fSopenharmony_ci    static ir::TypeNode *GetTypeAnnotationFromLiteral(TSParser *parser, lexer::Lexer *lexer)
10343af6ab5fSopenharmony_ci    {
10353af6ab5fSopenharmony_ci        switch (lexer->GetToken().KeywordType()) {
10363af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_NUMBER: {
10373af6ab5fSopenharmony_ci                if ((lexer->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
10383af6ab5fSopenharmony_ci                    auto *bigintNode = parser->AllocNode<ir::BigIntLiteral>(lexer->GetToken().BigInt());
10393af6ab5fSopenharmony_ci                    bigintNode->SetRange(lexer->GetToken().Loc());
10403af6ab5fSopenharmony_ci
10413af6ab5fSopenharmony_ci                    return parser->AllocNode<ir::TSLiteralType>(bigintNode);
10423af6ab5fSopenharmony_ci                }
10433af6ab5fSopenharmony_ci                auto *numberNode = parser->AllocNode<ir::NumberLiteral>(lexer->GetToken().GetNumber());
10443af6ab5fSopenharmony_ci                numberNode->SetRange(lexer->GetToken().Loc());
10453af6ab5fSopenharmony_ci
10463af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSLiteralType>(numberNode);
10473af6ab5fSopenharmony_ci            }
10483af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_STRING: {
10493af6ab5fSopenharmony_ci                auto *stringNode = parser->AllocNode<ir::StringLiteral>(lexer->GetToken().String());
10503af6ab5fSopenharmony_ci                stringNode->SetRange(lexer->GetToken().Loc());
10513af6ab5fSopenharmony_ci
10523af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSLiteralType>(stringNode);
10533af6ab5fSopenharmony_ci            }
10543af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_TRUE: {
10553af6ab5fSopenharmony_ci                auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(true);
10563af6ab5fSopenharmony_ci                booleanLiteral->SetRange(lexer->GetToken().Loc());
10573af6ab5fSopenharmony_ci
10583af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSLiteralType>(booleanLiteral);
10593af6ab5fSopenharmony_ci            }
10603af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_FALSE: {
10613af6ab5fSopenharmony_ci                auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(false);
10623af6ab5fSopenharmony_ci                booleanLiteral->SetRange(lexer->GetToken().Loc());
10633af6ab5fSopenharmony_ci
10643af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSLiteralType>(booleanLiteral);
10653af6ab5fSopenharmony_ci            }
10663af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_NULL: {
10673af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSNullKeyword>();
10683af6ab5fSopenharmony_ci            }
10693af6ab5fSopenharmony_ci            default: {
10703af6ab5fSopenharmony_ci                return nullptr;
10713af6ab5fSopenharmony_ci            }
10723af6ab5fSopenharmony_ci        }
10733af6ab5fSopenharmony_ci    }
10743af6ab5fSopenharmony_ci
10753af6ab5fSopenharmony_ci    static ir::TypeNode *GetTypeAnnotation(TSParser *parser, lexer::Lexer *lexer)
10763af6ab5fSopenharmony_ci    {
10773af6ab5fSopenharmony_ci        switch (lexer->GetToken().KeywordType()) {
10783af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_NUMBER:
10793af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_STRING:
10803af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_TRUE:
10813af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_FALSE:
10823af6ab5fSopenharmony_ci            case lexer::TokenType::LITERAL_NULL: {
10833af6ab5fSopenharmony_ci                return GetTypeAnnotationFromLiteral(parser, lexer);
10843af6ab5fSopenharmony_ci            }
10853af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_ANY: {
10863af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSAnyKeyword>();
10873af6ab5fSopenharmony_ci            }
10883af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_BOOLEAN: {
10893af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSBooleanKeyword>();
10903af6ab5fSopenharmony_ci            }
10913af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_NUMBER: {
10923af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSNumberKeyword>();
10933af6ab5fSopenharmony_ci            }
10943af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_STRING: {
10953af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSStringKeyword>();
10963af6ab5fSopenharmony_ci            }
10973af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_UNKNOWN: {
10983af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSUnknownKeyword>();
10993af6ab5fSopenharmony_ci            }
11003af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_VOID: {
11013af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSVoidKeyword>();
11023af6ab5fSopenharmony_ci            }
11033af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_UNDEFINED: {
11043af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSUndefinedKeyword>();
11053af6ab5fSopenharmony_ci            }
11063af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_NEVER: {
11073af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSNeverKeyword>();
11083af6ab5fSopenharmony_ci            }
11093af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_OBJECT: {
11103af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSObjectKeyword>();
11113af6ab5fSopenharmony_ci            }
11123af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_BIGINT: {
11133af6ab5fSopenharmony_ci                return parser->AllocNode<ir::TSBigintKeyword>();
11143af6ab5fSopenharmony_ci            }
11153af6ab5fSopenharmony_ci            default: {
11163af6ab5fSopenharmony_ci                parser->ThrowSyntaxError("Unexpected type");
11173af6ab5fSopenharmony_ci            }
11183af6ab5fSopenharmony_ci        }
11193af6ab5fSopenharmony_ci    }
11203af6ab5fSopenharmony_ci};
11213af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseBasicType()
11223af6ab5fSopenharmony_ci{
11233af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) {
11243af6ab5fSopenharmony_ci        Lexer()->NextToken();
11253af6ab5fSopenharmony_ci
11263af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) {
11273af6ab5fSopenharmony_ci            ThrowSyntaxError("Type expected");
11283af6ab5fSopenharmony_ci        }
11293af6ab5fSopenharmony_ci    }
11303af6ab5fSopenharmony_ci
11313af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = ParseBasicTypeHelper::GetTypeAnnotation(this, Lexer());
11323af6ab5fSopenharmony_ci
11333af6ab5fSopenharmony_ci    typeAnnotation->SetRange(Lexer()->GetToken().Loc());
11343af6ab5fSopenharmony_ci
11353af6ab5fSopenharmony_ci    Lexer()->NextToken();
11363af6ab5fSopenharmony_ci    return typeAnnotation;
11373af6ab5fSopenharmony_ci}
11383af6ab5fSopenharmony_ci
11393af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError)
11403af6ab5fSopenharmony_ci{
11413af6ab5fSopenharmony_ci    if (typeAnnotation != nullptr) {
11423af6ab5fSopenharmony_ci        return nullptr;
11433af6ab5fSopenharmony_ci    }
11443af6ab5fSopenharmony_ci
11453af6ab5fSopenharmony_ci    lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
11463af6ab5fSopenharmony_ci
11473af6ab5fSopenharmony_ci    bool abstractConstructor = false;
11483af6ab5fSopenharmony_ci
11493af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
11503af6ab5fSopenharmony_ci        abstractConstructor = true;
11513af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'abstract'
11523af6ab5fSopenharmony_ci    }
11533af6ab5fSopenharmony_ci
11543af6ab5fSopenharmony_ci    bool isConstructionType = false;
11553af6ab5fSopenharmony_ci
11563af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW) {
11573af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'new'
11583af6ab5fSopenharmony_ci        isConstructionType = true;
11593af6ab5fSopenharmony_ci
11603af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
11613af6ab5fSopenharmony_ci            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
11623af6ab5fSopenharmony_ci            ThrowSyntaxError("'(' expected");
11633af6ab5fSopenharmony_ci        }
11643af6ab5fSopenharmony_ci    }
11653af6ab5fSopenharmony_ci
11663af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) {
11673af6ab5fSopenharmony_ci        return ParseFunctionType(typeStart, isConstructionType, throwError, abstractConstructor);
11683af6ab5fSopenharmony_ci    }
11693af6ab5fSopenharmony_ci
11703af6ab5fSopenharmony_ci    const auto startPos = Lexer()->Save();
11713af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
11723af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '('
11733af6ab5fSopenharmony_ci
11743af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
11753af6ab5fSopenharmony_ci    ir::TypeNode *type = ParseTypeAnnotation(&options);
11763af6ab5fSopenharmony_ci
11773af6ab5fSopenharmony_ci    if (type == nullptr) {
11783af6ab5fSopenharmony_ci        Lexer()->Rewind(startPos);
11793af6ab5fSopenharmony_ci        return ParseFunctionType(typeStart, false, throwError);
11803af6ab5fSopenharmony_ci    }
11813af6ab5fSopenharmony_ci
11823af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
11833af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
11843af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
11853af6ab5fSopenharmony_ci        Lexer()->Rewind(startPos);
11863af6ab5fSopenharmony_ci        return ParseFunctionType(typeStart, false, throwError);
11873af6ab5fSopenharmony_ci    }
11883af6ab5fSopenharmony_ci
11893af6ab5fSopenharmony_ci    if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
11903af6ab5fSopenharmony_ci        ThrowSyntaxError("')' expected");
11913af6ab5fSopenharmony_ci    }
11923af6ab5fSopenharmony_ci
11933af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = Lexer()->GetToken().End();
11943af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ')'
11953af6ab5fSopenharmony_ci
11963af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
11973af6ab5fSopenharmony_ci        Lexer()->Rewind(startPos);
11983af6ab5fSopenharmony_ci
11993af6ab5fSopenharmony_ci        return ParseFunctionType(typeStart, false, throwError);
12003af6ab5fSopenharmony_ci    }
12013af6ab5fSopenharmony_ci
12023af6ab5fSopenharmony_ci    auto *result = AllocNode<ir::TSParenthesizedType>(type);
12033af6ab5fSopenharmony_ci    result->SetRange({typeStart, endLoc});
12043af6ab5fSopenharmony_ci
12053af6ab5fSopenharmony_ci    return result;
12063af6ab5fSopenharmony_ci}
12073af6ab5fSopenharmony_ci
12083af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseFunctionType(lexer::SourcePosition startLoc, bool isConstructionType, bool throwError,
12093af6ab5fSopenharmony_ci                                          bool abstractConstructor)
12103af6ab5fSopenharmony_ci{
12113af6ab5fSopenharmony_ci    ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
12123af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
12133af6ab5fSopenharmony_ci        auto options = throwError ? TypeAnnotationParsingOptions::REPORT_ERROR : TypeAnnotationParsingOptions::NO_OPTS;
12143af6ab5fSopenharmony_ci        typeParamDecl = ParseTypeParameterDeclaration(&options);
12153af6ab5fSopenharmony_ci
12163af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
12173af6ab5fSopenharmony_ci            if (!throwError) {
12183af6ab5fSopenharmony_ci                return nullptr;
12193af6ab5fSopenharmony_ci            }
12203af6ab5fSopenharmony_ci
12213af6ab5fSopenharmony_ci            ThrowSyntaxError("'(' expected");
12223af6ab5fSopenharmony_ci        }
12233af6ab5fSopenharmony_ci    }
12243af6ab5fSopenharmony_ci
12253af6ab5fSopenharmony_ci    auto params = ParseFunctionParams();
12263af6ab5fSopenharmony_ci
12273af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
12283af6ab5fSopenharmony_ci        ThrowSyntaxError("'=>' expected");
12293af6ab5fSopenharmony_ci    }
12303af6ab5fSopenharmony_ci
12313af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '=>'
12323af6ab5fSopenharmony_ci
12333af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options =
12343af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
12353af6ab5fSopenharmony_ci    ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
12363af6ab5fSopenharmony_ci
12373af6ab5fSopenharmony_ci    ir::TypeNode *funcType = nullptr;
12383af6ab5fSopenharmony_ci
12393af6ab5fSopenharmony_ci    ir::FunctionSignature signature(typeParamDecl, std::move(params), returnTypeAnnotation);
12403af6ab5fSopenharmony_ci
12413af6ab5fSopenharmony_ci    if (isConstructionType) {
12423af6ab5fSopenharmony_ci        funcType = AllocNode<ir::TSConstructorType>(std::move(signature), abstractConstructor);
12433af6ab5fSopenharmony_ci    } else {
12443af6ab5fSopenharmony_ci        funcType = AllocNode<ir::TSFunctionType>(std::move(signature));
12453af6ab5fSopenharmony_ci    }
12463af6ab5fSopenharmony_ci
12473af6ab5fSopenharmony_ci    funcType->SetRange({startLoc, returnTypeAnnotation->End()});
12483af6ab5fSopenharmony_ci
12493af6ab5fSopenharmony_ci    return funcType;
12503af6ab5fSopenharmony_ci}
12513af6ab5fSopenharmony_ci
12523af6ab5fSopenharmony_ciclass TSParser::ParseTypeAnnotationElementHelper {
12533af6ab5fSopenharmony_ci    friend ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation,
12543af6ab5fSopenharmony_ci                                                              TypeAnnotationParsingOptions *options);
12553af6ab5fSopenharmony_ci
12563af6ab5fSopenharmony_ciprivate:
12573af6ab5fSopenharmony_ci    static ir::TypeNode *ParseKeywordTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation,
12583af6ab5fSopenharmony_ci                                            TypeAnnotationParsingOptions *options)
12593af6ab5fSopenharmony_ci    {
12603af6ab5fSopenharmony_ci        switch (lexer->GetToken().Type()) {
12613af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_NEW: {
12623af6ab5fSopenharmony_ci                return parser->ParseParenthesizedOrFunctionType(
12633af6ab5fSopenharmony_ci                    typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
12643af6ab5fSopenharmony_ci            }
12653af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_TYPEOF: {
12663af6ab5fSopenharmony_ci                if (typeAnnotation != nullptr) {
12673af6ab5fSopenharmony_ci                    break;
12683af6ab5fSopenharmony_ci                }
12693af6ab5fSopenharmony_ci
12703af6ab5fSopenharmony_ci                return parser->ParseTypeReferenceOrQuery(true);
12713af6ab5fSopenharmony_ci            }
12723af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_IMPORT: {
12733af6ab5fSopenharmony_ci                if (typeAnnotation != nullptr) {
12743af6ab5fSopenharmony_ci                    break;
12753af6ab5fSopenharmony_ci                }
12763af6ab5fSopenharmony_ci                return parser->ParseImportType(lexer->GetToken().Start());
12773af6ab5fSopenharmony_ci            }
12783af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_CONST: {
12793af6ab5fSopenharmony_ci                if (((*options) & TypeAnnotationParsingOptions::ALLOW_CONST) == 0) {
12803af6ab5fSopenharmony_ci                    break;
12813af6ab5fSopenharmony_ci                }
12823af6ab5fSopenharmony_ci
12833af6ab5fSopenharmony_ci                (*options) &= ~TypeAnnotationParsingOptions::ALLOW_CONST;
12843af6ab5fSopenharmony_ci                return parser->ParseConstExpression();
12853af6ab5fSopenharmony_ci            }
12863af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_EXTENDS: {
12873af6ab5fSopenharmony_ci                if (((*options) &
12883af6ab5fSopenharmony_ci                     (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) {
12893af6ab5fSopenharmony_ci                    break;
12903af6ab5fSopenharmony_ci                }
12913af6ab5fSopenharmony_ci
12923af6ab5fSopenharmony_ci                if (typeAnnotation == nullptr) {
12933af6ab5fSopenharmony_ci                    return parser->ParseIdentifierReference();
12943af6ab5fSopenharmony_ci                }
12953af6ab5fSopenharmony_ci
12963af6ab5fSopenharmony_ci                return parser->ParseConditionalType(typeAnnotation,
12973af6ab5fSopenharmony_ci                                                    ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
12983af6ab5fSopenharmony_ci            }
12993af6ab5fSopenharmony_ci            case lexer::TokenType::KEYW_THIS: {
13003af6ab5fSopenharmony_ci                return parser->ParseThisTypeOrTypePredicate(
13013af6ab5fSopenharmony_ci                    typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0,
13023af6ab5fSopenharmony_ci                    ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
13033af6ab5fSopenharmony_ci            }
13043af6ab5fSopenharmony_ci            default: {
13053af6ab5fSopenharmony_ci                break;
13063af6ab5fSopenharmony_ci            }
13073af6ab5fSopenharmony_ci        }
13083af6ab5fSopenharmony_ci        return nullptr;
13093af6ab5fSopenharmony_ci    }
13103af6ab5fSopenharmony_ci
13113af6ab5fSopenharmony_ci    static ir::TypeNode *ParsePunctuatorTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation,
13123af6ab5fSopenharmony_ci                                               TypeAnnotationParsingOptions *options)
13133af6ab5fSopenharmony_ci    {
13143af6ab5fSopenharmony_ci        switch (lexer->GetToken().Type()) {
13153af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
13163af6ab5fSopenharmony_ci                if (((*options) &
13173af6ab5fSopenharmony_ci                     (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) {
13183af6ab5fSopenharmony_ci                    break;
13193af6ab5fSopenharmony_ci                }
13203af6ab5fSopenharmony_ci
13213af6ab5fSopenharmony_ci                return parser->ParseUnionType(typeAnnotation,
13223af6ab5fSopenharmony_ci                                              ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
13233af6ab5fSopenharmony_ci            }
13243af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
13253af6ab5fSopenharmony_ci                if (((*options) & TypeAnnotationParsingOptions::IN_INTERSECTION) != 0) {
13263af6ab5fSopenharmony_ci                    break;
13273af6ab5fSopenharmony_ci                }
13283af6ab5fSopenharmony_ci
13293af6ab5fSopenharmony_ci                return parser->ParseIntersectionType(
13303af6ab5fSopenharmony_ci                    typeAnnotation, ((*options) & TypeAnnotationParsingOptions::IN_UNION) != 0,
13313af6ab5fSopenharmony_ci                    ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
13323af6ab5fSopenharmony_ci            }
13333af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_LESS_THAN:
13343af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
13353af6ab5fSopenharmony_ci                return parser->ParseParenthesizedOrFunctionType(
13363af6ab5fSopenharmony_ci                    typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
13373af6ab5fSopenharmony_ci            }
13383af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
13393af6ab5fSopenharmony_ci                if (typeAnnotation != nullptr) {
13403af6ab5fSopenharmony_ci                    if (lexer->Lookahead() == lexer::LEX_CHAR_RIGHT_SQUARE) {
13413af6ab5fSopenharmony_ci                        return parser->ParseArrayType(typeAnnotation);
13423af6ab5fSopenharmony_ci                    }
13433af6ab5fSopenharmony_ci
13443af6ab5fSopenharmony_ci                    return parser->ParseIndexAccessType(typeAnnotation);
13453af6ab5fSopenharmony_ci                }
13463af6ab5fSopenharmony_ci
13473af6ab5fSopenharmony_ci                return parser->ParseTupleType();
13483af6ab5fSopenharmony_ci            }
13493af6ab5fSopenharmony_ci            case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
13503af6ab5fSopenharmony_ci                return parser->ParseTypeLiteralOrMappedType(typeAnnotation);
13513af6ab5fSopenharmony_ci            }
13523af6ab5fSopenharmony_ci            default: {
13533af6ab5fSopenharmony_ci                break;
13543af6ab5fSopenharmony_ci            }
13553af6ab5fSopenharmony_ci        }
13563af6ab5fSopenharmony_ci
13573af6ab5fSopenharmony_ci        return nullptr;
13583af6ab5fSopenharmony_ci    }
13593af6ab5fSopenharmony_ci};
13603af6ab5fSopenharmony_ci
13613af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, TypeAnnotationParsingOptions *options)
13623af6ab5fSopenharmony_ci{
13633af6ab5fSopenharmony_ci    switch (Lexer()->GetToken().Type()) {
13643af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MINUS:
13653af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_NUMBER:
13663af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_STRING:
13673af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_FALSE:
13683af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_TRUE:
13693af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_NULL:
13703af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_VOID: {
13713af6ab5fSopenharmony_ci            if (typeAnnotation != nullptr) {
13723af6ab5fSopenharmony_ci                break;
13733af6ab5fSopenharmony_ci            }
13743af6ab5fSopenharmony_ci
13753af6ab5fSopenharmony_ci            return ParseBasicType();
13763af6ab5fSopenharmony_ci        }
13773af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_IDENT: {
13783af6ab5fSopenharmony_ci            if (IsStartOfAbstractConstructorType()) {
13793af6ab5fSopenharmony_ci                return ParseParenthesizedOrFunctionType(typeAnnotation,
13803af6ab5fSopenharmony_ci                                                        ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
13813af6ab5fSopenharmony_ci            }
13823af6ab5fSopenharmony_ci
13833af6ab5fSopenharmony_ci            return ParseTypeReferenceOrTypePredicate(
13843af6ab5fSopenharmony_ci                typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0);
13853af6ab5fSopenharmony_ci        }
13863af6ab5fSopenharmony_ci        default: {
13873af6ab5fSopenharmony_ci            ir::TypeNode *parsedValue =
13883af6ab5fSopenharmony_ci                ParseTypeAnnotationElementHelper::ParseKeywordTokens(this, Lexer(), typeAnnotation, options);
13893af6ab5fSopenharmony_ci            if (parsedValue != nullptr) {
13903af6ab5fSopenharmony_ci                return parsedValue;
13913af6ab5fSopenharmony_ci            }
13923af6ab5fSopenharmony_ci
13933af6ab5fSopenharmony_ci            parsedValue =
13943af6ab5fSopenharmony_ci                ParseTypeAnnotationElementHelper::ParsePunctuatorTokens(this, Lexer(), typeAnnotation, options);
13953af6ab5fSopenharmony_ci            if (parsedValue != nullptr) {
13963af6ab5fSopenharmony_ci                return parsedValue;
13973af6ab5fSopenharmony_ci            }
13983af6ab5fSopenharmony_ci
13993af6ab5fSopenharmony_ci            break;
14003af6ab5fSopenharmony_ci        }
14013af6ab5fSopenharmony_ci    }
14023af6ab5fSopenharmony_ci
14033af6ab5fSopenharmony_ci    if (typeAnnotation == nullptr && (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0)) {
14043af6ab5fSopenharmony_ci        ThrowSyntaxError("Type expected");
14053af6ab5fSopenharmony_ci    }
14063af6ab5fSopenharmony_ci
14073af6ab5fSopenharmony_ci    return nullptr;
14083af6ab5fSopenharmony_ci}
14093af6ab5fSopenharmony_ci
14103af6ab5fSopenharmony_cibool TSParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
14113af6ab5fSopenharmony_ci                                                 const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
14123af6ab5fSopenharmony_ci{
14133af6ab5fSopenharmony_ci    if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
14143af6ab5fSopenharmony_ci        (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
14153af6ab5fSopenharmony_ci        return true;
14163af6ab5fSopenharmony_ci    }
14173af6ab5fSopenharmony_ci
14183af6ab5fSopenharmony_ci    const auto savedPos = Lexer()->Save();
14193af6ab5fSopenharmony_ci
14203af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
14213af6ab5fSopenharmony_ci        Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
14223af6ab5fSopenharmony_ci    }
14233af6ab5fSopenharmony_ci
14243af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
14253af6ab5fSopenharmony_ci    ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
14263af6ab5fSopenharmony_ci
14273af6ab5fSopenharmony_ci    if (typeParams == nullptr) {
14283af6ab5fSopenharmony_ci        Lexer()->Rewind(savedPos);
14293af6ab5fSopenharmony_ci        return true;
14303af6ab5fSopenharmony_ci    }
14313af6ab5fSopenharmony_ci
14323af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
14333af6ab5fSopenharmony_ci        ThrowSyntaxError("'(' or '`' expected");
14343af6ab5fSopenharmony_ci    }
14353af6ab5fSopenharmony_ci
14363af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
14373af6ab5fSopenharmony_ci        if (!ignoreCallExpression) {
14383af6ab5fSopenharmony_ci            *returnExpression = ParseCallExpression(*returnExpression, false);
14393af6ab5fSopenharmony_ci            (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
14403af6ab5fSopenharmony_ci            return false;
14413af6ab5fSopenharmony_ci        }
14423af6ab5fSopenharmony_ci
14433af6ab5fSopenharmony_ci        return true;
14443af6ab5fSopenharmony_ci    }
14453af6ab5fSopenharmony_ci
14463af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
14473af6ab5fSopenharmony_ci        ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
14483af6ab5fSopenharmony_ci        lexer::SourcePosition endLoc = propertyNode->End();
14493af6ab5fSopenharmony_ci
14503af6ab5fSopenharmony_ci        *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
14513af6ab5fSopenharmony_ci        (*returnExpression)->SetRange({startLoc, endLoc});
14523af6ab5fSopenharmony_ci        return false;
14533af6ab5fSopenharmony_ci    }
14543af6ab5fSopenharmony_ci
14553af6ab5fSopenharmony_ci    Lexer()->Rewind(savedPos);
14563af6ab5fSopenharmony_ci    return true;
14573af6ab5fSopenharmony_ci}
14583af6ab5fSopenharmony_ci
14593af6ab5fSopenharmony_cibool TSParser::IsNamedFunctionExpression()
14603af6ab5fSopenharmony_ci{
14613af6ab5fSopenharmony_ci    return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
14623af6ab5fSopenharmony_ci           Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
14633af6ab5fSopenharmony_ci}
14643af6ab5fSopenharmony_ci
14653af6ab5fSopenharmony_ciir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
14663af6ab5fSopenharmony_ci{
14673af6ab5fSopenharmony_ci    auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
14683af6ab5fSopenharmony_ci    identNode->SetReference();
14693af6ab5fSopenharmony_ci    identNode->SetRange(Lexer()->GetToken().Loc());
14703af6ab5fSopenharmony_ci
14713af6ab5fSopenharmony_ci    Lexer()->NextToken();
14723af6ab5fSopenharmony_ci
14733af6ab5fSopenharmony_ci    ParsePotentialOptionalFunctionParameter(identNode);
14743af6ab5fSopenharmony_ci
14753af6ab5fSopenharmony_ci    return identNode;
14763af6ab5fSopenharmony_ci}
14773af6ab5fSopenharmony_ci
14783af6ab5fSopenharmony_ciir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature)
14793af6ab5fSopenharmony_ci{
14803af6ab5fSopenharmony_ci    lexer::SourcePosition memberStartLoc = Lexer()->GetToken().Start();
14813af6ab5fSopenharmony_ci
14823af6ab5fSopenharmony_ci    if (!isCallSignature) {
14833af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'new' keyword
14843af6ab5fSopenharmony_ci    }
14853af6ab5fSopenharmony_ci
14863af6ab5fSopenharmony_ci    ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
14873af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
14883af6ab5fSopenharmony_ci        auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
14893af6ab5fSopenharmony_ci        typeParamDecl = ParseTypeParameterDeclaration(&options);
14903af6ab5fSopenharmony_ci
14913af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
14923af6ab5fSopenharmony_ci            ThrowSyntaxError("'(' expected");
14933af6ab5fSopenharmony_ci        }
14943af6ab5fSopenharmony_ci    }
14953af6ab5fSopenharmony_ci
14963af6ab5fSopenharmony_ci    FunctionParameterContext funcParamContext(&GetContext());
14973af6ab5fSopenharmony_ci    auto params = ParseFunctionParams();
14983af6ab5fSopenharmony_ci
14993af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = nullptr;
15003af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
15013af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
15023af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options =
15033af6ab5fSopenharmony_ci            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
15043af6ab5fSopenharmony_ci        typeAnnotation = ParseTypeAnnotation(&options);
15053af6ab5fSopenharmony_ci    }
15063af6ab5fSopenharmony_ci
15073af6ab5fSopenharmony_ci    auto kind = isCallSignature ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE
15083af6ab5fSopenharmony_ci                                : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE;
15093af6ab5fSopenharmony_ci    auto *signatureMember = AllocNode<ir::TSSignatureDeclaration>(
15103af6ab5fSopenharmony_ci        kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation));
15113af6ab5fSopenharmony_ci    signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()});
15123af6ab5fSopenharmony_ci
15133af6ab5fSopenharmony_ci    return signatureMember;
15143af6ab5fSopenharmony_ci}
15153af6ab5fSopenharmony_ci
15163af6ab5fSopenharmony_cibool TSParser::IsPotentiallyIndexSignature()
15173af6ab5fSopenharmony_ci{
15183af6ab5fSopenharmony_ci    const auto savedPos = Lexer()->Save();
15193af6ab5fSopenharmony_ci
15203af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '['
15213af6ab5fSopenharmony_ci
15223af6ab5fSopenharmony_ci    bool isIndexSignature =
15233af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON;
15243af6ab5fSopenharmony_ci
15253af6ab5fSopenharmony_ci    Lexer()->Rewind(savedPos);
15263af6ab5fSopenharmony_ci
15273af6ab5fSopenharmony_ci    return isIndexSignature;
15283af6ab5fSopenharmony_ci}
15293af6ab5fSopenharmony_ci
15303af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments)
15313af6ab5fSopenharmony_ciir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
15323af6ab5fSopenharmony_ci{
15333af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat '['
15343af6ab5fSopenharmony_ci
15353af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT);
15363af6ab5fSopenharmony_ci    auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
15373af6ab5fSopenharmony_ci    key->SetRange(Lexer()->GetToken().Loc());
15383af6ab5fSopenharmony_ci
15393af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat key
15403af6ab5fSopenharmony_ci
15413af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON);
15423af6ab5fSopenharmony_ci
15433af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ':'
15443af6ab5fSopenharmony_ci
15453af6ab5fSopenharmony_ci    TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
15463af6ab5fSopenharmony_ci    ir::TypeNode *keyType = ParseTypeAnnotation(&options);
15473af6ab5fSopenharmony_ci
15483af6ab5fSopenharmony_ci    if (!keyType->IsTSNumberKeyword() && !keyType->IsTSStringKeyword()) {
15493af6ab5fSopenharmony_ci        ThrowSyntaxError(
15503af6ab5fSopenharmony_ci            "An index signature parameter type must be either "
15513af6ab5fSopenharmony_ci            "'string' or 'number'");
15523af6ab5fSopenharmony_ci    }
15533af6ab5fSopenharmony_ci
15543af6ab5fSopenharmony_ci    key->SetTsTypeAnnotation(keyType);
15553af6ab5fSopenharmony_ci
15563af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
15573af6ab5fSopenharmony_ci        ThrowSyntaxError("']' expected.");
15583af6ab5fSopenharmony_ci    }
15593af6ab5fSopenharmony_ci
15603af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ']'
15613af6ab5fSopenharmony_ci
15623af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
15633af6ab5fSopenharmony_ci        ThrowSyntaxError("An index signature must have a type annotation.");
15643af6ab5fSopenharmony_ci    }
15653af6ab5fSopenharmony_ci
15663af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat ':'
15673af6ab5fSopenharmony_ci
15683af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
15693af6ab5fSopenharmony_ci
15703af6ab5fSopenharmony_ci    auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
15713af6ab5fSopenharmony_ci    indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
15723af6ab5fSopenharmony_ci    return indexSignature;
15733af6ab5fSopenharmony_ci}
15743af6ab5fSopenharmony_ci
15753af6ab5fSopenharmony_cistd::tuple<ir::Expression *, bool> TSParser::ParseInterfacePropertyKey()
15763af6ab5fSopenharmony_ci{
15773af6ab5fSopenharmony_ci    ir::Expression *key = nullptr;
15783af6ab5fSopenharmony_ci    bool isComputed = false;
15793af6ab5fSopenharmony_ci
15803af6ab5fSopenharmony_ci    switch (Lexer()->GetToken().Type()) {
15813af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_IDENT: {
15823af6ab5fSopenharmony_ci            const util::StringView &ident = Lexer()->GetToken().Ident();
15833af6ab5fSopenharmony_ci            key = AllocNode<ir::Identifier>(ident, Allocator());
15843af6ab5fSopenharmony_ci            key->SetRange(Lexer()->GetToken().Loc());
15853af6ab5fSopenharmony_ci            break;
15863af6ab5fSopenharmony_ci        }
15873af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_STRING: {
15883af6ab5fSopenharmony_ci            const util::StringView &string = Lexer()->GetToken().String();
15893af6ab5fSopenharmony_ci            key = AllocNode<ir::StringLiteral>(string);
15903af6ab5fSopenharmony_ci            key->SetRange(Lexer()->GetToken().Loc());
15913af6ab5fSopenharmony_ci            break;
15923af6ab5fSopenharmony_ci        }
15933af6ab5fSopenharmony_ci        case lexer::TokenType::LITERAL_NUMBER: {
15943af6ab5fSopenharmony_ci            if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
15953af6ab5fSopenharmony_ci                key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
15963af6ab5fSopenharmony_ci            } else {
15973af6ab5fSopenharmony_ci                key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
15983af6ab5fSopenharmony_ci            }
15993af6ab5fSopenharmony_ci
16003af6ab5fSopenharmony_ci            key->SetRange(Lexer()->GetToken().Loc());
16013af6ab5fSopenharmony_ci            break;
16023af6ab5fSopenharmony_ci        }
16033af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
16043af6ab5fSopenharmony_ci            Lexer()->NextToken();  // eat left square bracket
16053af6ab5fSopenharmony_ci
16063af6ab5fSopenharmony_ci            key = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
16073af6ab5fSopenharmony_ci            isComputed = true;
16083af6ab5fSopenharmony_ci
16093af6ab5fSopenharmony_ci            if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
16103af6ab5fSopenharmony_ci                ThrowSyntaxError("Unexpected token, expected ']'");
16113af6ab5fSopenharmony_ci            }
16123af6ab5fSopenharmony_ci            break;
16133af6ab5fSopenharmony_ci        }
16143af6ab5fSopenharmony_ci        default: {
16153af6ab5fSopenharmony_ci            ThrowSyntaxError("Unexpected token in property key");
16163af6ab5fSopenharmony_ci        }
16173af6ab5fSopenharmony_ci    }
16183af6ab5fSopenharmony_ci
16193af6ab5fSopenharmony_ci    Lexer()->NextToken();
16203af6ab5fSopenharmony_ci    return {key, isComputed};
16213af6ab5fSopenharmony_ci}
16223af6ab5fSopenharmony_ci
16233af6ab5fSopenharmony_civoid TSParser::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, varbinder::VariableFlags flags)
16243af6ab5fSopenharmony_ci{
16253af6ab5fSopenharmony_ci    varbinder::Variable *propVar = nullptr;
16263af6ab5fSopenharmony_ci    bool isMethod = (flags & varbinder::VariableFlags::METHOD) != 0;
16273af6ab5fSopenharmony_ci    util::StringView propName = "__computed";
16283af6ab5fSopenharmony_ci
16293af6ab5fSopenharmony_ci    switch (key->Type()) {
16303af6ab5fSopenharmony_ci        case ir::AstNodeType::IDENTIFIER: {
16313af6ab5fSopenharmony_ci            propName = key->AsIdentifier()->Name();
16323af6ab5fSopenharmony_ci            break;
16333af6ab5fSopenharmony_ci        }
16343af6ab5fSopenharmony_ci        case ir::AstNodeType::NUMBER_LITERAL: {
16353af6ab5fSopenharmony_ci            propName = key->AsNumberLiteral()->Str();
16363af6ab5fSopenharmony_ci            flags |= varbinder::VariableFlags::NUMERIC_NAME;
16373af6ab5fSopenharmony_ci            break;
16383af6ab5fSopenharmony_ci        }
16393af6ab5fSopenharmony_ci        case ir::AstNodeType::STRING_LITERAL: {
16403af6ab5fSopenharmony_ci            propName = key->AsStringLiteral()->Str();
16413af6ab5fSopenharmony_ci            break;
16423af6ab5fSopenharmony_ci        }
16433af6ab5fSopenharmony_ci        default: {
16443af6ab5fSopenharmony_ci            flags |= varbinder::VariableFlags::COMPUTED;
16453af6ab5fSopenharmony_ci            break;
16463af6ab5fSopenharmony_ci        }
16473af6ab5fSopenharmony_ci    }
16483af6ab5fSopenharmony_ci
16493af6ab5fSopenharmony_ci    propVar = isMethod ? varbinder::Scope::CreateVar<varbinder::MethodDecl>(Allocator(), propName, flags, node)
16503af6ab5fSopenharmony_ci                       : varbinder::Scope::CreateVar<varbinder::PropertyDecl>(Allocator(), propName, flags, node);
16513af6ab5fSopenharmony_ci
16523af6ab5fSopenharmony_ci    node->SetVariable(propVar);
16533af6ab5fSopenharmony_ci}
16543af6ab5fSopenharmony_ci
16553af6ab5fSopenharmony_ciir::AstNode *TSParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
16563af6ab5fSopenharmony_ci{
16573af6ab5fSopenharmony_ci    auto [key, isComputed] = ParseInterfacePropertyKey();
16583af6ab5fSopenharmony_ci    varbinder::VariableFlags flags = isReadonly ? varbinder::VariableFlags::READONLY : varbinder::VariableFlags::NONE;
16593af6ab5fSopenharmony_ci
16603af6ab5fSopenharmony_ci    bool isOptional = false;
16613af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
16623af6ab5fSopenharmony_ci        isOptional = true;
16633af6ab5fSopenharmony_ci        flags |= varbinder::VariableFlags::OPTIONAL;
16643af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat '?'
16653af6ab5fSopenharmony_ci    }
16663af6ab5fSopenharmony_ci
16673af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
16683af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
16693af6ab5fSopenharmony_ci        if (isReadonly) {
16703af6ab5fSopenharmony_ci            ThrowSyntaxError("'readonly' modifier can only appear on a property declaration or index signature.",
16713af6ab5fSopenharmony_ci                             startLoc);
16723af6ab5fSopenharmony_ci        }
16733af6ab5fSopenharmony_ci
16743af6ab5fSopenharmony_ci        ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
16753af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
16763af6ab5fSopenharmony_ci            auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
16773af6ab5fSopenharmony_ci            typeParamDecl = ParseTypeParameterDeclaration(&options);
16783af6ab5fSopenharmony_ci        }
16793af6ab5fSopenharmony_ci
16803af6ab5fSopenharmony_ci        ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, false);
16813af6ab5fSopenharmony_ci
16823af6ab5fSopenharmony_ci        FunctionParameterContext funcParamContext(&GetContext());
16833af6ab5fSopenharmony_ci        auto params = ParseFunctionParams();
16843af6ab5fSopenharmony_ci
16853af6ab5fSopenharmony_ci        ir::TypeNode *returnType = nullptr;
16863af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
16873af6ab5fSopenharmony_ci            Lexer()->NextToken();  // eat ':'
16883af6ab5fSopenharmony_ci            TypeAnnotationParsingOptions options =
16893af6ab5fSopenharmony_ci                TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
16903af6ab5fSopenharmony_ci            returnType = ParseTypeAnnotation(&options);
16913af6ab5fSopenharmony_ci        }
16923af6ab5fSopenharmony_ci
16933af6ab5fSopenharmony_ci        auto *methodSignature = AllocNode<ir::TSMethodSignature>(
16943af6ab5fSopenharmony_ci            key, ir::FunctionSignature(typeParamDecl, std::move(params), returnType), isComputed, isOptional);
16953af6ab5fSopenharmony_ci        CreateTSVariableForProperty(methodSignature, key, flags | varbinder::VariableFlags::METHOD);
16963af6ab5fSopenharmony_ci        methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
16973af6ab5fSopenharmony_ci        return methodSignature;
16983af6ab5fSopenharmony_ci    }
16993af6ab5fSopenharmony_ci
17003af6ab5fSopenharmony_ci    ir::TypeNode *typeAnnotation = nullptr;
17013af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
17023af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
17033af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options =
17043af6ab5fSopenharmony_ci            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
17053af6ab5fSopenharmony_ci        typeAnnotation = ParseTypeAnnotation(&options);
17063af6ab5fSopenharmony_ci    }
17073af6ab5fSopenharmony_ci
17083af6ab5fSopenharmony_ci    auto *propertySignature =
17093af6ab5fSopenharmony_ci        AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, isOptional, isReadonly);
17103af6ab5fSopenharmony_ci    CreateTSVariableForProperty(propertySignature, key, flags | varbinder::VariableFlags::PROPERTY);
17113af6ab5fSopenharmony_ci    propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
17123af6ab5fSopenharmony_ci    return propertySignature;
17133af6ab5fSopenharmony_ci}
17143af6ab5fSopenharmony_ci
17153af6ab5fSopenharmony_ciir::AstNode *TSParser::ParseTypeLiteralOrInterfaceMember()
17163af6ab5fSopenharmony_ci{
17173af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
17183af6ab5fSopenharmony_ci        ThrowSyntaxError("Decorators are not allowed here");
17193af6ab5fSopenharmony_ci    }
17203af6ab5fSopenharmony_ci
17213af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
17223af6ab5fSopenharmony_ci        Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
17233af6ab5fSopenharmony_ci        return ParseSignatureMember(true);
17243af6ab5fSopenharmony_ci    }
17253af6ab5fSopenharmony_ci
17263af6ab5fSopenharmony_ci    char32_t nextCp = Lexer()->Lookahead();
17273af6ab5fSopenharmony_ci    if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW &&
17283af6ab5fSopenharmony_ci        (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN)) {
17293af6ab5fSopenharmony_ci        return ParseSignatureMember(false);
17303af6ab5fSopenharmony_ci    }
17313af6ab5fSopenharmony_ci
17323af6ab5fSopenharmony_ci    lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
17333af6ab5fSopenharmony_ci    bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
17343af6ab5fSopenharmony_ci                      nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON &&
17353af6ab5fSopenharmony_ci                      nextCp != lexer::LEX_CHAR_COMMA;
17363af6ab5fSopenharmony_ci    if (isReadonly) {
17373af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat 'readonly"
17383af6ab5fSopenharmony_ci    }
17393af6ab5fSopenharmony_ci
17403af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
17413af6ab5fSopenharmony_ci        IsPotentiallyIndexSignature()) {
17423af6ab5fSopenharmony_ci        return ParseIndexSignature(startLoc, isReadonly);
17433af6ab5fSopenharmony_ci    }
17443af6ab5fSopenharmony_ci
17453af6ab5fSopenharmony_ci    return ParsePropertyOrMethodSignature(startLoc, isReadonly);
17463af6ab5fSopenharmony_ci}
17473af6ab5fSopenharmony_ci
17483af6ab5fSopenharmony_civoid TSParser::ValidateFunctionParam(const ArenaVector<ir::Expression *> &params, const ir::Expression *parameter,
17493af6ab5fSopenharmony_ci                                     bool *seenOptional)
17503af6ab5fSopenharmony_ci{
17513af6ab5fSopenharmony_ci    if (!parameter->IsIdentifier()) {
17523af6ab5fSopenharmony_ci        GetContext().Status() |= ParserStatus::HAS_COMPLEX_PARAM;
17533af6ab5fSopenharmony_ci        if (!parameter->IsRestElement()) {
17543af6ab5fSopenharmony_ci            return;
17553af6ab5fSopenharmony_ci        }
17563af6ab5fSopenharmony_ci
17573af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
17583af6ab5fSopenharmony_ci            ThrowSyntaxError("A rest parameter must be last in parameter list");
17593af6ab5fSopenharmony_ci        }
17603af6ab5fSopenharmony_ci        return;
17613af6ab5fSopenharmony_ci    }
17623af6ab5fSopenharmony_ci
17633af6ab5fSopenharmony_ci    bool currentIsOptional = parameter->AsIdentifier()->IsOptional();
17643af6ab5fSopenharmony_ci    if (*seenOptional && !currentIsOptional) {
17653af6ab5fSopenharmony_ci        ThrowSyntaxError("A required parameter cannot follow an optional parameter");
17663af6ab5fSopenharmony_ci    }
17673af6ab5fSopenharmony_ci
17683af6ab5fSopenharmony_ci    *seenOptional |= currentIsOptional;
17693af6ab5fSopenharmony_ci    const util::StringView &paramName = parameter->AsIdentifier()->Name();
17703af6ab5fSopenharmony_ci
17713af6ab5fSopenharmony_ci    if (paramName.Is("this")) {
17723af6ab5fSopenharmony_ci        if (!params.empty()) {
17733af6ab5fSopenharmony_ci            ThrowSyntaxError("A 'this' parameter must be the first parameter");
17743af6ab5fSopenharmony_ci        }
17753af6ab5fSopenharmony_ci
17763af6ab5fSopenharmony_ci        if ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0) {
17773af6ab5fSopenharmony_ci            ThrowSyntaxError("A constructor cannot have a 'this' parameter");
17783af6ab5fSopenharmony_ci        }
17793af6ab5fSopenharmony_ci
17803af6ab5fSopenharmony_ci        if ((GetContext().Status() & ParserStatus::ARROW_FUNCTION) != 0) {
17813af6ab5fSopenharmony_ci            ThrowSyntaxError("An arrow function cannot have a 'this' parameter");
17823af6ab5fSopenharmony_ci        }
17833af6ab5fSopenharmony_ci
17843af6ab5fSopenharmony_ci        if ((GetContext().Status() & ParserStatus::ACCESSOR_FUNCTION) != 0) {
17853af6ab5fSopenharmony_ci            ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters");
17863af6ab5fSopenharmony_ci        }
17873af6ab5fSopenharmony_ci    }
17883af6ab5fSopenharmony_ci
17893af6ab5fSopenharmony_ci    if (paramName.Is("constructor") && ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0)) {
17903af6ab5fSopenharmony_ci        ThrowSyntaxError("'constructor' cannot be used as a parameter property name");
17913af6ab5fSopenharmony_ci    }
17923af6ab5fSopenharmony_ci}
17933af6ab5fSopenharmony_ci
17943af6ab5fSopenharmony_ciArenaVector<ir::Expression *> TSParser::ParseFunctionParams()
17953af6ab5fSopenharmony_ci{
17963af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
17973af6ab5fSopenharmony_ci    Lexer()->NextToken();
17983af6ab5fSopenharmony_ci
17993af6ab5fSopenharmony_ci    ArenaVector<ir::Expression *> params(Allocator()->Adapter());
18003af6ab5fSopenharmony_ci    bool seenOptional = false;
18013af6ab5fSopenharmony_ci
18023af6ab5fSopenharmony_ci    while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
18033af6ab5fSopenharmony_ci        ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter());
18043af6ab5fSopenharmony_ci
18053af6ab5fSopenharmony_ci        ParseDecorators(decorators);
18063af6ab5fSopenharmony_ci
18073af6ab5fSopenharmony_ci        if (!decorators.empty() && ((GetContext().Status() & ParserStatus::IN_CLASS_BODY) == 0)) {
18083af6ab5fSopenharmony_ci            ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
18093af6ab5fSopenharmony_ci        }
18103af6ab5fSopenharmony_ci
18113af6ab5fSopenharmony_ci        ir::Expression *parameter = ParseFunctionParameter();
18123af6ab5fSopenharmony_ci        ValidateFunctionParam(params, parameter, &seenOptional);
18133af6ab5fSopenharmony_ci
18143af6ab5fSopenharmony_ci        if (!decorators.empty()) {
18153af6ab5fSopenharmony_ci            parameter->AddDecorators(std::move(decorators));
18163af6ab5fSopenharmony_ci        }
18173af6ab5fSopenharmony_ci
18183af6ab5fSopenharmony_ci        params.push_back(parameter);
18193af6ab5fSopenharmony_ci
18203af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
18213af6ab5fSopenharmony_ci            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
18223af6ab5fSopenharmony_ci            ThrowSyntaxError(", expected");
18233af6ab5fSopenharmony_ci        }
18243af6ab5fSopenharmony_ci
18253af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
18263af6ab5fSopenharmony_ci            Lexer()->NextToken();
18273af6ab5fSopenharmony_ci        }
18283af6ab5fSopenharmony_ci    }
18293af6ab5fSopenharmony_ci
18303af6ab5fSopenharmony_ci    ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
18313af6ab5fSopenharmony_ci    Lexer()->NextToken();
18323af6ab5fSopenharmony_ci
18333af6ab5fSopenharmony_ci    return params;
18343af6ab5fSopenharmony_ci}
18353af6ab5fSopenharmony_ci
18363af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseClassKeyAnnotation()
18373af6ab5fSopenharmony_ci{
18383af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
18393af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
18403af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options =
18413af6ab5fSopenharmony_ci            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
18423af6ab5fSopenharmony_ci        return ParseTypeAnnotation(&options);
18433af6ab5fSopenharmony_ci    }
18443af6ab5fSopenharmony_ci
18453af6ab5fSopenharmony_ci    return nullptr;
18463af6ab5fSopenharmony_ci}
18473af6ab5fSopenharmony_ci
18483af6ab5fSopenharmony_civoid TSParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
18493af6ab5fSopenharmony_ci{
18503af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) {
18513af6ab5fSopenharmony_ci        ThrowSyntaxError("A method cannot be named with a private identifier");
18523af6ab5fSopenharmony_ci    }
18533af6ab5fSopenharmony_ci
18543af6ab5fSopenharmony_ci    if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
18553af6ab5fSopenharmony_ci                                      Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
18563af6ab5fSopenharmony_ci        if (((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY)) != 0)) {
18573af6ab5fSopenharmony_ci            ThrowSyntaxError("Class method can not be declare nor readonly");
18583af6ab5fSopenharmony_ci        }
18593af6ab5fSopenharmony_ci        desc->classMethod = true;
18603af6ab5fSopenharmony_ci    } else {
18613af6ab5fSopenharmony_ci        if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
18623af6ab5fSopenharmony_ci            ThrowSyntaxError("Expected '('");
18633af6ab5fSopenharmony_ci        }
18643af6ab5fSopenharmony_ci        desc->classField = true;
18653af6ab5fSopenharmony_ci
18663af6ab5fSopenharmony_ci        if (desc->invalidComputedProperty) {
18673af6ab5fSopenharmony_ci            ThrowSyntaxError(
18683af6ab5fSopenharmony_ci                "Computed property name must refer to a symbol or "
18693af6ab5fSopenharmony_ci                "literal expression whose value is "
18703af6ab5fSopenharmony_ci                "number or string");
18713af6ab5fSopenharmony_ci        }
18723af6ab5fSopenharmony_ci    }
18733af6ab5fSopenharmony_ci
18743af6ab5fSopenharmony_ci    if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
18753af6ab5fSopenharmony_ci        desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
18763af6ab5fSopenharmony_ci    }
18773af6ab5fSopenharmony_ci
18783af6ab5fSopenharmony_ci    if (desc->isGenerator) {
18793af6ab5fSopenharmony_ci        desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
18803af6ab5fSopenharmony_ci    }
18813af6ab5fSopenharmony_ci}
18823af6ab5fSopenharmony_ci
18833af6ab5fSopenharmony_ciir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc,
18843af6ab5fSopenharmony_ci                                                 const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName,
18853af6ab5fSopenharmony_ci                                                 lexer::SourcePosition *propEnd)
18863af6ab5fSopenharmony_ci{
18873af6ab5fSopenharmony_ci    if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) {
18883af6ab5fSopenharmony_ci        desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION;
18893af6ab5fSopenharmony_ci    }
18903af6ab5fSopenharmony_ci
18913af6ab5fSopenharmony_ci    desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION;
18923af6ab5fSopenharmony_ci
18933af6ab5fSopenharmony_ci    if (InAmbientContext() && (desc->newStatus & ParserStatus::ASYNC_FUNCTION) != 0) {
18943af6ab5fSopenharmony_ci        ThrowSyntaxError("'async' modifier cannot be used in an ambient context.");
18953af6ab5fSopenharmony_ci    }
18963af6ab5fSopenharmony_ci
18973af6ab5fSopenharmony_ci    if (InAmbientContext() && desc->isGenerator) {
18983af6ab5fSopenharmony_ci        ThrowSyntaxError("Generators are not allowed in an ambient context.");
18993af6ab5fSopenharmony_ci    }
19003af6ab5fSopenharmony_ci
19013af6ab5fSopenharmony_ci    if (desc->methodKind != ir::MethodDefinitionKind::SET &&
19023af6ab5fSopenharmony_ci        ((desc->newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) == 0)) {
19033af6ab5fSopenharmony_ci        desc->newStatus |= ParserStatus::NEED_RETURN_TYPE;
19043af6ab5fSopenharmony_ci    }
19053af6ab5fSopenharmony_ci
19063af6ab5fSopenharmony_ci    ir::ScriptFunction *func = ParseFunction(desc->newStatus);
19073af6ab5fSopenharmony_ci
19083af6ab5fSopenharmony_ci    if (func->IsOverload() && !desc->decorators.empty()) {
19093af6ab5fSopenharmony_ci        ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.",
19103af6ab5fSopenharmony_ci                         desc->decorators.front()->Start());
19113af6ab5fSopenharmony_ci    }
19123af6ab5fSopenharmony_ci
19133af6ab5fSopenharmony_ci    auto *funcExpr = AllocNode<ir::FunctionExpression>(func);
19143af6ab5fSopenharmony_ci    funcExpr->SetRange(func->Range());
19153af6ab5fSopenharmony_ci
19163af6ab5fSopenharmony_ci    if (desc->methodKind == ir::MethodDefinitionKind::SET) {
19173af6ab5fSopenharmony_ci        ValidateClassSetter(desc, properties, propName, func);
19183af6ab5fSopenharmony_ci    } else if (desc->methodKind == ir::MethodDefinitionKind::GET) {
19193af6ab5fSopenharmony_ci        ValidateClassGetter(desc, properties, propName, func);
19203af6ab5fSopenharmony_ci    }
19213af6ab5fSopenharmony_ci
19223af6ab5fSopenharmony_ci    *propEnd = func->End();
19233af6ab5fSopenharmony_ci    func->AddFlag(ir::ScriptFunctionFlags::METHOD);
19243af6ab5fSopenharmony_ci    auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(),
19253af6ab5fSopenharmony_ci                                                   desc->isComputed);
19263af6ab5fSopenharmony_ci    method->SetRange(funcExpr->Range());
19273af6ab5fSopenharmony_ci
19283af6ab5fSopenharmony_ci    return method;
19293af6ab5fSopenharmony_ci}
19303af6ab5fSopenharmony_ci
19313af6ab5fSopenharmony_civoid TSParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
19323af6ab5fSopenharmony_ci                                   ir::Expression *propName, ir::ScriptFunction *func)
19333af6ab5fSopenharmony_ci{
19343af6ab5fSopenharmony_ci    if (func->Params().size() != 1) {
19353af6ab5fSopenharmony_ci        ThrowSyntaxError("Setter must have exactly one formal parameter");
19363af6ab5fSopenharmony_ci    }
19373af6ab5fSopenharmony_ci
19383af6ab5fSopenharmony_ci    if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
19393af6ab5fSopenharmony_ci        ir::ModifierFlags access = GetAccessability(desc->modifiers);
19403af6ab5fSopenharmony_ci        CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
19413af6ab5fSopenharmony_ci    }
19423af6ab5fSopenharmony_ci}
19433af6ab5fSopenharmony_ci
19443af6ab5fSopenharmony_civoid TSParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
19453af6ab5fSopenharmony_ci                                   ir::Expression *propName, ir::ScriptFunction *func)
19463af6ab5fSopenharmony_ci{
19473af6ab5fSopenharmony_ci    if (!func->Params().empty()) {
19483af6ab5fSopenharmony_ci        ThrowSyntaxError("Getter must not have formal parameters");
19493af6ab5fSopenharmony_ci    }
19503af6ab5fSopenharmony_ci
19513af6ab5fSopenharmony_ci    if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
19523af6ab5fSopenharmony_ci        ir::ModifierFlags access = GetAccessability(desc->modifiers);
19533af6ab5fSopenharmony_ci
19543af6ab5fSopenharmony_ci        CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
19553af6ab5fSopenharmony_ci    }
19563af6ab5fSopenharmony_ci}
19573af6ab5fSopenharmony_ci
19583af6ab5fSopenharmony_civoid TSParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
19593af6ab5fSopenharmony_ci{
19603af6ab5fSopenharmony_ci    if (typeAnnotation == nullptr) {
19613af6ab5fSopenharmony_ci        ThrowSyntaxError("An index signature must have a type annotation");
19623af6ab5fSopenharmony_ci    }
19633af6ab5fSopenharmony_ci}
19643af6ab5fSopenharmony_ci
19653af6ab5fSopenharmony_cibool TSParser::IsModifierKind(const lexer::Token &token)
19663af6ab5fSopenharmony_ci{
19673af6ab5fSopenharmony_ci    switch (token.KeywordType()) {
19683af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_PUBLIC:
19693af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_PRIVATE:
19703af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_PROTECTED:
19713af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_STATIC:
19723af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_ASYNC:
19733af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_ABSTRACT:
19743af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_DECLARE:
19753af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_READONLY:
19763af6ab5fSopenharmony_ci            return true;
19773af6ab5fSopenharmony_ci        default:
19783af6ab5fSopenharmony_ci            break;
19793af6ab5fSopenharmony_ci    }
19803af6ab5fSopenharmony_ci
19813af6ab5fSopenharmony_ci    return false;
19823af6ab5fSopenharmony_ci}
19833af6ab5fSopenharmony_ci
19843af6ab5fSopenharmony_civoid TSParser::CheckIfTypeParameterNameIsReserved()
19853af6ab5fSopenharmony_ci{
19863af6ab5fSopenharmony_ci    if (Lexer()->GetToken().IsReservedTypeName()) {
19873af6ab5fSopenharmony_ci        ThrowSyntaxError("Invalid type parameter name");
19883af6ab5fSopenharmony_ci    }
19893af6ab5fSopenharmony_ci}
19903af6ab5fSopenharmony_ci
19913af6ab5fSopenharmony_civoid TSParser::ThrowErrorIfStaticConstructor(ir::ModifierFlags flags)
19923af6ab5fSopenharmony_ci{
19933af6ab5fSopenharmony_ci    if ((flags & ir::ModifierFlags::STATIC) != 0) {
19943af6ab5fSopenharmony_ci        ThrowSyntaxError("Static modifier can not appear on a constructor");
19953af6ab5fSopenharmony_ci    }
19963af6ab5fSopenharmony_ci}
19973af6ab5fSopenharmony_ci
19983af6ab5fSopenharmony_cistd::tuple<bool, bool, bool> TSParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
19993af6ab5fSopenharmony_ci{
20003af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat left square bracket
20013af6ab5fSopenharmony_ci
20023af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
20033af6ab5fSopenharmony_ci        Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
20043af6ab5fSopenharmony_ci        auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
20053af6ab5fSopenharmony_ci        id->SetRange(Lexer()->GetToken().Loc());
20063af6ab5fSopenharmony_ci
20073af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat param
20083af6ab5fSopenharmony_ci
20093af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
20103af6ab5fSopenharmony_ci            ThrowSyntaxError("':' expected");
20113af6ab5fSopenharmony_ci        }
20123af6ab5fSopenharmony_ci
20133af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
20143af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
20153af6ab5fSopenharmony_ci        ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
20163af6ab5fSopenharmony_ci
20173af6ab5fSopenharmony_ci        if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) {
20183af6ab5fSopenharmony_ci            ThrowSyntaxError(
20193af6ab5fSopenharmony_ci                "An index signature parameter type must be either "
20203af6ab5fSopenharmony_ci                "'string' or 'number'");
20213af6ab5fSopenharmony_ci        }
20223af6ab5fSopenharmony_ci
20233af6ab5fSopenharmony_ci        id->SetTsTypeAnnotation(typeAnnotation);
20243af6ab5fSopenharmony_ci
20253af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
20263af6ab5fSopenharmony_ci            ThrowSyntaxError("']' expected");
20273af6ab5fSopenharmony_ci        }
20283af6ab5fSopenharmony_ci
20293af6ab5fSopenharmony_ci        *propName = id;
20303af6ab5fSopenharmony_ci        Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
20313af6ab5fSopenharmony_ci
20323af6ab5fSopenharmony_ci        return {false, false, true};
20333af6ab5fSopenharmony_ci    }
20343af6ab5fSopenharmony_ci
20353af6ab5fSopenharmony_ci    *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
20363af6ab5fSopenharmony_ci
20373af6ab5fSopenharmony_ci    bool invalidComputedProperty =
20383af6ab5fSopenharmony_ci        !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
20393af6ab5fSopenharmony_ci        !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
20403af6ab5fSopenharmony_ci          (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
20413af6ab5fSopenharmony_ci
20423af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
20433af6ab5fSopenharmony_ci        ThrowSyntaxError("Unexpected token, expected ']'");
20443af6ab5fSopenharmony_ci    }
20453af6ab5fSopenharmony_ci
20463af6ab5fSopenharmony_ci    return {true, invalidComputedProperty, false};
20473af6ab5fSopenharmony_ci}
20483af6ab5fSopenharmony_ci
20493af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseFunctionReturnType([[maybe_unused]] ParserStatus status)
20503af6ab5fSopenharmony_ci{
20513af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
20523af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
20533af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options =
20543af6ab5fSopenharmony_ci            TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
20553af6ab5fSopenharmony_ci        return ParseTypeAnnotation(&options);
20563af6ab5fSopenharmony_ci    }
20573af6ab5fSopenharmony_ci
20583af6ab5fSopenharmony_ci    return nullptr;
20593af6ab5fSopenharmony_ci}
20603af6ab5fSopenharmony_ci
20613af6ab5fSopenharmony_civoid TSParser::ValidateFunctionOverloadParams(const ArenaVector<ir::Expression *> &params)
20623af6ab5fSopenharmony_ci{
20633af6ab5fSopenharmony_ci    for (auto *it : params) {
20643af6ab5fSopenharmony_ci        if (it->IsAssignmentPattern()) {
20653af6ab5fSopenharmony_ci            ThrowSyntaxError(
20663af6ab5fSopenharmony_ci                "A parameter initializer is only allowed in a function "
20673af6ab5fSopenharmony_ci                "or constructor implementation.",
20683af6ab5fSopenharmony_ci                it->Start());
20693af6ab5fSopenharmony_ci        }
20703af6ab5fSopenharmony_ci    }
20713af6ab5fSopenharmony_ci}
20723af6ab5fSopenharmony_ci
20733af6ab5fSopenharmony_cistd::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> TSParser::ParseFunctionBody(
20743af6ab5fSopenharmony_ci    const ArenaVector<ir::Expression *> &params, ParserStatus newStatus, ParserStatus contextStatus)
20753af6ab5fSopenharmony_ci{
20763af6ab5fSopenharmony_ci    bool isDeclare = InAmbientContext();
20773af6ab5fSopenharmony_ci    bool isOverload = false;
20783af6ab5fSopenharmony_ci    bool letDeclare = true;
20793af6ab5fSopenharmony_ci    ir::BlockStatement *body = nullptr;
20803af6ab5fSopenharmony_ci    lexer::SourcePosition endLoc = Lexer()->GetToken().End();
20813af6ab5fSopenharmony_ci
20823af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
20833af6ab5fSopenharmony_ci        if ((newStatus & ParserStatus::FUNCTION_DECLARATION) != 0) {
20843af6ab5fSopenharmony_ci            ValidateFunctionOverloadParams(params);
20853af6ab5fSopenharmony_ci        } else if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
20863af6ab5fSopenharmony_ci            ThrowSyntaxError("Unexpected token, expected '{'");
20873af6ab5fSopenharmony_ci        } else {
20883af6ab5fSopenharmony_ci            letDeclare = false;
20893af6ab5fSopenharmony_ci        }
20903af6ab5fSopenharmony_ci
20913af6ab5fSopenharmony_ci        isOverload = true;
20923af6ab5fSopenharmony_ci    } else if (isDeclare) {
20933af6ab5fSopenharmony_ci        ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
20943af6ab5fSopenharmony_ci    } else {
20953af6ab5fSopenharmony_ci        body = ParseBlockStatement();
20963af6ab5fSopenharmony_ci        endLoc = body->End();
20973af6ab5fSopenharmony_ci    }
20983af6ab5fSopenharmony_ci
20993af6ab5fSopenharmony_ci    return {letDeclare, body, endLoc, isOverload};
21003af6ab5fSopenharmony_ci}
21013af6ab5fSopenharmony_ci
21023af6ab5fSopenharmony_ciir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
21033af6ab5fSopenharmony_ci{
21043af6ab5fSopenharmony_ci    ir::Identifier *local = ParseNamedImport(Lexer()->GetToken());
21053af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat local name
21063af6ab5fSopenharmony_ci
21073af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
21083af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat substitution
21093af6ab5fSopenharmony_ci        if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
21103af6ab5fSopenharmony_ci            ThrowSyntaxError("identifier expected");
21113af6ab5fSopenharmony_ci        }
21123af6ab5fSopenharmony_ci
21133af6ab5fSopenharmony_ci        auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(local, ParseModuleReference(), false);
21143af6ab5fSopenharmony_ci
21153af6ab5fSopenharmony_ci        return importEqualsDecl;
21163af6ab5fSopenharmony_ci    }
21173af6ab5fSopenharmony_ci
21183af6ab5fSopenharmony_ci    auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
21193af6ab5fSopenharmony_ci    specifier->SetRange(specifier->Local()->Range());
21203af6ab5fSopenharmony_ci    specifiers->push_back(specifier);
21213af6ab5fSopenharmony_ci
21223af6ab5fSopenharmony_ci    Lexer()->NextToken();  // eat specifier name
21233af6ab5fSopenharmony_ci
21243af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
21253af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat comma
21263af6ab5fSopenharmony_ci    }
21273af6ab5fSopenharmony_ci
21283af6ab5fSopenharmony_ci    return nullptr;
21293af6ab5fSopenharmony_ci}
21303af6ab5fSopenharmony_ci
21313af6ab5fSopenharmony_civoid TSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param)
21323af6ab5fSopenharmony_ci{
21333af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
21343af6ab5fSopenharmony_ci        Lexer()->NextToken();  // eat ':'
21353af6ab5fSopenharmony_ci
21363af6ab5fSopenharmony_ci        TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
21373af6ab5fSopenharmony_ci        param->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
21383af6ab5fSopenharmony_ci    }
21393af6ab5fSopenharmony_ci
21403af6ab5fSopenharmony_ci    if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
21413af6ab5fSopenharmony_ci        ThrowSyntaxError("Catch clause variable cannot have an initializer");
21423af6ab5fSopenharmony_ci    }
21433af6ab5fSopenharmony_ci}
21443af6ab5fSopenharmony_ci
21453af6ab5fSopenharmony_civoid TSParser::ThrowPossibleOutOfBoundaryJumpError(bool allowBreak)
21463af6ab5fSopenharmony_ci{
21473af6ab5fSopenharmony_ci    if (((GetContext().Status() & ParserStatus::FUNCTION) != 0) && !allowBreak) {
21483af6ab5fSopenharmony_ci        ThrowSyntaxError("Jump target cannot cross function boundary");
21493af6ab5fSopenharmony_ci    }
21503af6ab5fSopenharmony_ci}
21513af6ab5fSopenharmony_ci
21523af6ab5fSopenharmony_civoid TSParser::ThrowIllegalBreakError()
21533af6ab5fSopenharmony_ci{
21543af6ab5fSopenharmony_ci    ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement");
21553af6ab5fSopenharmony_ci}
21563af6ab5fSopenharmony_ci
21573af6ab5fSopenharmony_civoid TSParser::ThrowIllegalContinueError()
21583af6ab5fSopenharmony_ci{
21593af6ab5fSopenharmony_ci    ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
21603af6ab5fSopenharmony_ci}
21613af6ab5fSopenharmony_ci
21623af6ab5fSopenharmony_civoid TSParser::ThrowMultipleDefaultError()
21633af6ab5fSopenharmony_ci{
21643af6ab5fSopenharmony_ci    ThrowSyntaxError("A 'default' clause cannot appear more than once in a 'switch' statement");
21653af6ab5fSopenharmony_ci}
21663af6ab5fSopenharmony_ci
21673af6ab5fSopenharmony_civoid TSParser::ThrowIllegalNewLineErrorAfterThrow()
21683af6ab5fSopenharmony_ci{
21693af6ab5fSopenharmony_ci    ThrowSyntaxError("Line break not permitted here");
21703af6ab5fSopenharmony_ci}
21713af6ab5fSopenharmony_ci
21723af6ab5fSopenharmony_civoid TSParser::ThrowIfBodyEmptyError(ir::Statement *consequent)
21733af6ab5fSopenharmony_ci{
21743af6ab5fSopenharmony_ci    if (consequent->IsEmptyStatement()) {
21753af6ab5fSopenharmony_ci        ThrowSyntaxError("The body of an if statement cannot be the empty statement");
21763af6ab5fSopenharmony_ci    }
21773af6ab5fSopenharmony_ci}
21783af6ab5fSopenharmony_ci
21793af6ab5fSopenharmony_ci}  // namespace ark::es2panda::parser
2180