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 "lexer/token/tokenType.h" 173af6ab5fSopenharmony_ci#include "parser/parserFlags.h" 183af6ab5fSopenharmony_ci#include "ir/astNode.h" 193af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h" 203af6ab5fSopenharmony_ci#include "ir/base/decorator.h" 213af6ab5fSopenharmony_ci#include "ir/base/metaProperty.h" 223af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h" 233af6ab5fSopenharmony_ci#include "ir/base/property.h" 243af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h" 253af6ab5fSopenharmony_ci#include "ir/base/spreadElement.h" 263af6ab5fSopenharmony_ci#include "ir/base/templateElement.h" 273af6ab5fSopenharmony_ci#include "ir/expression.h" 283af6ab5fSopenharmony_ci#include "ir/expressions/arrayExpression.h" 293af6ab5fSopenharmony_ci#include "ir/expressions/arrowFunctionExpression.h" 303af6ab5fSopenharmony_ci#include "ir/expressions/assignmentExpression.h" 313af6ab5fSopenharmony_ci#include "ir/expressions/awaitExpression.h" 323af6ab5fSopenharmony_ci#include "ir/expressions/binaryExpression.h" 333af6ab5fSopenharmony_ci#include "ir/expressions/callExpression.h" 343af6ab5fSopenharmony_ci#include "ir/expressions/chainExpression.h" 353af6ab5fSopenharmony_ci#include "ir/expressions/classExpression.h" 363af6ab5fSopenharmony_ci#include "ir/expressions/conditionalExpression.h" 373af6ab5fSopenharmony_ci#include "ir/expressions/directEvalExpression.h" 383af6ab5fSopenharmony_ci#include "ir/expressions/functionExpression.h" 393af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 403af6ab5fSopenharmony_ci#include "ir/expressions/importExpression.h" 413af6ab5fSopenharmony_ci#include "ir/expressions/literals/bigIntLiteral.h" 423af6ab5fSopenharmony_ci#include "ir/expressions/literals/booleanLiteral.h" 433af6ab5fSopenharmony_ci#include "ir/expressions/literals/nullLiteral.h" 443af6ab5fSopenharmony_ci#include "ir/expressions/literals/numberLiteral.h" 453af6ab5fSopenharmony_ci#include "ir/expressions/literals/regExpLiteral.h" 463af6ab5fSopenharmony_ci#include "ir/expressions/literals/charLiteral.h" 473af6ab5fSopenharmony_ci#include "ir/expressions/literals/stringLiteral.h" 483af6ab5fSopenharmony_ci#include "ir/expressions/literals/undefinedLiteral.h" 493af6ab5fSopenharmony_ci#include "ir/expressions/memberExpression.h" 503af6ab5fSopenharmony_ci#include "ir/expressions/newExpression.h" 513af6ab5fSopenharmony_ci#include "ir/expressions/objectExpression.h" 523af6ab5fSopenharmony_ci#include "ir/expressions/omittedExpression.h" 533af6ab5fSopenharmony_ci#include "ir/expressions/sequenceExpression.h" 543af6ab5fSopenharmony_ci#include "ir/expressions/superExpression.h" 553af6ab5fSopenharmony_ci#include "ir/expressions/taggedTemplateExpression.h" 563af6ab5fSopenharmony_ci#include "ir/expressions/templateLiteral.h" 573af6ab5fSopenharmony_ci#include "ir/expressions/thisExpression.h" 583af6ab5fSopenharmony_ci#include "ir/expressions/typeofExpression.h" 593af6ab5fSopenharmony_ci#include "ir/expressions/unaryExpression.h" 603af6ab5fSopenharmony_ci#include "ir/expressions/updateExpression.h" 613af6ab5fSopenharmony_ci#include "ir/expressions/yieldExpression.h" 623af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h" 633af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h" 643af6ab5fSopenharmony_ci#include "ir/ts/tsAsExpression.h" 653af6ab5fSopenharmony_ci#include "ir/ts/tsNonNullExpression.h" 663af6ab5fSopenharmony_ci#include "ir/validationInfo.h" 673af6ab5fSopenharmony_ci#include "lexer/lexer.h" 683af6ab5fSopenharmony_ci#include "lexer/regexp/regexp.h" 693af6ab5fSopenharmony_ci#include "lexer/token/letters.h" 703af6ab5fSopenharmony_ci#include "lexer/token/sourceLocation.h" 713af6ab5fSopenharmony_ci#include "lexer/token/token.h" 723af6ab5fSopenharmony_ci#include "macros.h" 733af6ab5fSopenharmony_ci 743af6ab5fSopenharmony_ci#include <memory> 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_ci#include "parser/parserStatusContext.h" 773af6ab5fSopenharmony_ci#include "parserImpl.h" 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_cinamespace ark::es2panda::parser { 803af6ab5fSopenharmony_ciir::YieldExpression *ParserImpl::ParseYieldExpression() 813af6ab5fSopenharmony_ci{ 823af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD); 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 853af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = lexer_->GetToken().End(); 863af6ab5fSopenharmony_ci 873af6ab5fSopenharmony_ci if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) { 883af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected identifier"); 893af6ab5fSopenharmony_ci } 903af6ab5fSopenharmony_ci 913af6ab5fSopenharmony_ci lexer_->NextToken(); 923af6ab5fSopenharmony_ci 933af6ab5fSopenharmony_ci bool isDelegate = false; 943af6ab5fSopenharmony_ci ir::Expression *argument = nullptr; 953af6ab5fSopenharmony_ci 963af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY && !lexer_->GetToken().NewLine()) { 973af6ab5fSopenharmony_ci isDelegate = true; 983af6ab5fSopenharmony_ci lexer_->NextToken(); 993af6ab5fSopenharmony_ci 1003af6ab5fSopenharmony_ci argument = ParseExpression(); 1013af6ab5fSopenharmony_ci endLoc = argument->End(); 1023af6ab5fSopenharmony_ci } else if (!lexer_->GetToken().NewLine() && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE && 1033af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && 1043af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET && 1053af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 1063af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 1073af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON && 1083af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::EOS) { 1093af6ab5fSopenharmony_ci argument = ParseExpression(); 1103af6ab5fSopenharmony_ci endLoc = argument->End(); 1113af6ab5fSopenharmony_ci } 1123af6ab5fSopenharmony_ci 1133af6ab5fSopenharmony_ci auto *yieldNode = AllocNode<ir::YieldExpression>(argument, isDelegate); 1143af6ab5fSopenharmony_ci yieldNode->SetRange({startLoc, endLoc}); 1153af6ab5fSopenharmony_ci 1163af6ab5fSopenharmony_ci return yieldNode; 1173af6ab5fSopenharmony_ci} 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags) 1203af6ab5fSopenharmony_ci{ 1213af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && 1223af6ab5fSopenharmony_ci (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0) { 1233af6ab5fSopenharmony_ci return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0); 1243af6ab5fSopenharmony_ci } 1253af6ab5fSopenharmony_ci 1263af6ab5fSopenharmony_ci return expr; 1273af6ab5fSopenharmony_ci} 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 1303af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseExpression(ExpressionParseFlags flags) 1313af6ab5fSopenharmony_ci{ 1323af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD && 1333af6ab5fSopenharmony_ci (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) { 1343af6ab5fSopenharmony_ci ir::YieldExpression *yieldExpr = ParseYieldExpression(); 1353af6ab5fSopenharmony_ci 1363af6ab5fSopenharmony_ci return ParsePotentialExpressionSequence(yieldExpr, flags); 1373af6ab5fSopenharmony_ci } 1383af6ab5fSopenharmony_ci 1393af6ab5fSopenharmony_ci ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags); 1403af6ab5fSopenharmony_ci ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags); 1413af6ab5fSopenharmony_ci 1423af6ab5fSopenharmony_ci if (lexer_->GetToken().NewLine()) { 1433af6ab5fSopenharmony_ci return assignmentExpression; 1443af6ab5fSopenharmony_ci } 1453af6ab5fSopenharmony_ci 1463af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && 1473af6ab5fSopenharmony_ci (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U) { 1483af6ab5fSopenharmony_ci return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U); 1493af6ab5fSopenharmony_ci } 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_ci return assignmentExpression; 1523af6ab5fSopenharmony_ci} 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 1553af6ab5fSopenharmony_ciir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags) 1563af6ab5fSopenharmony_ci{ 1573af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 1583af6ab5fSopenharmony_ci 1593af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> elements(Allocator()->Adapter()); 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_ci lexer_->NextToken(); 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci bool trailingComma = false; 1643af6ab5fSopenharmony_ci bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0; 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_ci while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1673af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 1683af6ab5fSopenharmony_ci auto *omitted = AllocNode<ir::OmittedExpression>(); 1693af6ab5fSopenharmony_ci omitted->SetRange(lexer_->GetToken().Loc()); 1703af6ab5fSopenharmony_ci elements.push_back(omitted); 1713af6ab5fSopenharmony_ci lexer_->NextToken(); 1723af6ab5fSopenharmony_ci continue; 1733af6ab5fSopenharmony_ci } 1743af6ab5fSopenharmony_ci 1753af6ab5fSopenharmony_ci ir::Expression *element {}; 1763af6ab5fSopenharmony_ci if (inPattern) { 1773af6ab5fSopenharmony_ci element = ParsePatternElement(); 1783af6ab5fSopenharmony_ci } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 1793af6ab5fSopenharmony_ci element = ParseSpreadElement(ExpressionParseFlags::POTENTIALLY_IN_PATTERN); 1803af6ab5fSopenharmony_ci } else { 1813af6ab5fSopenharmony_ci element = ParseExpression(ExpressionParseFlags::POTENTIALLY_IN_PATTERN); 1823af6ab5fSopenharmony_ci } 1833af6ab5fSopenharmony_ci 1843af6ab5fSopenharmony_ci bool containsRest = element->IsRestElement(); 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ci elements.push_back(element); 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 1893af6ab5fSopenharmony_ci if (containsRest) { 1903af6ab5fSopenharmony_ci ThrowSyntaxError("Rest element must be last element", startLoc); 1913af6ab5fSopenharmony_ci } 1923af6ab5fSopenharmony_ci 1933af6ab5fSopenharmony_ci lexer_->NextToken(); // eat comma 1943af6ab5fSopenharmony_ci 1953af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1963af6ab5fSopenharmony_ci trailingComma = true; 1973af6ab5fSopenharmony_ci break; 1983af6ab5fSopenharmony_ci } 1993af6ab5fSopenharmony_ci 2003af6ab5fSopenharmony_ci continue; 2013af6ab5fSopenharmony_ci } 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 2043af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ',' or ']'"); 2053af6ab5fSopenharmony_ci } 2063af6ab5fSopenharmony_ci } 2073af6ab5fSopenharmony_ci 2083af6ab5fSopenharmony_ci auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION; 2093af6ab5fSopenharmony_ci auto *arrayExpressionNode = 2103af6ab5fSopenharmony_ci AllocNode<ir::ArrayExpression>(nodeType, std::move(elements), Allocator(), trailingComma); 2113af6ab5fSopenharmony_ci arrayExpressionNode->SetRange({startLoc, lexer_->GetToken().End()}); 2123af6ab5fSopenharmony_ci lexer_->NextToken(); 2133af6ab5fSopenharmony_ci 2143af6ab5fSopenharmony_ci if (inPattern) { 2153af6ab5fSopenharmony_ci arrayExpressionNode->SetDeclaration(); 2163af6ab5fSopenharmony_ci } 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_ci ParseArrayExpressionErrorCheck(arrayExpressionNode, flags, inPattern); 2193af6ab5fSopenharmony_ci return arrayExpressionNode; 2203af6ab5fSopenharmony_ci} 2213af6ab5fSopenharmony_ci 2223af6ab5fSopenharmony_civoid ParserImpl::ParseArrayExpressionErrorCheck(ir::ArrayExpression *arrayExpressionNode, 2233af6ab5fSopenharmony_ci const ExpressionParseFlags flags, const bool inPattern) 2243af6ab5fSopenharmony_ci{ 2253af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) { 2263af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION && 2273af6ab5fSopenharmony_ci !arrayExpressionNode->ConvertibleToArrayPattern()) { 2283af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", arrayExpressionNode->Start()); 2293af6ab5fSopenharmony_ci } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 2303af6ab5fSopenharmony_ci ir::ValidationInfo info = arrayExpressionNode->ValidateExpression(); 2313af6ab5fSopenharmony_ci if (info.Fail()) { 2323af6ab5fSopenharmony_ci ThrowSyntaxError(info.msg.Utf8(), info.pos); 2333af6ab5fSopenharmony_ci } 2343af6ab5fSopenharmony_ci } 2353af6ab5fSopenharmony_ci } 2363af6ab5fSopenharmony_ci} 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ciParserStatus ParserImpl::ValidateArrowParameter(ir::Expression *expr, [[maybe_unused]] bool *seenOptional) 2393af6ab5fSopenharmony_ci{ 2403af6ab5fSopenharmony_ci switch (expr->Type()) { 2413af6ab5fSopenharmony_ci case ir::AstNodeType::SPREAD_ELEMENT: { 2423af6ab5fSopenharmony_ci if (!expr->AsSpreadElement()->ConvertibleToRest(true)) { 2433af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid rest element."); 2443af6ab5fSopenharmony_ci } 2453af6ab5fSopenharmony_ci 2463af6ab5fSopenharmony_ci [[fallthrough]]; 2473af6ab5fSopenharmony_ci } 2483af6ab5fSopenharmony_ci case ir::AstNodeType::REST_ELEMENT: { 2493af6ab5fSopenharmony_ci ValidateArrowParameterBindings(expr->AsRestElement()->Argument()); 2503af6ab5fSopenharmony_ci return ParserStatus::HAS_COMPLEX_PARAM; 2513af6ab5fSopenharmony_ci } 2523af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 2533af6ab5fSopenharmony_ci ValidateArrowParameterBindings(expr); 2543af6ab5fSopenharmony_ci return ParserStatus::NO_OPTS; 2553af6ab5fSopenharmony_ci } 2563af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_EXPRESSION: { 2573af6ab5fSopenharmony_ci if (ir::ObjectExpression *objectPattern = expr->AsObjectExpression(); 2583af6ab5fSopenharmony_ci !objectPattern->ConvertibleToObjectPattern()) { 2593af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid destructuring assignment target"); 2603af6ab5fSopenharmony_ci } 2613af6ab5fSopenharmony_ci 2623af6ab5fSopenharmony_ci ValidateArrowParameterBindings(expr); 2633af6ab5fSopenharmony_ci return ParserStatus::HAS_COMPLEX_PARAM; 2643af6ab5fSopenharmony_ci } 2653af6ab5fSopenharmony_ci case ir::AstNodeType::ARRAY_EXPRESSION: { 2663af6ab5fSopenharmony_ci if (ir::ArrayExpression *arrayPattern = expr->AsArrayExpression(); 2673af6ab5fSopenharmony_ci !arrayPattern->ConvertibleToArrayPattern()) { 2683af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid destructuring assignment target"); 2693af6ab5fSopenharmony_ci } 2703af6ab5fSopenharmony_ci 2713af6ab5fSopenharmony_ci ValidateArrowParameterBindings(expr); 2723af6ab5fSopenharmony_ci return ParserStatus::HAS_COMPLEX_PARAM; 2733af6ab5fSopenharmony_ci } 2743af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { 2753af6ab5fSopenharmony_ci ValidateArrowParameterAssignment(expr->AsAssignmentExpression()); 2763af6ab5fSopenharmony_ci ValidateArrowParameterBindings(expr); 2773af6ab5fSopenharmony_ci return ParserStatus::HAS_COMPLEX_PARAM; 2783af6ab5fSopenharmony_ci } 2793af6ab5fSopenharmony_ci default: { 2803af6ab5fSopenharmony_ci break; 2813af6ab5fSopenharmony_ci } 2823af6ab5fSopenharmony_ci } 2833af6ab5fSopenharmony_ci ThrowSyntaxError("Insufficient formal parameter in arrow function."); 2843af6ab5fSopenharmony_ci return ParserStatus::NO_OPTS; 2853af6ab5fSopenharmony_ci} 2863af6ab5fSopenharmony_ci 2873af6ab5fSopenharmony_civoid ParserImpl::ValidateArrowParameterAssignment(ir::AssignmentExpression *expr) 2883af6ab5fSopenharmony_ci{ 2893af6ab5fSopenharmony_ci if (expr->Right()->IsYieldExpression()) { 2903af6ab5fSopenharmony_ci ThrowSyntaxError("yield is not allowed in arrow function parameters"); 2913af6ab5fSopenharmony_ci } else if (expr->Right()->IsAwaitExpression()) { 2923af6ab5fSopenharmony_ci ThrowSyntaxError("await is not allowed in arrow function parameters"); 2933af6ab5fSopenharmony_ci } else if (!expr->ConvertibleToAssignmentPattern()) { 2943af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid destructuring assignment target"); 2953af6ab5fSopenharmony_ci } 2963af6ab5fSopenharmony_ci} 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_ciir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowFunctionContext *arrowFunctionContext, 2993af6ab5fSopenharmony_ci ArrowFunctionDescriptor *desc, 3003af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl, 3013af6ab5fSopenharmony_ci ir::TypeNode *returnTypeAnnotation) 3023af6ab5fSopenharmony_ci{ 3033af6ab5fSopenharmony_ci context_.Status() |= desc->newStatus; 3043af6ab5fSopenharmony_ci 3053af6ab5fSopenharmony_ci lexer_->NextToken(); // eat '=>' 3063af6ab5fSopenharmony_ci ir::ScriptFunction *funcNode {}; 3073af6ab5fSopenharmony_ci 3083af6ab5fSopenharmony_ci ir::AstNode *body = nullptr; 3093af6ab5fSopenharmony_ci lexer::SourcePosition endLoc; 3103af6ab5fSopenharmony_ci lexer::SourcePosition bodyStart = lexer_->GetToken().Start(); 3113af6ab5fSopenharmony_ci 3123af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 3133af6ab5fSopenharmony_ci body = ParseExpression(); 3143af6ab5fSopenharmony_ci endLoc = body->AsExpression()->End(); 3153af6ab5fSopenharmony_ci arrowFunctionContext->AddFlag(ir::ScriptFunctionFlags::EXPRESSION); 3163af6ab5fSopenharmony_ci } else { 3173af6ab5fSopenharmony_ci lexer_->NextToken(); 3183af6ab5fSopenharmony_ci auto statements = ParseStatementList(); 3193af6ab5fSopenharmony_ci body = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements)); 3203af6ab5fSopenharmony_ci body->SetRange({bodyStart, lexer_->GetToken().End()}); 3213af6ab5fSopenharmony_ci 3223af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 3233af6ab5fSopenharmony_ci ThrowSyntaxError("Expected a '}'"); 3243af6ab5fSopenharmony_ci } 3253af6ab5fSopenharmony_ci 3263af6ab5fSopenharmony_ci lexer_->NextToken(); 3273af6ab5fSopenharmony_ci endLoc = body->End(); 3283af6ab5fSopenharmony_ci } 3293af6ab5fSopenharmony_ci 3303af6ab5fSopenharmony_ci // clang-format off 3313af6ab5fSopenharmony_ci funcNode = AllocNode<ir::ScriptFunction>( 3323af6ab5fSopenharmony_ci Allocator(), ir::ScriptFunction::ScriptFunctionData { 3333af6ab5fSopenharmony_ci body, 3343af6ab5fSopenharmony_ci ir::FunctionSignature(typeParamDecl, std::move(desc->params), returnTypeAnnotation), 3353af6ab5fSopenharmony_ci arrowFunctionContext->Flags(), 3363af6ab5fSopenharmony_ci {}, 3373af6ab5fSopenharmony_ci false, 3383af6ab5fSopenharmony_ci context_.GetLanguage()}); 3393af6ab5fSopenharmony_ci // clang-format on 3403af6ab5fSopenharmony_ci funcNode->SetRange({desc->startLoc, endLoc}); 3413af6ab5fSopenharmony_ci 3423af6ab5fSopenharmony_ci auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(funcNode); 3433af6ab5fSopenharmony_ci arrowFuncNode->SetRange(funcNode->Range()); 3443af6ab5fSopenharmony_ci 3453af6ab5fSopenharmony_ci return arrowFuncNode; 3463af6ab5fSopenharmony_ci} 3473af6ab5fSopenharmony_ci 3483af6ab5fSopenharmony_ciArrowFunctionDescriptor ParserImpl::ConvertToArrowParameter(ir::Expression *expr, bool isAsync) 3493af6ab5fSopenharmony_ci{ 3503af6ab5fSopenharmony_ci auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS; 3513af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ci if (expr == nullptr) { 3543af6ab5fSopenharmony_ci return ArrowFunctionDescriptor {std::move(params), lexer_->GetToken().Start(), arrowStatus}; 3553af6ab5fSopenharmony_ci } 3563af6ab5fSopenharmony_ci 3573af6ab5fSopenharmony_ci bool seenOptional = false; 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ci switch (expr->Type()) { 3603af6ab5fSopenharmony_ci case ir::AstNodeType::REST_ELEMENT: 3613af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: 3623af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_EXPRESSION: 3633af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_EXPRESSION: 3643af6ab5fSopenharmony_ci case ir::AstNodeType::ARRAY_EXPRESSION: { 3653af6ab5fSopenharmony_ci arrowStatus |= ValidateArrowParameter(expr, &seenOptional); 3663af6ab5fSopenharmony_ci 3673af6ab5fSopenharmony_ci params.push_back(expr); 3683af6ab5fSopenharmony_ci break; 3693af6ab5fSopenharmony_ci } 3703af6ab5fSopenharmony_ci case ir::AstNodeType::SEQUENCE_EXPRESSION: { 3713af6ab5fSopenharmony_ci auto &sequence = expr->AsSequenceExpression()->Sequence(); 3723af6ab5fSopenharmony_ci 3733af6ab5fSopenharmony_ci for (auto *it : sequence) { 3743af6ab5fSopenharmony_ci arrowStatus |= ValidateArrowParameter(it, &seenOptional); 3753af6ab5fSopenharmony_ci } 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci params.swap(sequence); 3783af6ab5fSopenharmony_ci break; 3793af6ab5fSopenharmony_ci } 3803af6ab5fSopenharmony_ci case ir::AstNodeType::CALL_EXPRESSION: { 3813af6ab5fSopenharmony_ci if (isAsync) { 3823af6ab5fSopenharmony_ci auto *callExpression = expr->AsCallExpression(); 3833af6ab5fSopenharmony_ci auto &arguments = callExpression->Arguments(); 3843af6ab5fSopenharmony_ci 3853af6ab5fSopenharmony_ci if (callExpression->HasTrailingComma()) { 3863af6ab5fSopenharmony_ci ASSERT(!arguments.empty()); 3873af6ab5fSopenharmony_ci ThrowSyntaxError("Rest parameter must be last formal parameter", arguments.back()->End()); 3883af6ab5fSopenharmony_ci } 3893af6ab5fSopenharmony_ci 3903af6ab5fSopenharmony_ci for (auto *it : arguments) { 3913af6ab5fSopenharmony_ci arrowStatus |= ValidateArrowParameter(it, &seenOptional); 3923af6ab5fSopenharmony_ci } 3933af6ab5fSopenharmony_ci 3943af6ab5fSopenharmony_ci params.swap(arguments); 3953af6ab5fSopenharmony_ci break; 3963af6ab5fSopenharmony_ci } 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_ci [[fallthrough]]; 3993af6ab5fSopenharmony_ci } 4003af6ab5fSopenharmony_ci default: { 4013af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, arrow (=>)"); 4023af6ab5fSopenharmony_ci } 4033af6ab5fSopenharmony_ci } 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus}; 4063af6ab5fSopenharmony_ci} 4073af6ab5fSopenharmony_ci 4083af6ab5fSopenharmony_ciir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpression(ir::Expression *expr, 4093af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl, 4103af6ab5fSopenharmony_ci ir::TypeNode *returnTypeAnnotation, bool isAsync) 4113af6ab5fSopenharmony_ci{ 4123af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW); 4133af6ab5fSopenharmony_ci 4143af6ab5fSopenharmony_ci if (lexer_->GetToken().NewLine()) { 4153af6ab5fSopenharmony_ci ThrowSyntaxError( 4163af6ab5fSopenharmony_ci "expected '=>' on the same line after an argument list, " 4173af6ab5fSopenharmony_ci "got line terminator"); 4183af6ab5fSopenharmony_ci } 4193af6ab5fSopenharmony_ci 4203af6ab5fSopenharmony_ci ArrowFunctionContext arrowFunctionContext(this, isAsync); 4213af6ab5fSopenharmony_ci FunctionParameterContext functionParamContext(&context_); 4223af6ab5fSopenharmony_ci ArrowFunctionDescriptor desc = ConvertToArrowParameter(expr, isAsync); 4233af6ab5fSopenharmony_ci 4243af6ab5fSopenharmony_ci return ParseArrowFunctionExpressionBody(&arrowFunctionContext, &desc, typeParamDecl, returnTypeAnnotation); 4253af6ab5fSopenharmony_ci} 4263af6ab5fSopenharmony_ci 4273af6ab5fSopenharmony_civoid ParserImpl::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement) 4283af6ab5fSopenharmony_ci{ 4293af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 4303af6ab5fSopenharmony_ci ThrowSyntaxError("Rest parameter must be last formal parameter"); 4313af6ab5fSopenharmony_ci } 4323af6ab5fSopenharmony_ci} 4333af6ab5fSopenharmony_ci 4343af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 4353af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseCoverParenthesizedExpressionAndArrowParameterList( 4363af6ab5fSopenharmony_ci [[maybe_unused]] ExpressionParseFlags flags) 4373af6ab5fSopenharmony_ci{ 4383af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 4393af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 4403af6ab5fSopenharmony_ci lexer_->NextToken(); 4413af6ab5fSopenharmony_ci 4423af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 4433af6ab5fSopenharmony_ci ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN); 4443af6ab5fSopenharmony_ci 4453af6ab5fSopenharmony_ci restElement->SetGrouped(); 4463af6ab5fSopenharmony_ci restElement->SetStart(start); 4473af6ab5fSopenharmony_ci 4483af6ab5fSopenharmony_ci ValidateArrowFunctionRestParameter(restElement); 4493af6ab5fSopenharmony_ci 4503af6ab5fSopenharmony_ci lexer_->NextToken(); 4513af6ab5fSopenharmony_ci 4523af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 4533af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 4543af6ab5fSopenharmony_ci } 4553af6ab5fSopenharmony_ci 4563af6ab5fSopenharmony_ci return ParseArrowFunctionExpression(restElement, nullptr, nullptr, false); 4573af6ab5fSopenharmony_ci } 4583af6ab5fSopenharmony_ci 4593af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 4603af6ab5fSopenharmony_ci lexer_->NextToken(); 4613af6ab5fSopenharmony_ci 4623af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 4633af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 4643af6ab5fSopenharmony_ci } 4653af6ab5fSopenharmony_ci 4663af6ab5fSopenharmony_ci auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, nullptr, false); 4673af6ab5fSopenharmony_ci arrowExpr->SetStart(start); 4683af6ab5fSopenharmony_ci arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start); 4693af6ab5fSopenharmony_ci 4703af6ab5fSopenharmony_ci return arrowExpr; 4713af6ab5fSopenharmony_ci } 4723af6ab5fSopenharmony_ci 4733af6ab5fSopenharmony_ci ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST | 4743af6ab5fSopenharmony_ci ExpressionParseFlags::POTENTIALLY_IN_PATTERN); 4753af6ab5fSopenharmony_ci 4763af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 4773af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ')'"); 4783af6ab5fSopenharmony_ci } 4793af6ab5fSopenharmony_ci 4803af6ab5fSopenharmony_ci expr->SetGrouped(); 4813af6ab5fSopenharmony_ci expr->SetRange({start, lexer_->GetToken().End()}); 4823af6ab5fSopenharmony_ci lexer_->NextToken(); 4833af6ab5fSopenharmony_ci 4843af6ab5fSopenharmony_ci return expr; 4853af6ab5fSopenharmony_ci} 4863af6ab5fSopenharmony_ci 4873af6ab5fSopenharmony_civoid ParserImpl::CheckInvalidDestructuring(const ir::AstNode *object) const 4883af6ab5fSopenharmony_ci{ 4893af6ab5fSopenharmony_ci object->Iterate([this](ir::AstNode *childNode) -> void { 4903af6ab5fSopenharmony_ci switch (childNode->Type()) { 4913af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_PATTERN: { 4923af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid property initializer"); 4933af6ab5fSopenharmony_ci break; 4943af6ab5fSopenharmony_ci } 4953af6ab5fSopenharmony_ci case ir::AstNodeType::REST_ELEMENT: 4963af6ab5fSopenharmony_ci case ir::AstNodeType::PROPERTY: 4973af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_EXPRESSION: { 4983af6ab5fSopenharmony_ci CheckInvalidDestructuring(childNode); 4993af6ab5fSopenharmony_ci break; 5003af6ab5fSopenharmony_ci } 5013af6ab5fSopenharmony_ci default: { 5023af6ab5fSopenharmony_ci break; 5033af6ab5fSopenharmony_ci } 5043af6ab5fSopenharmony_ci } 5053af6ab5fSopenharmony_ci }); 5063af6ab5fSopenharmony_ci} 5073af6ab5fSopenharmony_ci 5083af6ab5fSopenharmony_civoid ParserImpl::ValidateGroupedExpression(ir::Expression *lhsExpression) 5093af6ab5fSopenharmony_ci{ 5103af6ab5fSopenharmony_ci lexer::TokenType tokenType = lexer_->GetToken().Type(); 5113af6ab5fSopenharmony_ci if (lhsExpression->IsGrouped() && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) { 5123af6ab5fSopenharmony_ci if (lhsExpression->IsSequenceExpression()) { 5133af6ab5fSopenharmony_ci for (auto *seq : lhsExpression->AsSequenceExpression()->Sequence()) { 5143af6ab5fSopenharmony_ci ValidateParenthesizedExpression(seq); 5153af6ab5fSopenharmony_ci } 5163af6ab5fSopenharmony_ci } else { 5173af6ab5fSopenharmony_ci ValidateParenthesizedExpression(lhsExpression); 5183af6ab5fSopenharmony_ci } 5193af6ab5fSopenharmony_ci } 5203af6ab5fSopenharmony_ci} 5213af6ab5fSopenharmony_ci 5223af6ab5fSopenharmony_civoid ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) 5233af6ab5fSopenharmony_ci{ 5243af6ab5fSopenharmony_ci switch (lhsExpression->Type()) { 5253af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 5263af6ab5fSopenharmony_ci auto info = lhsExpression->AsIdentifier()->ValidateExpression(); 5273af6ab5fSopenharmony_ci if (info.Fail()) { 5283af6ab5fSopenharmony_ci ThrowSyntaxError(info.msg.Utf8(), info.pos); 5293af6ab5fSopenharmony_ci } 5303af6ab5fSopenharmony_ci break; 5313af6ab5fSopenharmony_ci } 5323af6ab5fSopenharmony_ci case ir::AstNodeType::MEMBER_EXPRESSION: { 5333af6ab5fSopenharmony_ci break; 5343af6ab5fSopenharmony_ci } 5353af6ab5fSopenharmony_ci case ir::AstNodeType::ARRAY_EXPRESSION: { 5363af6ab5fSopenharmony_ci auto info = lhsExpression->AsArrayExpression()->ValidateExpression(); 5373af6ab5fSopenharmony_ci if (info.Fail()) { 5383af6ab5fSopenharmony_ci ThrowSyntaxError(info.msg.Utf8(), info.pos); 5393af6ab5fSopenharmony_ci } 5403af6ab5fSopenharmony_ci break; 5413af6ab5fSopenharmony_ci } 5423af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_EXPRESSION: { 5433af6ab5fSopenharmony_ci auto info = lhsExpression->AsObjectExpression()->ValidateExpression(); 5443af6ab5fSopenharmony_ci if (info.Fail()) { 5453af6ab5fSopenharmony_ci ThrowSyntaxError(info.msg.Utf8(), info.pos); 5463af6ab5fSopenharmony_ci } 5473af6ab5fSopenharmony_ci break; 5483af6ab5fSopenharmony_ci } 5493af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { 5503af6ab5fSopenharmony_ci if (lhsExpression->AsAssignmentExpression()->ConvertibleToAssignmentPattern(false)) { 5513af6ab5fSopenharmony_ci break; 5523af6ab5fSopenharmony_ci } 5533af6ab5fSopenharmony_ci [[fallthrough]]; 5543af6ab5fSopenharmony_ci } 5553af6ab5fSopenharmony_ci case ir::AstNodeType::SPREAD_ELEMENT: { 5563af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid left-hand side in assignment expression"); 5573af6ab5fSopenharmony_ci } 5583af6ab5fSopenharmony_ci default: { 5593af6ab5fSopenharmony_ci break; 5603af6ab5fSopenharmony_ci } 5613af6ab5fSopenharmony_ci } 5623af6ab5fSopenharmony_ci} 5633af6ab5fSopenharmony_ci 5643af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePrefixAssertionExpression() 5653af6ab5fSopenharmony_ci{ 5663af6ab5fSopenharmony_ci ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(lexer_->GetToken().Type()), "'."}); 5673af6ab5fSopenharmony_ci return nullptr; 5683af6ab5fSopenharmony_ci} 5693af6ab5fSopenharmony_ci 5703af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpression, ExpressionParseFlags flags) 5713af6ab5fSopenharmony_ci{ 5723af6ab5fSopenharmony_ci ValidateGroupedExpression(lhsExpression); 5733af6ab5fSopenharmony_ci 5743af6ab5fSopenharmony_ci lexer::TokenType tokenType = lexer_->GetToken().Type(); 5753af6ab5fSopenharmony_ci switch (tokenType) { 5763af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: { 5773af6ab5fSopenharmony_ci lexer_->NextToken(); 5783af6ab5fSopenharmony_ci ir::Expression *consequent = ParseExpression(); 5793af6ab5fSopenharmony_ci 5803af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 5813af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ':'"); 5823af6ab5fSopenharmony_ci } 5833af6ab5fSopenharmony_ci 5843af6ab5fSopenharmony_ci lexer_->NextToken(); 5853af6ab5fSopenharmony_ci ir::Expression *alternate = ParseExpression(); 5863af6ab5fSopenharmony_ci 5873af6ab5fSopenharmony_ci auto *conditionalExpr = AllocNode<ir::ConditionalExpression>(lhsExpression, consequent, alternate); 5883af6ab5fSopenharmony_ci conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()}); 5893af6ab5fSopenharmony_ci return conditionalExpr; 5903af6ab5fSopenharmony_ci } 5913af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_ARROW: { 5923af6ab5fSopenharmony_ci if (lexer_->GetToken().NewLine()) { 5933af6ab5fSopenharmony_ci ThrowSyntaxError("Uncaught SyntaxError: expected expression, got '=>'"); 5943af6ab5fSopenharmony_ci } 5953af6ab5fSopenharmony_ci 5963af6ab5fSopenharmony_ci return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false); 5973af6ab5fSopenharmony_ci } 5983af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: { 5993af6ab5fSopenharmony_ci ValidateAssignmentTarget(flags, lhsExpression); 6003af6ab5fSopenharmony_ci 6013af6ab5fSopenharmony_ci lexer_->NextToken(); 6023af6ab5fSopenharmony_ci ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags)); 6033af6ab5fSopenharmony_ci 6043af6ab5fSopenharmony_ci auto *binaryAssignmentExpression = 6053af6ab5fSopenharmony_ci AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType); 6063af6ab5fSopenharmony_ci 6073af6ab5fSopenharmony_ci binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); 6083af6ab5fSopenharmony_ci return binaryAssignmentExpression; 6093af6ab5fSopenharmony_ci } 6103af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_AS: { 6113af6ab5fSopenharmony_ci if (auto asExpression = ParsePotentialAsExpression(lhsExpression); asExpression != nullptr) { 6123af6ab5fSopenharmony_ci return ParseAssignmentExpression(asExpression); 6133af6ab5fSopenharmony_ci } 6143af6ab5fSopenharmony_ci break; 6153af6ab5fSopenharmony_ci } 6163af6ab5fSopenharmony_ci default: { 6173af6ab5fSopenharmony_ci auto expression = ParseAssignmentBinaryExpression(tokenType, lhsExpression, flags); 6183af6ab5fSopenharmony_ci if (expression == nullptr) { 6193af6ab5fSopenharmony_ci expression = ParseAssignmentEqualExpression(tokenType, lhsExpression, flags); 6203af6ab5fSopenharmony_ci } 6213af6ab5fSopenharmony_ci 6223af6ab5fSopenharmony_ci if (expression != nullptr) { 6233af6ab5fSopenharmony_ci return expression; 6243af6ab5fSopenharmony_ci } 6253af6ab5fSopenharmony_ci 6263af6ab5fSopenharmony_ci break; 6273af6ab5fSopenharmony_ci } 6283af6ab5fSopenharmony_ci } 6293af6ab5fSopenharmony_ci 6303af6ab5fSopenharmony_ci return lhsExpression; 6313af6ab5fSopenharmony_ci} 6323af6ab5fSopenharmony_ci 6333af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseAssignmentBinaryExpression(const lexer::TokenType tokenType, 6343af6ab5fSopenharmony_ci ir::Expression *lhsExpression, 6353af6ab5fSopenharmony_ci const ExpressionParseFlags flags) 6363af6ab5fSopenharmony_ci{ 6373af6ab5fSopenharmony_ci switch (tokenType) { 6383af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_IN: { 6393af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::STOP_AT_IN) != 0) { 6403af6ab5fSopenharmony_ci break; 6413af6ab5fSopenharmony_ci } 6423af6ab5fSopenharmony_ci 6433af6ab5fSopenharmony_ci [[fallthrough]]; 6443af6ab5fSopenharmony_ci } 6453af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: 6463af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: 6473af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: 6483af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_OR: 6493af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: 6503af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_AND: 6513af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EQUAL: 6523af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: 6533af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: 6543af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: 6553af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: 6563af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: 6573af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_GREATER_THAN: 6583af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: 6593af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: 6603af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: 6613af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: 6623af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_PLUS: 6633af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MINUS: 6643af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MULTIPLY: 6653af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE: 6663af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MOD: 6673af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_INSTANCEOF: 6683af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: { 6693af6ab5fSopenharmony_ci return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression)); 6703af6ab5fSopenharmony_ci } 6713af6ab5fSopenharmony_ci default: 6723af6ab5fSopenharmony_ci break; 6733af6ab5fSopenharmony_ci } 6743af6ab5fSopenharmony_ci 6753af6ab5fSopenharmony_ci return nullptr; 6763af6ab5fSopenharmony_ci} 6773af6ab5fSopenharmony_ci 6783af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenType tokenType, 6793af6ab5fSopenharmony_ci ir::Expression *lhsExpression, 6803af6ab5fSopenharmony_ci const ExpressionParseFlags flags) 6813af6ab5fSopenharmony_ci{ 6823af6ab5fSopenharmony_ci switch (tokenType) { 6833af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: 6843af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: 6853af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: 6863af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: 6873af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: 6883af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: 6893af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: 6903af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: 6913af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: 6923af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: 6933af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: 6943af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: { 6953af6ab5fSopenharmony_ci ValidateLvalueAssignmentTarget(lhsExpression); 6963af6ab5fSopenharmony_ci 6973af6ab5fSopenharmony_ci lexer_->NextToken(); 6983af6ab5fSopenharmony_ci ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags)); 6993af6ab5fSopenharmony_ci 7003af6ab5fSopenharmony_ci auto *binaryAssignmentExpression = 7013af6ab5fSopenharmony_ci AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType); 7023af6ab5fSopenharmony_ci 7033af6ab5fSopenharmony_ci binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); 7043af6ab5fSopenharmony_ci return binaryAssignmentExpression; 7053af6ab5fSopenharmony_ci } 7063af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL: 7073af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL: 7083af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL: { 7093af6ab5fSopenharmony_ci ThrowUnexpectedToken(tokenType); 7103af6ab5fSopenharmony_ci } 7113af6ab5fSopenharmony_ci default: 7123af6ab5fSopenharmony_ci break; 7133af6ab5fSopenharmony_ci } 7143af6ab5fSopenharmony_ci 7153af6ab5fSopenharmony_ci return nullptr; 7163af6ab5fSopenharmony_ci} 7173af6ab5fSopenharmony_ci 7183af6ab5fSopenharmony_ciir::TemplateLiteral *ParserImpl::ParseTemplateLiteral() 7193af6ab5fSopenharmony_ci{ 7203af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 7213af6ab5fSopenharmony_ci 7223af6ab5fSopenharmony_ci ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter()); 7233af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> expressions(Allocator()->Adapter()); 7243af6ab5fSopenharmony_ci 7253af6ab5fSopenharmony_ci while (true) { 7263af6ab5fSopenharmony_ci lexer_->ResetTokenEnd(); 7273af6ab5fSopenharmony_ci const auto startPos = lexer_->Save(); 7283af6ab5fSopenharmony_ci 7293af6ab5fSopenharmony_ci lexer_->ScanString<lexer::LEX_CHAR_BACK_TICK>(); 7303af6ab5fSopenharmony_ci util::StringView cooked = lexer_->GetToken().String(); 7313af6ab5fSopenharmony_ci 7323af6ab5fSopenharmony_ci lexer_->Rewind(startPos); 7333af6ab5fSopenharmony_ci auto [raw, end, scanExpression] = lexer_->ScanTemplateString(); 7343af6ab5fSopenharmony_ci 7353af6ab5fSopenharmony_ci auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked); 7363af6ab5fSopenharmony_ci element->SetRange({lexer::SourcePosition {startPos.Iterator().Index(), startPos.Line()}, 7373af6ab5fSopenharmony_ci lexer::SourcePosition {end, lexer_->Line()}}); 7383af6ab5fSopenharmony_ci quasis.push_back(element); 7393af6ab5fSopenharmony_ci 7403af6ab5fSopenharmony_ci if (!scanExpression) { 7413af6ab5fSopenharmony_ci lexer_->ScanTemplateStringEnd(); 7423af6ab5fSopenharmony_ci break; 7433af6ab5fSopenharmony_ci } 7443af6ab5fSopenharmony_ci 7453af6ab5fSopenharmony_ci ir::Expression *expression = nullptr; 7463af6ab5fSopenharmony_ci 7473af6ab5fSopenharmony_ci { 7483af6ab5fSopenharmony_ci lexer::TemplateLiteralParserContext ctx(lexer_); 7493af6ab5fSopenharmony_ci lexer_->PushTemplateContext(&ctx); 7503af6ab5fSopenharmony_ci lexer_->NextToken(); 7513af6ab5fSopenharmony_ci expression = ParseExpression(); 7523af6ab5fSopenharmony_ci } 7533af6ab5fSopenharmony_ci 7543af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 7553af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected '}'."); 7563af6ab5fSopenharmony_ci } 7573af6ab5fSopenharmony_ci 7583af6ab5fSopenharmony_ci expressions.push_back(expression); 7593af6ab5fSopenharmony_ci } 7603af6ab5fSopenharmony_ci 7613af6ab5fSopenharmony_ci auto *templateNode = AllocNode<ir::TemplateLiteral>(std::move(quasis), std::move(expressions)); 7623af6ab5fSopenharmony_ci templateNode->SetRange({startLoc, lexer_->GetToken().End()}); 7633af6ab5fSopenharmony_ci 7643af6ab5fSopenharmony_ci lexer_->NextToken(); 7653af6ab5fSopenharmony_ci 7663af6ab5fSopenharmony_ci return templateNode; 7673af6ab5fSopenharmony_ci} 7683af6ab5fSopenharmony_ci 7693af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseNewExpression() 7703af6ab5fSopenharmony_ci{ 7713af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 7723af6ab5fSopenharmony_ci 7733af6ab5fSopenharmony_ci lexer_->NextToken(); // eat new 7743af6ab5fSopenharmony_ci 7753af6ab5fSopenharmony_ci // parse callee part of NewExpression 7763af6ab5fSopenharmony_ci ir::Expression *callee = ParseMemberExpression(true); 7773af6ab5fSopenharmony_ci if (callee->IsImportExpression() && !callee->IsGrouped()) { 7783af6ab5fSopenharmony_ci ThrowSyntaxError("Cannot use new with import(...)"); 7793af6ab5fSopenharmony_ci } 7803af6ab5fSopenharmony_ci 7813af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> arguments(Allocator()->Adapter()); 7823af6ab5fSopenharmony_ci 7833af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 7843af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = callee->End(); 7853af6ab5fSopenharmony_ci auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments)); 7863af6ab5fSopenharmony_ci newExprNode->SetRange({start, endLoc}); 7873af6ab5fSopenharmony_ci 7883af6ab5fSopenharmony_ci return newExprNode; 7893af6ab5fSopenharmony_ci } 7903af6ab5fSopenharmony_ci 7913af6ab5fSopenharmony_ci lexer_->NextToken(); // eat left parenthesis 7923af6ab5fSopenharmony_ci 7933af6ab5fSopenharmony_ci // parse argument part of NewExpression 7943af6ab5fSopenharmony_ci while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 7953af6ab5fSopenharmony_ci ir::Expression *argument = nullptr; 7963af6ab5fSopenharmony_ci 7973af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 7983af6ab5fSopenharmony_ci argument = ParseSpreadElement(); 7993af6ab5fSopenharmony_ci } else { 8003af6ab5fSopenharmony_ci argument = ParseExpression(); 8013af6ab5fSopenharmony_ci } 8023af6ab5fSopenharmony_ci 8033af6ab5fSopenharmony_ci arguments.push_back(argument); 8043af6ab5fSopenharmony_ci 8053af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 8063af6ab5fSopenharmony_ci lexer_->NextToken(); // eat comma 8073af6ab5fSopenharmony_ci } 8083af6ab5fSopenharmony_ci 8093af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::EOS) { 8103af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token in argument parsing"); 8113af6ab5fSopenharmony_ci } 8123af6ab5fSopenharmony_ci } 8133af6ab5fSopenharmony_ci 8143af6ab5fSopenharmony_ci auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments)); 8153af6ab5fSopenharmony_ci newExprNode->SetRange({start, lexer_->GetToken().End()}); 8163af6ab5fSopenharmony_ci 8173af6ab5fSopenharmony_ci lexer_->NextToken(); 8183af6ab5fSopenharmony_ci 8193af6ab5fSopenharmony_ci return newExprNode; 8203af6ab5fSopenharmony_ci} 8213af6ab5fSopenharmony_ci 8223af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseLeftHandSideExpression(ExpressionParseFlags flags) 8233af6ab5fSopenharmony_ci{ 8243af6ab5fSopenharmony_ci return ParseMemberExpression(false, flags); 8253af6ab5fSopenharmony_ci} 8263af6ab5fSopenharmony_ci 8273af6ab5fSopenharmony_ciir::MetaProperty *ParserImpl::ParsePotentialNewTarget() 8283af6ab5fSopenharmony_ci{ 8293af6ab5fSopenharmony_ci lexer::SourceRange loc = lexer_->GetToken().Loc(); 8303af6ab5fSopenharmony_ci 8313af6ab5fSopenharmony_ci if (lexer_->Lookahead() == lexer::LEX_CHAR_DOT) { 8323af6ab5fSopenharmony_ci lexer_->NextToken(); 8333af6ab5fSopenharmony_ci lexer_->NextToken(); 8343af6ab5fSopenharmony_ci 8353af6ab5fSopenharmony_ci if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_TARGET) { 8363af6ab5fSopenharmony_ci if ((context_.Status() & ParserStatus::ALLOW_NEW_TARGET) == 0) { 8373af6ab5fSopenharmony_ci ThrowSyntaxError("'new.Target' is not allowed here"); 8383af6ab5fSopenharmony_ci } 8393af6ab5fSopenharmony_ci 8403af6ab5fSopenharmony_ci if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) { 8413af6ab5fSopenharmony_ci ThrowSyntaxError("'new.Target' must not contain escaped characters"); 8423af6ab5fSopenharmony_ci } 8433af6ab5fSopenharmony_ci 8443af6ab5fSopenharmony_ci auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::NEW_TARGET); 8453af6ab5fSopenharmony_ci metaProperty->SetRange(loc); 8463af6ab5fSopenharmony_ci lexer_->NextToken(); 8473af6ab5fSopenharmony_ci return metaProperty; 8483af6ab5fSopenharmony_ci } 8493af6ab5fSopenharmony_ci } 8503af6ab5fSopenharmony_ci 8513af6ab5fSopenharmony_ci return nullptr; 8523af6ab5fSopenharmony_ci} 8533af6ab5fSopenharmony_ci 8543af6ab5fSopenharmony_ciir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) 8553af6ab5fSopenharmony_ci{ 8563af6ab5fSopenharmony_ci auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator()); 8573af6ab5fSopenharmony_ci identNode->SetReference(); 8583af6ab5fSopenharmony_ci identNode->SetRange(lexer_->GetToken().Loc()); 8593af6ab5fSopenharmony_ci 8603af6ab5fSopenharmony_ci lexer_->NextToken(); 8613af6ab5fSopenharmony_ci return identNode; 8623af6ab5fSopenharmony_ci} 8633af6ab5fSopenharmony_ci 8643af6ab5fSopenharmony_ciir::BooleanLiteral *ParserImpl::ParseBooleanLiteral() 8653af6ab5fSopenharmony_ci{ 8663af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE || 8673af6ab5fSopenharmony_ci lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE); 8683af6ab5fSopenharmony_ci 8693af6ab5fSopenharmony_ci auto *booleanNode = AllocNode<ir::BooleanLiteral>(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE); 8703af6ab5fSopenharmony_ci booleanNode->SetRange(lexer_->GetToken().Loc()); 8713af6ab5fSopenharmony_ci 8723af6ab5fSopenharmony_ci lexer_->NextToken(); 8733af6ab5fSopenharmony_ci return booleanNode; 8743af6ab5fSopenharmony_ci} 8753af6ab5fSopenharmony_ci 8763af6ab5fSopenharmony_ciir::NullLiteral *ParserImpl::ParseNullLiteral() 8773af6ab5fSopenharmony_ci{ 8783af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL); 8793af6ab5fSopenharmony_ci auto *nullNode = AllocNode<ir::NullLiteral>(); 8803af6ab5fSopenharmony_ci nullNode->SetRange(lexer_->GetToken().Loc()); 8813af6ab5fSopenharmony_ci 8823af6ab5fSopenharmony_ci lexer_->NextToken(); 8833af6ab5fSopenharmony_ci return nullNode; 8843af6ab5fSopenharmony_ci} 8853af6ab5fSopenharmony_ci 8863af6ab5fSopenharmony_ciir::Literal *ParserImpl::ParseNumberLiteral() 8873af6ab5fSopenharmony_ci{ 8883af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER); 8893af6ab5fSopenharmony_ci 8903af6ab5fSopenharmony_ci ir::Literal *numberNode {}; 8913af6ab5fSopenharmony_ci 8923af6ab5fSopenharmony_ci if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0U) { 8933af6ab5fSopenharmony_ci numberNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt()); 8943af6ab5fSopenharmony_ci } else { 8953af6ab5fSopenharmony_ci numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber()); 8963af6ab5fSopenharmony_ci } 8973af6ab5fSopenharmony_ci 8983af6ab5fSopenharmony_ci numberNode->SetRange(lexer_->GetToken().Loc()); 8993af6ab5fSopenharmony_ci 9003af6ab5fSopenharmony_ci lexer_->NextToken(); 9013af6ab5fSopenharmony_ci return numberNode; 9023af6ab5fSopenharmony_ci} 9033af6ab5fSopenharmony_ci 9043af6ab5fSopenharmony_ciir::CharLiteral *ParserImpl::ParseCharLiteral() 9053af6ab5fSopenharmony_ci{ 9063af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR); 9073af6ab5fSopenharmony_ci 9083af6ab5fSopenharmony_ci auto *charNode = AllocNode<ir::CharLiteral>(lexer_->GetToken().Utf16()); 9093af6ab5fSopenharmony_ci charNode->SetRange(lexer_->GetToken().Loc()); 9103af6ab5fSopenharmony_ci 9113af6ab5fSopenharmony_ci lexer_->NextToken(); 9123af6ab5fSopenharmony_ci return charNode; 9133af6ab5fSopenharmony_ci} 9143af6ab5fSopenharmony_ci 9153af6ab5fSopenharmony_ciir::StringLiteral *ParserImpl::ParseStringLiteral() 9163af6ab5fSopenharmony_ci{ 9173af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING); 9183af6ab5fSopenharmony_ci 9193af6ab5fSopenharmony_ci auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String()); 9203af6ab5fSopenharmony_ci stringNode->SetRange(lexer_->GetToken().Loc()); 9213af6ab5fSopenharmony_ci 9223af6ab5fSopenharmony_ci lexer_->NextToken(); 9233af6ab5fSopenharmony_ci return stringNode; 9243af6ab5fSopenharmony_ci} 9253af6ab5fSopenharmony_ci 9263af6ab5fSopenharmony_ciir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral() 9273af6ab5fSopenharmony_ci{ 9283af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED); 9293af6ab5fSopenharmony_ci auto *undefinedNode = AllocNode<ir::UndefinedLiteral>(); 9303af6ab5fSopenharmony_ci undefinedNode->SetRange(lexer_->GetToken().Loc()); 9313af6ab5fSopenharmony_ci 9323af6ab5fSopenharmony_ci lexer_->NextToken(); 9333af6ab5fSopenharmony_ci return undefinedNode; 9343af6ab5fSopenharmony_ci} 9353af6ab5fSopenharmony_ci 9363af6ab5fSopenharmony_ciir::ThisExpression *ParserImpl::ParseThisExpression() 9373af6ab5fSopenharmony_ci{ 9383af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS); 9393af6ab5fSopenharmony_ci 9403af6ab5fSopenharmony_ci auto *thisExprNode = AllocNode<ir::ThisExpression>(); 9413af6ab5fSopenharmony_ci thisExprNode->SetRange(lexer_->GetToken().Loc()); 9423af6ab5fSopenharmony_ci 9433af6ab5fSopenharmony_ci lexer_->NextToken(); 9443af6ab5fSopenharmony_ci return thisExprNode; 9453af6ab5fSopenharmony_ci} 9463af6ab5fSopenharmony_ci 9473af6ab5fSopenharmony_ciir::RegExpLiteral *ParserImpl::ParseRegularExpression() 9483af6ab5fSopenharmony_ci{ 9493af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE || 9503af6ab5fSopenharmony_ci lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL); 9513af6ab5fSopenharmony_ci 9523af6ab5fSopenharmony_ci lexer_->ResetTokenEnd(); 9533af6ab5fSopenharmony_ci auto regexp = lexer_->ScanRegExp(); 9543af6ab5fSopenharmony_ci 9553af6ab5fSopenharmony_ci lexer::RegExpParser reParser(regexp, Allocator(), *this); 9563af6ab5fSopenharmony_ci 9573af6ab5fSopenharmony_ci reParser.ParsePattern(); 9583af6ab5fSopenharmony_ci 9593af6ab5fSopenharmony_ci auto *regexpNode = AllocNode<ir::RegExpLiteral>(regexp.patternStr, regexp.flags, regexp.flagsStr); 9603af6ab5fSopenharmony_ci regexpNode->SetRange(lexer_->GetToken().Loc()); 9613af6ab5fSopenharmony_ci 9623af6ab5fSopenharmony_ci lexer_->NextToken(); 9633af6ab5fSopenharmony_ci return regexpNode; 9643af6ab5fSopenharmony_ci} 9653af6ab5fSopenharmony_ci 9663af6ab5fSopenharmony_ciir::SuperExpression *ParserImpl::ParseSuperExpression() 9673af6ab5fSopenharmony_ci{ 9683af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER); 9693af6ab5fSopenharmony_ci 9703af6ab5fSopenharmony_ci auto *superExprNode = AllocNode<ir::SuperExpression>(); 9713af6ab5fSopenharmony_ci superExprNode->SetRange(lexer_->GetToken().Loc()); 9723af6ab5fSopenharmony_ci 9733af6ab5fSopenharmony_ci lexer_->NextToken(); // eat super 9743af6ab5fSopenharmony_ci 9753af6ab5fSopenharmony_ci if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD || 9763af6ab5fSopenharmony_ci lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) && 9773af6ab5fSopenharmony_ci (context_.Status() & ParserStatus::ALLOW_SUPER) != 0U) { 9783af6ab5fSopenharmony_ci return superExprNode; 9793af6ab5fSopenharmony_ci } 9803af6ab5fSopenharmony_ci 9813af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 9823af6ab5fSopenharmony_ci (context_.Status() & ParserStatus::ALLOW_SUPER_CALL) != 0U) { 9833af6ab5fSopenharmony_ci return superExprNode; 9843af6ab5fSopenharmony_ci } 9853af6ab5fSopenharmony_ci 9863af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected super keyword"); 9873af6ab5fSopenharmony_ci} 9883af6ab5fSopenharmony_ci 9893af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags) 9903af6ab5fSopenharmony_ci{ 9913af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 9923af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 9933af6ab5fSopenharmony_ci return ParsePrimaryExpressionIdent(flags); 9943af6ab5fSopenharmony_ci } 9953af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_TRUE: 9963af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_FALSE: { 9973af6ab5fSopenharmony_ci return ParseBooleanLiteral(); 9983af6ab5fSopenharmony_ci } 9993af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NULL: { 10003af6ab5fSopenharmony_ci return ParseNullLiteral(); 10013af6ab5fSopenharmony_ci } 10023af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_UNDEFINED: { 10033af6ab5fSopenharmony_ci return ParseUndefinedLiteral(); 10043af6ab5fSopenharmony_ci } 10053af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: { 10063af6ab5fSopenharmony_ci return ParseNumberLiteral(); 10073af6ab5fSopenharmony_ci } 10083af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: { 10093af6ab5fSopenharmony_ci return ParseStringLiteral(); 10103af6ab5fSopenharmony_ci } 10113af6ab5fSopenharmony_ci default: { 10123af6ab5fSopenharmony_ci break; 10133af6ab5fSopenharmony_ci } 10143af6ab5fSopenharmony_ci } 10153af6ab5fSopenharmony_ci 10163af6ab5fSopenharmony_ci ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(lexer_->GetToken().Type()), "'."}); 10173af6ab5fSopenharmony_ci return nullptr; 10183af6ab5fSopenharmony_ci} 10193af6ab5fSopenharmony_ci 10203af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseHashMaskOperator() 10213af6ab5fSopenharmony_ci{ 10223af6ab5fSopenharmony_ci ValidatePrivateIdentifier(); 10233af6ab5fSopenharmony_ci auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator()); 10243af6ab5fSopenharmony_ci privateIdent->SetPrivate(true); 10253af6ab5fSopenharmony_ci privateIdent->SetReference(); 10263af6ab5fSopenharmony_ci lexer_->NextToken(); 10273af6ab5fSopenharmony_ci 10283af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_IN) { 10293af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected private identifier"); 10303af6ab5fSopenharmony_ci } 10313af6ab5fSopenharmony_ci 10323af6ab5fSopenharmony_ci return privateIdent; 10333af6ab5fSopenharmony_ci} 10343af6ab5fSopenharmony_ci 10353af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseClassExpression() 10363af6ab5fSopenharmony_ci{ 10373af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 10383af6ab5fSopenharmony_ci ir::ClassDefinition *classDefinition = ParseClassDefinition(ir::ClassDefinitionModifiers::ID_REQUIRED); 10393af6ab5fSopenharmony_ci 10403af6ab5fSopenharmony_ci auto *classExpr = AllocNode<ir::ClassExpression>(classDefinition); 10413af6ab5fSopenharmony_ci classExpr->SetRange({startLoc, classDefinition->End()}); 10423af6ab5fSopenharmony_ci 10433af6ab5fSopenharmony_ci return classExpr; 10443af6ab5fSopenharmony_ci} 10453af6ab5fSopenharmony_ci 10463af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePunctuators(ExpressionParseFlags flags) 10473af6ab5fSopenharmony_ci{ 10483af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 10493af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE: 10503af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { 10513af6ab5fSopenharmony_ci return ParseRegularExpression(); 10523af6ab5fSopenharmony_ci } 10533af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 10543af6ab5fSopenharmony_ci return ParseArrayExpression(CarryPatternFlags(flags)); 10553af6ab5fSopenharmony_ci } 10563af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 10573af6ab5fSopenharmony_ci return ParseCoverParenthesizedExpressionAndArrowParameterList(); 10583af6ab5fSopenharmony_ci } 10593af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 10603af6ab5fSopenharmony_ci return ParseObjectExpression(CarryPatternFlags(flags)); 10613af6ab5fSopenharmony_ci } 10623af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BACK_TICK: { 10633af6ab5fSopenharmony_ci return ParseTemplateLiteral(); 10643af6ab5fSopenharmony_ci } 10653af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_HASH_MARK: { 10663af6ab5fSopenharmony_ci return ParseHashMaskOperator(); 10673af6ab5fSopenharmony_ci } 10683af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 10693af6ab5fSopenharmony_ci return ParsePrefixAssertionExpression(); 10703af6ab5fSopenharmony_ci } 10713af6ab5fSopenharmony_ci default: { 10723af6ab5fSopenharmony_ci UNREACHABLE(); 10733af6ab5fSopenharmony_ci } 10743af6ab5fSopenharmony_ci } 10753af6ab5fSopenharmony_ci return nullptr; 10763af6ab5fSopenharmony_ci} 10773af6ab5fSopenharmony_ci 10783af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 10793af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags) 10803af6ab5fSopenharmony_ci{ 10813af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 10823af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_IMPORT: { 10833af6ab5fSopenharmony_ci return ParseImportExpression(); 10843af6ab5fSopenharmony_ci } 10853af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE: 10863af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: 10873af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: 10883af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: 10893af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: 10903af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BACK_TICK: 10913af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_HASH_MARK: 10923af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 10933af6ab5fSopenharmony_ci return ParsePunctuators(flags); 10943af6ab5fSopenharmony_ci } 10953af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_FUNCTION: { 10963af6ab5fSopenharmony_ci return ParseFunctionExpression(); 10973af6ab5fSopenharmony_ci } 10983af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_CLASS: { 10993af6ab5fSopenharmony_ci return ParseClassExpression(); 11003af6ab5fSopenharmony_ci } 11013af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_THIS: { 11023af6ab5fSopenharmony_ci return ParseThisExpression(); 11033af6ab5fSopenharmony_ci } 11043af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_TYPEOF: { 11053af6ab5fSopenharmony_ci return ParseUnaryOrPrefixUpdateExpression(); 11063af6ab5fSopenharmony_ci } 11073af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_SUPER: { 11083af6ab5fSopenharmony_ci return ParseSuperExpression(); 11093af6ab5fSopenharmony_ci } 11103af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NEW: { 11113af6ab5fSopenharmony_ci ir::MetaProperty *newTarget = ParsePotentialNewTarget(); 11123af6ab5fSopenharmony_ci 11133af6ab5fSopenharmony_ci if (newTarget != nullptr) { 11143af6ab5fSopenharmony_ci return newTarget; 11153af6ab5fSopenharmony_ci } 11163af6ab5fSopenharmony_ci 11173af6ab5fSopenharmony_ci return ParseNewExpression(); 11183af6ab5fSopenharmony_ci } 11193af6ab5fSopenharmony_ci default: { 11203af6ab5fSopenharmony_ci break; 11213af6ab5fSopenharmony_ci } 11223af6ab5fSopenharmony_ci } 11233af6ab5fSopenharmony_ci 11243af6ab5fSopenharmony_ci return ParsePrimaryExpressionWithLiterals(flags); 11253af6ab5fSopenharmony_ci} 11263af6ab5fSopenharmony_ci 11273af6ab5fSopenharmony_cistatic constexpr size_t GetOperatorPrecedenceArithmeticAndComparison(const lexer::TokenType operatorType) 11283af6ab5fSopenharmony_ci{ 11293af6ab5fSopenharmony_ci switch (operatorType) { 11303af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EQUAL: 11313af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: 11323af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: 11333af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { 11343af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 8; 11353af6ab5fSopenharmony_ci return PRECEDENCE; 11363af6ab5fSopenharmony_ci } 11373af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: 11383af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: 11393af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_GREATER_THAN: 11403af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: 11413af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_INSTANCEOF: 11423af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_IN: { 11433af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 9; 11443af6ab5fSopenharmony_ci return PRECEDENCE; 11453af6ab5fSopenharmony_ci } 11463af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_PLUS: 11473af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MINUS: { 11483af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 12; 11493af6ab5fSopenharmony_ci return PRECEDENCE; 11503af6ab5fSopenharmony_ci } 11513af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MULTIPLY: 11523af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_DIVIDE: 11533af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MOD: { 11543af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 13; 11553af6ab5fSopenharmony_ci return PRECEDENCE; 11563af6ab5fSopenharmony_ci } 11573af6ab5fSopenharmony_ci default: { 11583af6ab5fSopenharmony_ci UNREACHABLE(); 11593af6ab5fSopenharmony_ci } 11603af6ab5fSopenharmony_ci } 11613af6ab5fSopenharmony_ci} 11623af6ab5fSopenharmony_ci 11633af6ab5fSopenharmony_cistatic constexpr size_t GetOperatorPrecedence(const lexer::TokenType operatorType) 11643af6ab5fSopenharmony_ci{ 11653af6ab5fSopenharmony_ci ASSERT(operatorType == lexer::TokenType::KEYW_AS || lexer::Token::IsBinaryToken(operatorType)); 11663af6ab5fSopenharmony_ci 11673af6ab5fSopenharmony_ci switch (operatorType) { 11683af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: { 11693af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 1; 11703af6ab5fSopenharmony_ci return PRECEDENCE; 11713af6ab5fSopenharmony_ci } 11723af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { 11733af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 2; 11743af6ab5fSopenharmony_ci return PRECEDENCE; 11753af6ab5fSopenharmony_ci } 11763af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { 11773af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 4; 11783af6ab5fSopenharmony_ci return PRECEDENCE; 11793af6ab5fSopenharmony_ci } 11803af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { 11813af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 5; 11823af6ab5fSopenharmony_ci return PRECEDENCE; 11833af6ab5fSopenharmony_ci } 11843af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { 11853af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 6; 11863af6ab5fSopenharmony_ci return PRECEDENCE; 11873af6ab5fSopenharmony_ci } 11883af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { 11893af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 7; 11903af6ab5fSopenharmony_ci return PRECEDENCE; 11913af6ab5fSopenharmony_ci } 11923af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: 11933af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: 11943af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: { 11953af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 10; 11963af6ab5fSopenharmony_ci return PRECEDENCE; 11973af6ab5fSopenharmony_ci } 11983af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_AS: { 11993af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 11; 12003af6ab5fSopenharmony_ci return PRECEDENCE; 12013af6ab5fSopenharmony_ci } 12023af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: { 12033af6ab5fSopenharmony_ci constexpr auto PRECEDENCE = 14; 12043af6ab5fSopenharmony_ci return PRECEDENCE; 12053af6ab5fSopenharmony_ci } 12063af6ab5fSopenharmony_ci default: { 12073af6ab5fSopenharmony_ci return GetOperatorPrecedenceArithmeticAndComparison(operatorType); 12083af6ab5fSopenharmony_ci } 12093af6ab5fSopenharmony_ci } 12103af6ab5fSopenharmony_ci} 12113af6ab5fSopenharmony_ci 12123af6ab5fSopenharmony_cistatic inline bool ShouldBinaryExpressionBeAmended(const ir::BinaryExpression *const binaryExpression, 12133af6ab5fSopenharmony_ci const lexer::TokenType operatorType) 12143af6ab5fSopenharmony_ci{ 12153af6ab5fSopenharmony_ci return GetOperatorPrecedence(binaryExpression->OperatorType()) <= GetOperatorPrecedence(operatorType) && 12163af6ab5fSopenharmony_ci !binaryExpression->IsGrouped() && 12173af6ab5fSopenharmony_ci (operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION || 12183af6ab5fSopenharmony_ci binaryExpression->OperatorType() != lexer::TokenType::PUNCTUATOR_EXPONENTIATION); 12193af6ab5fSopenharmony_ci} 12203af6ab5fSopenharmony_ci 12213af6ab5fSopenharmony_cistatic inline bool ShouldAsExpressionBeAmended(const ir::TSAsExpression *const asExpression, 12223af6ab5fSopenharmony_ci const lexer::TokenType operatorType) 12233af6ab5fSopenharmony_ci{ 12243af6ab5fSopenharmony_ci return GetOperatorPrecedence(lexer::TokenType::KEYW_AS) <= GetOperatorPrecedence(operatorType) && 12253af6ab5fSopenharmony_ci !asExpression->IsGrouped() && operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION; 12263af6ab5fSopenharmony_ci} 12273af6ab5fSopenharmony_ci 12283af6ab5fSopenharmony_cistatic inline bool ShouldExpressionBeAmended(const ir::Expression *const expression, 12293af6ab5fSopenharmony_ci const lexer::TokenType operatorType) 12303af6ab5fSopenharmony_ci{ 12313af6ab5fSopenharmony_ci bool shouldBeAmended = false; 12323af6ab5fSopenharmony_ci 12333af6ab5fSopenharmony_ci if (expression->IsBinaryExpression()) { 12343af6ab5fSopenharmony_ci shouldBeAmended = ShouldBinaryExpressionBeAmended(expression->AsBinaryExpression(), operatorType); 12353af6ab5fSopenharmony_ci } else if (expression->IsTSAsExpression()) { 12363af6ab5fSopenharmony_ci shouldBeAmended = ShouldAsExpressionBeAmended(expression->AsTSAsExpression(), operatorType); 12373af6ab5fSopenharmony_ci } 12383af6ab5fSopenharmony_ci 12393af6ab5fSopenharmony_ci return shouldBeAmended; 12403af6ab5fSopenharmony_ci} 12413af6ab5fSopenharmony_ci 12423af6ab5fSopenharmony_cistatic inline bool AreLogicalAndNullishMixedIncorrectly(const ir::Expression *const expression, 12433af6ab5fSopenharmony_ci const lexer::TokenType operatorType) 12443af6ab5fSopenharmony_ci{ 12453af6ab5fSopenharmony_ci return ((operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR || 12463af6ab5fSopenharmony_ci operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) && 12473af6ab5fSopenharmony_ci expression->IsBinaryExpression() && 12483af6ab5fSopenharmony_ci expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && 12493af6ab5fSopenharmony_ci !expression->IsGrouped()) || 12503af6ab5fSopenharmony_ci (operatorType == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && expression->IsBinaryExpression() && 12513af6ab5fSopenharmony_ci (expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR || 12523af6ab5fSopenharmony_ci expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) && 12533af6ab5fSopenharmony_ci !expression->IsGrouped()); 12543af6ab5fSopenharmony_ci} 12553af6ab5fSopenharmony_ci 12563af6ab5fSopenharmony_cistatic inline ir::Expression *GetAmendedChildExpression(ir::Expression *const expression) 12573af6ab5fSopenharmony_ci{ 12583af6ab5fSopenharmony_ci ir::Expression *amendedChild = nullptr; 12593af6ab5fSopenharmony_ci 12603af6ab5fSopenharmony_ci if (expression->IsBinaryExpression()) { 12613af6ab5fSopenharmony_ci amendedChild = expression->AsBinaryExpression()->Left(); 12623af6ab5fSopenharmony_ci } else if (expression->IsTSAsExpression()) { 12633af6ab5fSopenharmony_ci amendedChild = expression->AsTSAsExpression()->Expr(); 12643af6ab5fSopenharmony_ci } else { 12653af6ab5fSopenharmony_ci UNREACHABLE(); 12663af6ab5fSopenharmony_ci } 12673af6ab5fSopenharmony_ci 12683af6ab5fSopenharmony_ci return amendedChild; 12693af6ab5fSopenharmony_ci} 12703af6ab5fSopenharmony_ci 12713af6ab5fSopenharmony_cistatic inline void SetAmendedChildExpression(ir::Expression *const parent, ir::Expression *const amended) 12723af6ab5fSopenharmony_ci{ 12733af6ab5fSopenharmony_ci if (parent->IsBinaryExpression()) { 12743af6ab5fSopenharmony_ci parent->AsBinaryExpression()->SetLeft(amended); 12753af6ab5fSopenharmony_ci amended->SetParent(parent); 12763af6ab5fSopenharmony_ci } else if (parent->IsTSAsExpression()) { 12773af6ab5fSopenharmony_ci parent->AsTSAsExpression()->SetExpr(amended); 12783af6ab5fSopenharmony_ci amended->SetParent(parent); 12793af6ab5fSopenharmony_ci } else { 12803af6ab5fSopenharmony_ci UNREACHABLE(); 12813af6ab5fSopenharmony_ci } 12823af6ab5fSopenharmony_ci} 12833af6ab5fSopenharmony_ci 12843af6ab5fSopenharmony_civoid ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::Expression *const right, 12853af6ab5fSopenharmony_ci const lexer::TokenType operatorType) 12863af6ab5fSopenharmony_ci{ 12873af6ab5fSopenharmony_ci auto *amended = GetAmendedChildExpression(right); 12883af6ab5fSopenharmony_ci 12893af6ab5fSopenharmony_ci amended->SetParent(nullptr); // Next line overwrite parent 12903af6ab5fSopenharmony_ci auto *binaryExpr = AllocNode<ir::BinaryExpression>(left, amended, operatorType); 12913af6ab5fSopenharmony_ci 12923af6ab5fSopenharmony_ci binaryExpr->SetRange({left->Start(), amended->End()}); 12933af6ab5fSopenharmony_ci SetAmendedChildExpression(right, binaryExpr); 12943af6ab5fSopenharmony_ci} 12953af6ab5fSopenharmony_ci 12963af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseExpressionOrTypeAnnotation([[maybe_unused]] lexer::TokenType type, 12973af6ab5fSopenharmony_ci [[maybe_unused]] ExpressionParseFlags flags) 12983af6ab5fSopenharmony_ci{ 12993af6ab5fSopenharmony_ci return ParseExpression(ExpressionParseFlags::DISALLOW_YIELD); 13003af6ab5fSopenharmony_ci} 13013af6ab5fSopenharmony_ci 13023af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, ExpressionParseFlags flags) 13033af6ab5fSopenharmony_ci{ 13043af6ab5fSopenharmony_ci lexer::TokenType operatorType = lexer_->GetToken().Type(); 13053af6ab5fSopenharmony_ci ASSERT(lexer::Token::IsBinaryToken(operatorType)); 13063af6ab5fSopenharmony_ci 13073af6ab5fSopenharmony_ci if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) { 13083af6ab5fSopenharmony_ci if ((left->IsUnaryExpression() || left->IsTypeofExpression()) && !left->IsGrouped()) { 13093af6ab5fSopenharmony_ci ThrowSyntaxError( 13103af6ab5fSopenharmony_ci "Illegal expression. Wrap left hand side or entire " 13113af6ab5fSopenharmony_ci "exponentiation in parentheses."); 13123af6ab5fSopenharmony_ci } 13133af6ab5fSopenharmony_ci } 13143af6ab5fSopenharmony_ci 13153af6ab5fSopenharmony_ci lexer_->NextToken(); 13163af6ab5fSopenharmony_ci 13173af6ab5fSopenharmony_ci ExpressionParseFlags newFlags = ExpressionParseFlags::DISALLOW_YIELD; 13183af6ab5fSopenharmony_ci if ((operatorType == lexer::TokenType::KEYW_INSTANCEOF) || ((flags & ExpressionParseFlags::INSTANCEOF) != 0)) { 13193af6ab5fSopenharmony_ci newFlags |= ExpressionParseFlags::INSTANCEOF; 13203af6ab5fSopenharmony_ci } 13213af6ab5fSopenharmony_ci 13223af6ab5fSopenharmony_ci ir::Expression *rightExpr = ParseExpressionOrTypeAnnotation(operatorType, ExpressionParseFlags::DISALLOW_YIELD); 13233af6ab5fSopenharmony_ci ir::ConditionalExpression *conditionalExpr = nullptr; 13243af6ab5fSopenharmony_ci 13253af6ab5fSopenharmony_ci if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) { 13263af6ab5fSopenharmony_ci conditionalExpr = rightExpr->AsConditionalExpression(); 13273af6ab5fSopenharmony_ci rightExpr = conditionalExpr->Test(); 13283af6ab5fSopenharmony_ci } 13293af6ab5fSopenharmony_ci 13303af6ab5fSopenharmony_ci if (ShouldExpressionBeAmended(rightExpr, operatorType)) { 13313af6ab5fSopenharmony_ci if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) { 13323af6ab5fSopenharmony_ci ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators."); 13333af6ab5fSopenharmony_ci } 13343af6ab5fSopenharmony_ci 13353af6ab5fSopenharmony_ci bool shouldBeAmended = true; 13363af6ab5fSopenharmony_ci 13373af6ab5fSopenharmony_ci ir::Expression *expression = rightExpr; 13383af6ab5fSopenharmony_ci ir::Expression *parentExpression = nullptr; 13393af6ab5fSopenharmony_ci 13403af6ab5fSopenharmony_ci while (shouldBeAmended && GetAmendedChildExpression(expression)->IsBinaryExpression()) { 13413af6ab5fSopenharmony_ci parentExpression = expression; 13423af6ab5fSopenharmony_ci parentExpression->SetStart(left->Start()); 13433af6ab5fSopenharmony_ci 13443af6ab5fSopenharmony_ci expression = GetAmendedChildExpression(expression); 13453af6ab5fSopenharmony_ci 13463af6ab5fSopenharmony_ci shouldBeAmended = ShouldExpressionBeAmended(expression, operatorType); 13473af6ab5fSopenharmony_ci } 13483af6ab5fSopenharmony_ci 13493af6ab5fSopenharmony_ci CreateAmendedBinaryExpression(left, shouldBeAmended ? expression : parentExpression, operatorType); 13503af6ab5fSopenharmony_ci } else { 13513af6ab5fSopenharmony_ci if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) { 13523af6ab5fSopenharmony_ci ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators."); 13533af6ab5fSopenharmony_ci } 13543af6ab5fSopenharmony_ci const lexer::SourcePosition &endPos = rightExpr->End(); 13553af6ab5fSopenharmony_ci rightExpr = AllocNode<ir::BinaryExpression>(left, rightExpr, operatorType); 13563af6ab5fSopenharmony_ci rightExpr->SetRange({left->Start(), endPos}); 13573af6ab5fSopenharmony_ci } 13583af6ab5fSopenharmony_ci 13593af6ab5fSopenharmony_ci if (conditionalExpr != nullptr) { 13603af6ab5fSopenharmony_ci conditionalExpr->SetStart(rightExpr->Start()); 13613af6ab5fSopenharmony_ci conditionalExpr->SetTest(rightExpr); 13623af6ab5fSopenharmony_ci return conditionalExpr; 13633af6ab5fSopenharmony_ci } 13643af6ab5fSopenharmony_ci 13653af6ab5fSopenharmony_ci return rightExpr; 13663af6ab5fSopenharmony_ci} 13673af6ab5fSopenharmony_ci 13683af6ab5fSopenharmony_ciArenaVector<ir::Expression *> ParserImpl::ParseCallExpressionArguments(bool &trailingComma) 13693af6ab5fSopenharmony_ci{ 13703af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> arguments(Allocator()->Adapter()); 13713af6ab5fSopenharmony_ci 13723af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT && 13733af6ab5fSopenharmony_ci lexer_->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE)) { 13743af6ab5fSopenharmony_ci arguments = std::move(ParseExpressionsArrayFormatPlaceholder()); 13753af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 13763af6ab5fSopenharmony_ci ThrowSyntaxError("Expected a ')'"); 13773af6ab5fSopenharmony_ci } 13783af6ab5fSopenharmony_ci } else { 13793af6ab5fSopenharmony_ci while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 13803af6ab5fSopenharmony_ci trailingComma = false; 13813af6ab5fSopenharmony_ci ir::Expression *argument {}; 13823af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 13833af6ab5fSopenharmony_ci argument = ParseSpreadElement(); 13843af6ab5fSopenharmony_ci } else { 13853af6ab5fSopenharmony_ci argument = ParseExpression(); 13863af6ab5fSopenharmony_ci } 13873af6ab5fSopenharmony_ci 13883af6ab5fSopenharmony_ci arguments.push_back(argument); 13893af6ab5fSopenharmony_ci 13903af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 13913af6ab5fSopenharmony_ci lexer_->NextToken(); 13923af6ab5fSopenharmony_ci trailingComma = true; 13933af6ab5fSopenharmony_ci } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 13943af6ab5fSopenharmony_ci ThrowSyntaxError("Expected a ')'"); 13953af6ab5fSopenharmony_ci } 13963af6ab5fSopenharmony_ci } 13973af6ab5fSopenharmony_ci } 13983af6ab5fSopenharmony_ci 13993af6ab5fSopenharmony_ci return arguments; 14003af6ab5fSopenharmony_ci} 14013af6ab5fSopenharmony_ci 14023af6ab5fSopenharmony_ciir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool isOptionalChain, bool handleEval) 14033af6ab5fSopenharmony_ci{ 14043af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 14053af6ab5fSopenharmony_ci bool trailingComma {}; 14063af6ab5fSopenharmony_ci 14073af6ab5fSopenharmony_ci while (true) { 14083af6ab5fSopenharmony_ci lexer_->NextToken(); 14093af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> arguments = ParseCallExpressionArguments(trailingComma); 14103af6ab5fSopenharmony_ci ir::CallExpression *callExpr {}; 14113af6ab5fSopenharmony_ci 14123af6ab5fSopenharmony_ci if (!isOptionalChain && handleEval && callee->IsIdentifier() && callee->AsIdentifier()->Name().Is("eval")) { 14133af6ab5fSopenharmony_ci auto parserStatus = static_cast<uint32_t>(context_.Status() | ParserStatus::DIRECT_EVAL); 14143af6ab5fSopenharmony_ci callExpr = AllocNode<ir::DirectEvalExpression>(callee, std::move(arguments), nullptr, isOptionalChain, 14153af6ab5fSopenharmony_ci parserStatus); 14163af6ab5fSopenharmony_ci } else { 14173af6ab5fSopenharmony_ci callExpr = 14183af6ab5fSopenharmony_ci AllocNode<ir::CallExpression>(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma); 14193af6ab5fSopenharmony_ci } 14203af6ab5fSopenharmony_ci 14213af6ab5fSopenharmony_ci callExpr->SetRange({callee->Start(), lexer_->GetToken().End()}); 14223af6ab5fSopenharmony_ci isOptionalChain = false; 14233af6ab5fSopenharmony_ci 14243af6ab5fSopenharmony_ci lexer_->NextToken(); 14253af6ab5fSopenharmony_ci 14263af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 14273af6ab5fSopenharmony_ci ParseTrailingBlock(callExpr); 14283af6ab5fSopenharmony_ci return callExpr; 14293af6ab5fSopenharmony_ci } 14303af6ab5fSopenharmony_ci 14313af6ab5fSopenharmony_ci callee = callExpr; 14323af6ab5fSopenharmony_ci } 14333af6ab5fSopenharmony_ci 14343af6ab5fSopenharmony_ci UNREACHABLE(); 14353af6ab5fSopenharmony_ci} 14363af6ab5fSopenharmony_ci 14373af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) 14383af6ab5fSopenharmony_ci{ 14393af6ab5fSopenharmony_ci ir::Expression *returnExpression = nullptr; 14403af6ab5fSopenharmony_ci 14413af6ab5fSopenharmony_ci bool isPrivate = false; 14423af6ab5fSopenharmony_ci 14433af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) { 14443af6ab5fSopenharmony_ci isPrivate = true; 14453af6ab5fSopenharmony_ci ValidatePrivateIdentifier(); 14463af6ab5fSopenharmony_ci } 14473af6ab5fSopenharmony_ci 14483af6ab5fSopenharmony_ci const auto tokenType = lexer_->GetToken().Type(); 14493af6ab5fSopenharmony_ci if (tokenType == lexer::TokenType::LITERAL_IDENT) { 14503af6ab5fSopenharmony_ci auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator()); 14513af6ab5fSopenharmony_ci identNode->SetReference(); 14523af6ab5fSopenharmony_ci identNode->SetPrivate(isPrivate); 14533af6ab5fSopenharmony_ci identNode->SetRange(lexer_->GetToken().Loc()); 14543af6ab5fSopenharmony_ci 14553af6ab5fSopenharmony_ci returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, identNode, 14563af6ab5fSopenharmony_ci ir::MemberExpressionKind::PROPERTY_ACCESS, false, true); 14573af6ab5fSopenharmony_ci returnExpression->SetRange({leftSideExpr->Start(), identNode->End()}); 14583af6ab5fSopenharmony_ci lexer_->NextToken(); 14593af6ab5fSopenharmony_ci } 14603af6ab5fSopenharmony_ci 14613af6ab5fSopenharmony_ci if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 14623af6ab5fSopenharmony_ci lexer_->NextToken(); // eat '[' 14633af6ab5fSopenharmony_ci ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 14643af6ab5fSopenharmony_ci 14653af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 14663af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 14673af6ab5fSopenharmony_ci } 14683af6ab5fSopenharmony_ci 14693af6ab5fSopenharmony_ci returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, propertyNode, 14703af6ab5fSopenharmony_ci ir::MemberExpressionKind::ELEMENT_ACCESS, true, true); 14713af6ab5fSopenharmony_ci returnExpression->SetRange({leftSideExpr->Start(), lexer_->GetToken().End()}); 14723af6ab5fSopenharmony_ci lexer_->NextToken(); 14733af6ab5fSopenharmony_ci } 14743af6ab5fSopenharmony_ci 14753af6ab5fSopenharmony_ci if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 14763af6ab5fSopenharmony_ci returnExpression = ParseCallExpression(leftSideExpr, true); 14773af6ab5fSopenharmony_ci } 14783af6ab5fSopenharmony_ci 14793af6ab5fSopenharmony_ci // Static semantic 14803af6ab5fSopenharmony_ci if (tokenType == lexer::TokenType::PUNCTUATOR_BACK_TICK || 14813af6ab5fSopenharmony_ci lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) { 14823af6ab5fSopenharmony_ci ThrowSyntaxError("Tagged Template Literals are not allowed in optionalChain"); 14833af6ab5fSopenharmony_ci } 14843af6ab5fSopenharmony_ci 14853af6ab5fSopenharmony_ci return returnExpression; 14863af6ab5fSopenharmony_ci} 14873af6ab5fSopenharmony_ci 14883af6ab5fSopenharmony_ciir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expression **returnExpression, 14893af6ab5fSopenharmony_ci const lexer::SourcePosition &startLoc) 14903af6ab5fSopenharmony_ci{ 14913af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 14923af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_FUNCTION: { 14933af6ab5fSopenharmony_ci *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); 14943af6ab5fSopenharmony_ci (*returnExpression)->SetStart(startLoc); 14953af6ab5fSopenharmony_ci break; 14963af6ab5fSopenharmony_ci } 14973af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 14983af6ab5fSopenharmony_ci ir::Expression *identRef = ParsePrimaryExpression(); 14993af6ab5fSopenharmony_ci ASSERT(identRef->IsIdentifier()); 15003af6ab5fSopenharmony_ci 15013af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 15023af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected '=>'"); 15033af6ab5fSopenharmony_ci } 15043af6ab5fSopenharmony_ci 15053af6ab5fSopenharmony_ci ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true); 15063af6ab5fSopenharmony_ci arrowFuncExpr->SetStart(startLoc); 15073af6ab5fSopenharmony_ci 15083af6ab5fSopenharmony_ci return arrowFuncExpr; 15093af6ab5fSopenharmony_ci } 15103af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_ARROW: { 15113af6ab5fSopenharmony_ci ir::ArrowFunctionExpression *arrowFuncExpr = 15123af6ab5fSopenharmony_ci ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true); 15133af6ab5fSopenharmony_ci arrowFuncExpr->SetStart(startLoc); 15143af6ab5fSopenharmony_ci return arrowFuncExpr; 15153af6ab5fSopenharmony_ci } 15163af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 15173af6ab5fSopenharmony_ci ir::CallExpression *callExpression = ParseCallExpression(*returnExpression, false); 15183af6ab5fSopenharmony_ci 15193af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) { 15203af6ab5fSopenharmony_ci ir::ArrowFunctionExpression *arrowFuncExpr = 15213af6ab5fSopenharmony_ci ParseArrowFunctionExpression(callExpression, nullptr, nullptr, true); 15223af6ab5fSopenharmony_ci arrowFuncExpr->SetStart(startLoc); 15233af6ab5fSopenharmony_ci 15243af6ab5fSopenharmony_ci return arrowFuncExpr; 15253af6ab5fSopenharmony_ci } 15263af6ab5fSopenharmony_ci 15273af6ab5fSopenharmony_ci *returnExpression = callExpression; 15283af6ab5fSopenharmony_ci break; 15293af6ab5fSopenharmony_ci } 15303af6ab5fSopenharmony_ci default: { 15313af6ab5fSopenharmony_ci break; 15323af6ab5fSopenharmony_ci } 15333af6ab5fSopenharmony_ci } 15343af6ab5fSopenharmony_ci 15353af6ab5fSopenharmony_ci return nullptr; 15363af6ab5fSopenharmony_ci} 15373af6ab5fSopenharmony_ci 15383af6ab5fSopenharmony_cibool ParserImpl::ParsePotentialGenericFunctionCall([[maybe_unused]] ir::Expression *primaryExpr, 15393af6ab5fSopenharmony_ci [[maybe_unused]] ir::Expression **returnExpression, 15403af6ab5fSopenharmony_ci [[maybe_unused]] const lexer::SourcePosition &startLoc, 15413af6ab5fSopenharmony_ci [[maybe_unused]] bool ignoreCallExpression) 15423af6ab5fSopenharmony_ci{ 15433af6ab5fSopenharmony_ci return true; 15443af6ab5fSopenharmony_ci} 15453af6ab5fSopenharmony_ci 15463af6ab5fSopenharmony_cibool ParserImpl::ParsePotentialNonNullExpression([[maybe_unused]] ir::Expression **returnExpression, 15473af6ab5fSopenharmony_ci [[maybe_unused]] lexer::SourcePosition startLoc) 15483af6ab5fSopenharmony_ci{ 15493af6ab5fSopenharmony_ci return true; 15503af6ab5fSopenharmony_ci} 15513af6ab5fSopenharmony_ci 15523af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePotentialAsExpression([[maybe_unused]] ir::Expression *primaryExpression) 15533af6ab5fSopenharmony_ci{ 15543af6ab5fSopenharmony_ci return nullptr; 15553af6ab5fSopenharmony_ci} 15563af6ab5fSopenharmony_ci 15573af6ab5fSopenharmony_ciir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr, bool isOptional) 15583af6ab5fSopenharmony_ci{ 15593af6ab5fSopenharmony_ci lexer_->NextToken(); // eat '[' 15603af6ab5fSopenharmony_ci ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 15613af6ab5fSopenharmony_ci 15623af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 15633af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 15643af6ab5fSopenharmony_ci } 15653af6ab5fSopenharmony_ci 15663af6ab5fSopenharmony_ci auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, propertyNode, 15673af6ab5fSopenharmony_ci ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional); 15683af6ab5fSopenharmony_ci memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()}); 15693af6ab5fSopenharmony_ci lexer_->NextToken(); 15703af6ab5fSopenharmony_ci return memberExpr; 15713af6ab5fSopenharmony_ci} 15723af6ab5fSopenharmony_ci 15733af6ab5fSopenharmony_ciir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *primaryExpr) 15743af6ab5fSopenharmony_ci{ 15753af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK); 15763af6ab5fSopenharmony_ci 15773af6ab5fSopenharmony_ci lexer::SourcePosition memberStart = lexer_->GetToken().Start(); 15783af6ab5fSopenharmony_ci ValidatePrivateIdentifier(); 15793af6ab5fSopenharmony_ci 15803af6ab5fSopenharmony_ci auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator()); 15813af6ab5fSopenharmony_ci privateIdent->SetRange({memberStart, lexer_->GetToken().End()}); 15823af6ab5fSopenharmony_ci privateIdent->SetPrivate(true); 15833af6ab5fSopenharmony_ci privateIdent->SetReference(); 15843af6ab5fSopenharmony_ci lexer_->NextToken(); 15853af6ab5fSopenharmony_ci 15863af6ab5fSopenharmony_ci auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, privateIdent, 15873af6ab5fSopenharmony_ci ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); 15883af6ab5fSopenharmony_ci memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()}); 15893af6ab5fSopenharmony_ci return memberExpr; 15903af6ab5fSopenharmony_ci} 15913af6ab5fSopenharmony_ci 15923af6ab5fSopenharmony_ciir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExpr, bool isOptional) 15933af6ab5fSopenharmony_ci{ 15943af6ab5fSopenharmony_ci ir::Identifier *ident = ExpectIdentifier(true); 15953af6ab5fSopenharmony_ci if (ident == nullptr) { // Error processing. 15963af6ab5fSopenharmony_ci return nullptr; 15973af6ab5fSopenharmony_ci } 15983af6ab5fSopenharmony_ci 15993af6ab5fSopenharmony_ci auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, 16003af6ab5fSopenharmony_ci false, isOptional); 16013af6ab5fSopenharmony_ci memberExpr->SetRange({primaryExpr->Start(), ident->End()}); 16023af6ab5fSopenharmony_ci 16033af6ab5fSopenharmony_ci return memberExpr; 16043af6ab5fSopenharmony_ci} 16053af6ab5fSopenharmony_ci 16063af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, 16073af6ab5fSopenharmony_ci bool ignoreCallExpression, bool *isChainExpression) 16083af6ab5fSopenharmony_ci{ 16093af6ab5fSopenharmony_ci ir::Expression *returnExpr = primaryExpr; 16103af6ab5fSopenharmony_ci while (true) { 16113af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 16123af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 16133af6ab5fSopenharmony_ci returnExpr = ParseElementAccess(returnExpr); 16143af6ab5fSopenharmony_ci continue; 16153af6ab5fSopenharmony_ci } 16163af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 16173af6ab5fSopenharmony_ci if (auto *asExpression = ParsePotentialAsExpression(returnExpr); asExpression != nullptr) { 16183af6ab5fSopenharmony_ci return asExpression; 16193af6ab5fSopenharmony_ci } 16203af6ab5fSopenharmony_ci break; 16213af6ab5fSopenharmony_ci } 16223af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: 16233af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 16243af6ab5fSopenharmony_ci if (ParsePotentialGenericFunctionCall(primaryExpr, &returnExpr, startLoc, ignoreCallExpression)) { 16253af6ab5fSopenharmony_ci break; 16263af6ab5fSopenharmony_ci } 16273af6ab5fSopenharmony_ci continue; 16283af6ab5fSopenharmony_ci } 16293af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BACK_TICK: { 16303af6ab5fSopenharmony_ci returnExpr = ParsePostPrimaryExpressionBackTick(returnExpr, startLoc); 16313af6ab5fSopenharmony_ci continue; 16323af6ab5fSopenharmony_ci } 16333af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 16343af6ab5fSopenharmony_ci if (ignoreCallExpression) { 16353af6ab5fSopenharmony_ci break; 16363af6ab5fSopenharmony_ci } 16373af6ab5fSopenharmony_ci returnExpr = ParseCallExpression(returnExpr, false); 16383af6ab5fSopenharmony_ci continue; 16393af6ab5fSopenharmony_ci } 16403af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { 16413af6ab5fSopenharmony_ci if (ParsePotentialNonNullExpression(&returnExpr, startLoc)) { 16423af6ab5fSopenharmony_ci break; 16433af6ab5fSopenharmony_ci } 16443af6ab5fSopenharmony_ci continue; 16453af6ab5fSopenharmony_ci } 16463af6ab5fSopenharmony_ci default: { 16473af6ab5fSopenharmony_ci auto tmp = ParsePostPrimaryExpressionDot(returnExpr, lexer_->GetToken().Type(), isChainExpression); 16483af6ab5fSopenharmony_ci if (tmp != nullptr) { 16493af6ab5fSopenharmony_ci returnExpr = tmp; 16503af6ab5fSopenharmony_ci continue; 16513af6ab5fSopenharmony_ci } 16523af6ab5fSopenharmony_ci } 16533af6ab5fSopenharmony_ci } 16543af6ab5fSopenharmony_ci break; 16553af6ab5fSopenharmony_ci } 16563af6ab5fSopenharmony_ci return returnExpr; 16573af6ab5fSopenharmony_ci} 16583af6ab5fSopenharmony_ci 16593af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *returnExpression, 16603af6ab5fSopenharmony_ci const lexer::SourcePosition startLoc) 16613af6ab5fSopenharmony_ci{ 16623af6ab5fSopenharmony_ci ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); 16633af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = propertyNode->End(); 16643af6ab5fSopenharmony_ci 16653af6ab5fSopenharmony_ci returnExpression = AllocNode<ir::TaggedTemplateExpression>(returnExpression, propertyNode, nullptr); 16663af6ab5fSopenharmony_ci returnExpression->SetRange({startLoc, endLoc}); 16673af6ab5fSopenharmony_ci 16683af6ab5fSopenharmony_ci return returnExpression; 16693af6ab5fSopenharmony_ci} 16703af6ab5fSopenharmony_ci 16713af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePostPrimaryExpressionDot(ir::Expression *returnExpression, 16723af6ab5fSopenharmony_ci const lexer::TokenType tokenType, bool *isChainExpression) 16733af6ab5fSopenharmony_ci{ 16743af6ab5fSopenharmony_ci switch (tokenType) { 16753af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: { 16763af6ab5fSopenharmony_ci *isChainExpression = true; 16773af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat ?. 16783af6ab5fSopenharmony_ci return ParseOptionalChain(returnExpression); 16793af6ab5fSopenharmony_ci } 16803af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_PERIOD: { 16813af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat period 16823af6ab5fSopenharmony_ci 16833af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) { 16843af6ab5fSopenharmony_ci return ParsePrivatePropertyAccess(returnExpression); 16853af6ab5fSopenharmony_ci } 16863af6ab5fSopenharmony_ci 16873af6ab5fSopenharmony_ci return ParsePropertyAccess(returnExpression); 16883af6ab5fSopenharmony_ci } 16893af6ab5fSopenharmony_ci default: { 16903af6ab5fSopenharmony_ci break; 16913af6ab5fSopenharmony_ci } 16923af6ab5fSopenharmony_ci } 16933af6ab5fSopenharmony_ci 16943af6ab5fSopenharmony_ci return nullptr; 16953af6ab5fSopenharmony_ci} 16963af6ab5fSopenharmony_ci 16973af6ab5fSopenharmony_civoid ParserImpl::ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression) 16983af6ab5fSopenharmony_ci{ 16993af6ab5fSopenharmony_ci if ((!returnExpression->IsMemberExpression() && !returnExpression->IsIdentifier() && 17003af6ab5fSopenharmony_ci !returnExpression->IsTSNonNullExpression()) || 17013af6ab5fSopenharmony_ci isChainExpression) { 17023af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid left-hand side operator."); 17033af6ab5fSopenharmony_ci } 17043af6ab5fSopenharmony_ci 17053af6ab5fSopenharmony_ci if (returnExpression->IsIdentifier()) { 17063af6ab5fSopenharmony_ci const util::StringView &returnExpressionStr = returnExpression->AsIdentifier()->Name(); 17073af6ab5fSopenharmony_ci 17083af6ab5fSopenharmony_ci if (returnExpressionStr.Is("eval")) { 17093af6ab5fSopenharmony_ci ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid"); 17103af6ab5fSopenharmony_ci } 17113af6ab5fSopenharmony_ci 17123af6ab5fSopenharmony_ci if (returnExpressionStr.Is("arguments")) { 17133af6ab5fSopenharmony_ci ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid"); 17143af6ab5fSopenharmony_ci } 17153af6ab5fSopenharmony_ci } 17163af6ab5fSopenharmony_ci} 17173af6ab5fSopenharmony_ci 17183af6ab5fSopenharmony_ciir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::SourcePosition startLoc) 17193af6ab5fSopenharmony_ci{ 17203af6ab5fSopenharmony_ci auto expr = top; 17213af6ab5fSopenharmony_ci while (expr->IsTSNonNullExpression()) { 17223af6ab5fSopenharmony_ci expr = expr->AsTSNonNullExpression()->Expr(); 17233af6ab5fSopenharmony_ci } 17243af6ab5fSopenharmony_ci auto chainParent = expr->Parent(); 17253af6ab5fSopenharmony_ci 17263af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = expr->End(); 17273af6ab5fSopenharmony_ci auto chain = AllocNode<ir::ChainExpression>(expr); 17283af6ab5fSopenharmony_ci chain->SetRange({startLoc, endLoc}); 17293af6ab5fSopenharmony_ci 17303af6ab5fSopenharmony_ci if (expr == top) { 17313af6ab5fSopenharmony_ci return chain; 17323af6ab5fSopenharmony_ci } 17333af6ab5fSopenharmony_ci chainParent->AsTSNonNullExpression()->SetExpr(chain); 17343af6ab5fSopenharmony_ci chain->SetParent(chainParent); 17353af6ab5fSopenharmony_ci return top; 17363af6ab5fSopenharmony_ci} 17373af6ab5fSopenharmony_ci 17383af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, ExpressionParseFlags flags) 17393af6ab5fSopenharmony_ci{ 17403af6ab5fSopenharmony_ci bool isAsync = lexer_->GetToken().IsAsyncModifier(); 17413af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 17423af6ab5fSopenharmony_ci ir::Expression *returnExpression = ParsePrimaryExpression(flags); 17433af6ab5fSopenharmony_ci 17443af6ab5fSopenharmony_ci if (lexer_->GetToken().NewLine() && returnExpression->IsArrowFunctionExpression()) { 17453af6ab5fSopenharmony_ci return returnExpression; 17463af6ab5fSopenharmony_ci } 17473af6ab5fSopenharmony_ci 17483af6ab5fSopenharmony_ci if (isAsync && !lexer_->GetToken().NewLine()) { 17493af6ab5fSopenharmony_ci context_.Status() |= ParserStatus::ASYNC_FUNCTION; 17503af6ab5fSopenharmony_ci ir::ArrowFunctionExpression *arrow = ParsePotentialArrowExpression(&returnExpression, startLoc); 17513af6ab5fSopenharmony_ci 17523af6ab5fSopenharmony_ci if (arrow != nullptr) { 17533af6ab5fSopenharmony_ci return arrow; 17543af6ab5fSopenharmony_ci } 17553af6ab5fSopenharmony_ci } 17563af6ab5fSopenharmony_ci 17573af6ab5fSopenharmony_ci bool isChainExpression; 17583af6ab5fSopenharmony_ci ir::Expression *prevExpression; 17593af6ab5fSopenharmony_ci do { 17603af6ab5fSopenharmony_ci isChainExpression = false; 17613af6ab5fSopenharmony_ci prevExpression = returnExpression; 17623af6ab5fSopenharmony_ci returnExpression = 17633af6ab5fSopenharmony_ci ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression); 17643af6ab5fSopenharmony_ci if (isChainExpression) { 17653af6ab5fSopenharmony_ci returnExpression = SetupChainExpr(returnExpression, startLoc); 17663af6ab5fSopenharmony_ci } 17673af6ab5fSopenharmony_ci } while (prevExpression != returnExpression); 17683af6ab5fSopenharmony_ci 17693af6ab5fSopenharmony_ci if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) { 17703af6ab5fSopenharmony_ci lexer::SourcePosition start = returnExpression->Start(); 17713af6ab5fSopenharmony_ci 17723af6ab5fSopenharmony_ci ValidateUpdateExpression(returnExpression, isChainExpression); 17733af6ab5fSopenharmony_ci 17743af6ab5fSopenharmony_ci returnExpression = AllocNode<ir::UpdateExpression>(returnExpression, lexer_->GetToken().Type(), false); 17753af6ab5fSopenharmony_ci 17763af6ab5fSopenharmony_ci returnExpression->SetRange({start, lexer_->GetToken().End()}); 17773af6ab5fSopenharmony_ci lexer_->NextToken(); 17783af6ab5fSopenharmony_ci } 17793af6ab5fSopenharmony_ci 17803af6ab5fSopenharmony_ci return returnExpression; 17813af6ab5fSopenharmony_ci} 17823af6ab5fSopenharmony_ci 17833af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 17843af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault) 17853af6ab5fSopenharmony_ci{ 17863af6ab5fSopenharmony_ci ir::Expression *returnNode = nullptr; 17873af6ab5fSopenharmony_ci 17883af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 17893af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 17903af6ab5fSopenharmony_ci returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN); 17913af6ab5fSopenharmony_ci break; 17923af6ab5fSopenharmony_ci } 17933af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: { 17943af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::IN_REST) != 0) { 17953af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 17963af6ab5fSopenharmony_ci } 17973af6ab5fSopenharmony_ci returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN); 17983af6ab5fSopenharmony_ci break; 17993af6ab5fSopenharmony_ci } 18003af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 18013af6ab5fSopenharmony_ci returnNode = 18023af6ab5fSopenharmony_ci ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN); 18033af6ab5fSopenharmony_ci break; 18043af6ab5fSopenharmony_ci } 18053af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 18063af6ab5fSopenharmony_ci returnNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator()); 18073af6ab5fSopenharmony_ci returnNode->AsIdentifier()->SetReference(); 18083af6ab5fSopenharmony_ci returnNode->SetRange(lexer_->GetToken().Loc()); 18093af6ab5fSopenharmony_ci lexer_->NextToken(); 18103af6ab5fSopenharmony_ci break; 18113af6ab5fSopenharmony_ci } 18123af6ab5fSopenharmony_ci default: { 18133af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected an identifier."); 18143af6ab5fSopenharmony_ci } 18153af6ab5fSopenharmony_ci } 18163af6ab5fSopenharmony_ci 18173af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 18183af6ab5fSopenharmony_ci return returnNode; 18193af6ab5fSopenharmony_ci } 18203af6ab5fSopenharmony_ci 18213af6ab5fSopenharmony_ci ParsePatternElementErrorCheck(flags, allowDefault); 18223af6ab5fSopenharmony_ci 18233af6ab5fSopenharmony_ci ir::Expression *rightNode = ParseExpression(); 18243af6ab5fSopenharmony_ci 18253af6ab5fSopenharmony_ci auto *assignmentExpression = AllocNode<ir::AssignmentExpression>( 18263af6ab5fSopenharmony_ci ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); 18273af6ab5fSopenharmony_ci assignmentExpression->SetRange({returnNode->Start(), rightNode->End()}); 18283af6ab5fSopenharmony_ci 18293af6ab5fSopenharmony_ci return assignmentExpression; 18303af6ab5fSopenharmony_ci} 18313af6ab5fSopenharmony_ci 18323af6ab5fSopenharmony_civoid ParserImpl::ParsePatternElementErrorCheck(const ExpressionParseFlags flags, const bool allowDefault) 18333af6ab5fSopenharmony_ci{ 18343af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::IN_REST) != 0) { 18353af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ')'"); 18363af6ab5fSopenharmony_ci } 18373af6ab5fSopenharmony_ci 18383af6ab5fSopenharmony_ci if (!allowDefault) { 18393af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid destructuring assignment target"); 18403af6ab5fSopenharmony_ci } 18413af6ab5fSopenharmony_ci 18423af6ab5fSopenharmony_ci lexer_->NextToken(); 18433af6ab5fSopenharmony_ci 18443af6ab5fSopenharmony_ci if (context_.IsGenerator() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD) { 18453af6ab5fSopenharmony_ci ThrowSyntaxError("Yield is not allowed in generator parameters"); 18463af6ab5fSopenharmony_ci } 18473af6ab5fSopenharmony_ci 18483af6ab5fSopenharmony_ci if (context_.IsAsync() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_AWAIT) { 18493af6ab5fSopenharmony_ci ThrowSyntaxError("Illegal await-expression in formal parameters of async function"); 18503af6ab5fSopenharmony_ci } 18513af6ab5fSopenharmony_ci} 18523af6ab5fSopenharmony_ci 18533af6ab5fSopenharmony_civoid ParserImpl::CheckPropertyKeyAsyncModifier(ParserStatus *methodStatus) 18543af6ab5fSopenharmony_ci{ 18553af6ab5fSopenharmony_ci const auto asyncPos = lexer_->Save(); 18563af6ab5fSopenharmony_ci lexer_->NextToken(); 18573af6ab5fSopenharmony_ci 18583af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 18593af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON && 18603af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 18613af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 18623af6ab5fSopenharmony_ci if (lexer_->GetToken().NewLine()) { 18633af6ab5fSopenharmony_ci ThrowSyntaxError( 18643af6ab5fSopenharmony_ci "Async methods cannot have a line terminator between " 18653af6ab5fSopenharmony_ci "'async' and the property name"); 18663af6ab5fSopenharmony_ci } 18673af6ab5fSopenharmony_ci 18683af6ab5fSopenharmony_ci *methodStatus |= ParserStatus::ASYNC_FUNCTION; 18693af6ab5fSopenharmony_ci } else { 18703af6ab5fSopenharmony_ci lexer_->Rewind(asyncPos); 18713af6ab5fSopenharmony_ci } 18723af6ab5fSopenharmony_ci} 18733af6ab5fSopenharmony_ci 18743af6ab5fSopenharmony_cistatic bool IsAccessorDelimiter(char32_t cp) 18753af6ab5fSopenharmony_ci{ 18763af6ab5fSopenharmony_ci switch (cp) { 18773af6ab5fSopenharmony_ci case lexer::LEX_CHAR_LEFT_PAREN: 18783af6ab5fSopenharmony_ci case lexer::LEX_CHAR_COLON: 18793af6ab5fSopenharmony_ci case lexer::LEX_CHAR_COMMA: 18803af6ab5fSopenharmony_ci case lexer::LEX_CHAR_RIGHT_BRACE: { 18813af6ab5fSopenharmony_ci return true; 18823af6ab5fSopenharmony_ci } 18833af6ab5fSopenharmony_ci default: { 18843af6ab5fSopenharmony_ci return false; 18853af6ab5fSopenharmony_ci } 18863af6ab5fSopenharmony_ci } 18873af6ab5fSopenharmony_ci} 18883af6ab5fSopenharmony_ci 18893af6ab5fSopenharmony_cistatic bool IsShorthandDelimiter(char32_t cp) 18903af6ab5fSopenharmony_ci{ 18913af6ab5fSopenharmony_ci switch (cp) { 18923af6ab5fSopenharmony_ci case lexer::LEX_CHAR_EQUALS: 18933af6ab5fSopenharmony_ci case lexer::LEX_CHAR_COMMA: 18943af6ab5fSopenharmony_ci case lexer::LEX_CHAR_RIGHT_BRACE: { 18953af6ab5fSopenharmony_ci return true; 18963af6ab5fSopenharmony_ci } 18973af6ab5fSopenharmony_ci default: { 18983af6ab5fSopenharmony_ci return false; 18993af6ab5fSopenharmony_ci } 19003af6ab5fSopenharmony_ci } 19013af6ab5fSopenharmony_ci} 19023af6ab5fSopenharmony_ci 19033af6ab5fSopenharmony_civoid ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags) 19043af6ab5fSopenharmony_ci{ 19053af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) { 19063af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 19073af6ab5fSopenharmony_ci } 19083af6ab5fSopenharmony_ci 19093af6ab5fSopenharmony_ci if ((currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { 19103af6ab5fSopenharmony_ci ThrowSyntaxError("Keyword must not contain escaped characters"); 19113af6ab5fSopenharmony_ci } 19123af6ab5fSopenharmony_ci} 19133af6ab5fSopenharmony_ci 19143af6ab5fSopenharmony_ciir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos) 19153af6ab5fSopenharmony_ci{ 19163af6ab5fSopenharmony_ci char32_t nextCp = lexer_->Lookahead(); 19173af6ab5fSopenharmony_ci lexer::TokenType keywordType = lexer_->GetToken().KeywordType(); 19183af6ab5fSopenharmony_ci 19193af6ab5fSopenharmony_ci /* Rewind the lexer to the beginning of the ident to reparse as common 19203af6ab5fSopenharmony_ci * identifier */ 19213af6ab5fSopenharmony_ci lexer_->Rewind(*startPos); 19223af6ab5fSopenharmony_ci lexer_->NextToken(); 19233af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 19243af6ab5fSopenharmony_ci 19253af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 19263af6ab5fSopenharmony_ci ThrowSyntaxError("Expected an identifier"); 19273af6ab5fSopenharmony_ci } 19283af6ab5fSopenharmony_ci 19293af6ab5fSopenharmony_ci const util::StringView &ident = lexer_->GetToken().Ident(); 19303af6ab5fSopenharmony_ci 19313af6ab5fSopenharmony_ci auto *key = AllocNode<ir::Identifier>(ident, Allocator()); 19323af6ab5fSopenharmony_ci key->SetRange(lexer_->GetToken().Loc()); 19333af6ab5fSopenharmony_ci 19343af6ab5fSopenharmony_ci ir::Expression *value = AllocNode<ir::Identifier>(ident, Allocator()); 19353af6ab5fSopenharmony_ci value->AsIdentifier()->SetReference(); 19363af6ab5fSopenharmony_ci value->SetRange(lexer_->GetToken().Loc()); 19373af6ab5fSopenharmony_ci 19383af6ab5fSopenharmony_ci lexer::SourcePosition end; 19393af6ab5fSopenharmony_ci 19403af6ab5fSopenharmony_ci if (nextCp == lexer::LEX_CHAR_EQUALS) { 19413af6ab5fSopenharmony_ci CheckRestrictedBinding(keywordType); 19423af6ab5fSopenharmony_ci 19433af6ab5fSopenharmony_ci lexer_->NextToken(); // substitution 19443af6ab5fSopenharmony_ci lexer_->NextToken(); // eat substitution 19453af6ab5fSopenharmony_ci 19463af6ab5fSopenharmony_ci ir::Expression *rightNode = ParseExpression(); 19473af6ab5fSopenharmony_ci 19483af6ab5fSopenharmony_ci auto *assignmentExpression = AllocNode<ir::AssignmentExpression>( 19493af6ab5fSopenharmony_ci ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); 19503af6ab5fSopenharmony_ci assignmentExpression->SetRange({value->Start(), rightNode->End()}); 19513af6ab5fSopenharmony_ci end = rightNode->End(); 19523af6ab5fSopenharmony_ci value = assignmentExpression; 19533af6ab5fSopenharmony_ci } else { 19543af6ab5fSopenharmony_ci end = lexer_->GetToken().End(); 19553af6ab5fSopenharmony_ci lexer_->NextToken(); 19563af6ab5fSopenharmony_ci } 19573af6ab5fSopenharmony_ci 19583af6ab5fSopenharmony_ci auto *returnProperty = AllocNode<ir::Property>(key, value); 19593af6ab5fSopenharmony_ci returnProperty->SetRange({start, end}); 19603af6ab5fSopenharmony_ci 19613af6ab5fSopenharmony_ci return returnProperty; 19623af6ab5fSopenharmony_ci} 19633af6ab5fSopenharmony_ci 19643af6ab5fSopenharmony_cibool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::PropertyKind *propertyKind, 19653af6ab5fSopenharmony_ci ParserStatus *methodStatus) 19663af6ab5fSopenharmony_ci{ 19673af6ab5fSopenharmony_ci if (lexer_->GetToken().IsAsyncModifier()) { 19683af6ab5fSopenharmony_ci CheckPropertyKeyAsyncModifier(methodStatus); 19693af6ab5fSopenharmony_ci } 19703af6ab5fSopenharmony_ci 19713af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { 19723af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) { 19733af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 19743af6ab5fSopenharmony_ci } 19753af6ab5fSopenharmony_ci 19763af6ab5fSopenharmony_ci lexer_->NextToken(); 19773af6ab5fSopenharmony_ci *methodStatus |= ParserStatus::GENERATOR_FUNCTION; 19783af6ab5fSopenharmony_ci } 19793af6ab5fSopenharmony_ci 19803af6ab5fSopenharmony_ci lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags(); 19813af6ab5fSopenharmony_ci char32_t nextCp = lexer_->Lookahead(); 19823af6ab5fSopenharmony_ci lexer::TokenType keywordType = lexer_->GetToken().KeywordType(); 19833af6ab5fSopenharmony_ci // Parse getter property 19843af6ab5fSopenharmony_ci if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) { 19853af6ab5fSopenharmony_ci ValidateAccessor(flags, currentTokenFlags); 19863af6ab5fSopenharmony_ci 19873af6ab5fSopenharmony_ci *propertyKind = ir::PropertyKind::GET; 19883af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 19893af6ab5fSopenharmony_ci 19903af6ab5fSopenharmony_ci return false; 19913af6ab5fSopenharmony_ci } 19923af6ab5fSopenharmony_ci 19933af6ab5fSopenharmony_ci // Parse setter property 19943af6ab5fSopenharmony_ci if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) { 19953af6ab5fSopenharmony_ci ValidateAccessor(flags, currentTokenFlags); 19963af6ab5fSopenharmony_ci 19973af6ab5fSopenharmony_ci *propertyKind = ir::PropertyKind::SET; 19983af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 19993af6ab5fSopenharmony_ci 20003af6ab5fSopenharmony_ci return false; 20013af6ab5fSopenharmony_ci } 20023af6ab5fSopenharmony_ci 20033af6ab5fSopenharmony_ci // Parse shorthand property or assignment pattern 20043af6ab5fSopenharmony_ci return (IsShorthandDelimiter(nextCp) && (*methodStatus & ParserStatus::ASYNC_FUNCTION) == 0); 20053af6ab5fSopenharmony_ci} 20063af6ab5fSopenharmony_ci 20073af6ab5fSopenharmony_civoid ParserImpl::ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus) 20083af6ab5fSopenharmony_ci{ 20093af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) { 20103af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 20113af6ab5fSopenharmony_ci } 20123af6ab5fSopenharmony_ci 20133af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 20143af6ab5fSopenharmony_ci *methodStatus |= ParserStatus::GENERATOR_FUNCTION; 20153af6ab5fSopenharmony_ci} 20163af6ab5fSopenharmony_ci 20173af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) 20183af6ab5fSopenharmony_ci{ 20193af6ab5fSopenharmony_ci ir::Expression *key = nullptr; 20203af6ab5fSopenharmony_ci 20213af6ab5fSopenharmony_ci switch (lexer_->GetToken().Type()) { 20223af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 20233af6ab5fSopenharmony_ci const util::StringView &ident = lexer_->GetToken().Ident(); 20243af6ab5fSopenharmony_ci key = AllocNode<ir::Identifier>(ident, Allocator()); 20253af6ab5fSopenharmony_ci key->SetRange(lexer_->GetToken().Loc()); 20263af6ab5fSopenharmony_ci break; 20273af6ab5fSopenharmony_ci } 20283af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: { 20293af6ab5fSopenharmony_ci const util::StringView &string = lexer_->GetToken().String(); 20303af6ab5fSopenharmony_ci key = AllocNode<ir::StringLiteral>(string); 20313af6ab5fSopenharmony_ci key->SetRange(lexer_->GetToken().Loc()); 20323af6ab5fSopenharmony_ci break; 20333af6ab5fSopenharmony_ci } 20343af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: { 20353af6ab5fSopenharmony_ci if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { 20363af6ab5fSopenharmony_ci key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt()); 20373af6ab5fSopenharmony_ci } else { 20383af6ab5fSopenharmony_ci key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber()); 20393af6ab5fSopenharmony_ci } 20403af6ab5fSopenharmony_ci 20413af6ab5fSopenharmony_ci key->SetRange(lexer_->GetToken().Loc()); 20423af6ab5fSopenharmony_ci break; 20433af6ab5fSopenharmony_ci } 20443af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 20453af6ab5fSopenharmony_ci lexer_->NextToken(); // eat left square bracket 20463af6ab5fSopenharmony_ci 20473af6ab5fSopenharmony_ci key = ParseExpression(flags | ExpressionParseFlags::ACCEPT_COMMA); 20483af6ab5fSopenharmony_ci 20493af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 20503af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ']'"); 20513af6ab5fSopenharmony_ci } 20523af6ab5fSopenharmony_ci break; 20533af6ab5fSopenharmony_ci } 20543af6ab5fSopenharmony_ci default: { 20553af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token in property key"); 20563af6ab5fSopenharmony_ci } 20573af6ab5fSopenharmony_ci } 20583af6ab5fSopenharmony_ci 20593af6ab5fSopenharmony_ci lexer_->NextToken(); 20603af6ab5fSopenharmony_ci return key; 20613af6ab5fSopenharmony_ci} 20623af6ab5fSopenharmony_ci 20633af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyKind, const ParserStatus *methodStatus, 20643af6ab5fSopenharmony_ci ExpressionParseFlags flags) 20653af6ab5fSopenharmony_ci{ 20663af6ab5fSopenharmony_ci bool isMethod = (*methodStatus & ParserStatus::FUNCTION) != 0; 20673af6ab5fSopenharmony_ci bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0; 20683af6ab5fSopenharmony_ci 20693af6ab5fSopenharmony_ci if (!isMethod && !ir::Property::IsAccessorKind(*propertyKind)) { 20703af6ab5fSopenharmony_ci // If the actual property is not getter/setter nor method, the following 20713af6ab5fSopenharmony_ci // token must be ':' 20723af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 20733af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ':'"); 20743af6ab5fSopenharmony_ci } 20753af6ab5fSopenharmony_ci 20763af6ab5fSopenharmony_ci lexer_->NextToken(); // eat colon 20773af6ab5fSopenharmony_ci 20783af6ab5fSopenharmony_ci if (!inPattern) { 20793af6ab5fSopenharmony_ci return ParseExpression(flags); 20803af6ab5fSopenharmony_ci } 20813af6ab5fSopenharmony_ci 20823af6ab5fSopenharmony_ci return ParsePatternElement(); 20833af6ab5fSopenharmony_ci } 20843af6ab5fSopenharmony_ci 20853af6ab5fSopenharmony_ci if (inPattern) { 20863af6ab5fSopenharmony_ci ThrowSyntaxError("Object pattern can't contain methods"); 20873af6ab5fSopenharmony_ci } 20883af6ab5fSopenharmony_ci 20893af6ab5fSopenharmony_ci ParserStatus newStatus = *methodStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER; 20903af6ab5fSopenharmony_ci 20913af6ab5fSopenharmony_ci if (*propertyKind != ir::PropertyKind::SET) { 20923af6ab5fSopenharmony_ci newStatus |= ParserStatus::NEED_RETURN_TYPE; 20933af6ab5fSopenharmony_ci } 20943af6ab5fSopenharmony_ci 20953af6ab5fSopenharmony_ci ir::ScriptFunction *methodDefinitonNode = ParseFunction(newStatus); 20963af6ab5fSopenharmony_ci methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD); 20973af6ab5fSopenharmony_ci 20983af6ab5fSopenharmony_ci size_t paramsSize = methodDefinitonNode->Params().size(); 20993af6ab5fSopenharmony_ci 21003af6ab5fSopenharmony_ci auto *value = AllocNode<ir::FunctionExpression>(methodDefinitonNode); 21013af6ab5fSopenharmony_ci value->SetRange(methodDefinitonNode->Range()); 21023af6ab5fSopenharmony_ci 21033af6ab5fSopenharmony_ci if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) { 21043af6ab5fSopenharmony_ci ThrowSyntaxError("Setter must have exactly one formal parameter"); 21053af6ab5fSopenharmony_ci } 21063af6ab5fSopenharmony_ci 21073af6ab5fSopenharmony_ci if (*propertyKind == ir::PropertyKind::GET && paramsSize != 0) { 21083af6ab5fSopenharmony_ci ThrowSyntaxError("Getter must not have formal parameters"); 21093af6ab5fSopenharmony_ci } 21103af6ab5fSopenharmony_ci 21113af6ab5fSopenharmony_ci return value; 21123af6ab5fSopenharmony_ci} 21133af6ab5fSopenharmony_ci 21143af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 21153af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags) 21163af6ab5fSopenharmony_ci{ 21173af6ab5fSopenharmony_ci ir::PropertyKind propertyKind = ir::PropertyKind::INIT; 21183af6ab5fSopenharmony_ci ParserStatus methodStatus = ParserStatus::NO_OPTS; 21193af6ab5fSopenharmony_ci 21203af6ab5fSopenharmony_ci const auto startPos = lexer_->Save(); 21213af6ab5fSopenharmony_ci lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 21223af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 21233af6ab5fSopenharmony_ci 21243af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 21253af6ab5fSopenharmony_ci return ParseSpreadElement(flags); 21263af6ab5fSopenharmony_ci } 21273af6ab5fSopenharmony_ci 21283af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 21293af6ab5fSopenharmony_ci if (ParsePropertyModifiers(flags, &propertyKind, &methodStatus)) { 21303af6ab5fSopenharmony_ci return ParseShorthandProperty(&startPos); 21313af6ab5fSopenharmony_ci } 21323af6ab5fSopenharmony_ci } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { 21333af6ab5fSopenharmony_ci ParseGeneratorPropertyModifier(flags, &methodStatus); 21343af6ab5fSopenharmony_ci } 21353af6ab5fSopenharmony_ci 21363af6ab5fSopenharmony_ci bool isComputed = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET; 21373af6ab5fSopenharmony_ci ir::Expression *key = ParsePropertyKey(flags); 21383af6ab5fSopenharmony_ci 21393af6ab5fSopenharmony_ci // Parse method property 21403af6ab5fSopenharmony_ci if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 21413af6ab5fSopenharmony_ci lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) && 21423af6ab5fSopenharmony_ci !ir::Property::IsAccessorKind(propertyKind)) { 21433af6ab5fSopenharmony_ci methodStatus |= ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER; 21443af6ab5fSopenharmony_ci propertyKind = ir::PropertyKind::INIT; 21453af6ab5fSopenharmony_ci } else if ((methodStatus & (ParserStatus::GENERATOR_FUNCTION | ParserStatus::ASYNC_FUNCTION)) != 0) { 21463af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected identifier"); 21473af6ab5fSopenharmony_ci } 21483af6ab5fSopenharmony_ci 21493af6ab5fSopenharmony_ci ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); 21503af6ab5fSopenharmony_ci lexer::SourcePosition end = value->End(); 21513af6ab5fSopenharmony_ci 21523af6ab5fSopenharmony_ci ASSERT(key); 21533af6ab5fSopenharmony_ci ASSERT(value); 21543af6ab5fSopenharmony_ci 21553af6ab5fSopenharmony_ci auto *returnProperty = 21563af6ab5fSopenharmony_ci AllocNode<ir::Property>(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); 21573af6ab5fSopenharmony_ci returnProperty->SetRange({start, end}); 21583af6ab5fSopenharmony_ci 21593af6ab5fSopenharmony_ci return returnProperty; 21603af6ab5fSopenharmony_ci} 21613af6ab5fSopenharmony_ci 21623af6ab5fSopenharmony_cibool ParserImpl::ParsePropertyEnd() 21633af6ab5fSopenharmony_ci{ 21643af6ab5fSopenharmony_ci // Property definiton must end with ',' or '}' otherwise we throw SyntaxError 21653af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 21663af6ab5fSopenharmony_ci lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 21673af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ',' or '}'"); 21683af6ab5fSopenharmony_ci } 21693af6ab5fSopenharmony_ci 21703af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && 21713af6ab5fSopenharmony_ci lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) { 21723af6ab5fSopenharmony_ci lexer_->NextToken(); 21733af6ab5fSopenharmony_ci return true; 21743af6ab5fSopenharmony_ci } 21753af6ab5fSopenharmony_ci 21763af6ab5fSopenharmony_ci return false; 21773af6ab5fSopenharmony_ci} 21783af6ab5fSopenharmony_ci 21793af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 21803af6ab5fSopenharmony_ciir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags flags) 21813af6ab5fSopenharmony_ci{ 21823af6ab5fSopenharmony_ci ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); 21833af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 21843af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> properties(Allocator()->Adapter()); 21853af6ab5fSopenharmony_ci bool trailingComma = false; 21863af6ab5fSopenharmony_ci bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0; 21873af6ab5fSopenharmony_ci 21883af6ab5fSopenharmony_ci if (lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) { 21893af6ab5fSopenharmony_ci lexer_->NextToken(); 21903af6ab5fSopenharmony_ci } 21913af6ab5fSopenharmony_ci 21923af6ab5fSopenharmony_ci while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 21933af6ab5fSopenharmony_ci ir::Expression *property = ParsePropertyDefinition(flags | ExpressionParseFlags::POTENTIALLY_IN_PATTERN); 21943af6ab5fSopenharmony_ci properties.push_back(property); 21953af6ab5fSopenharmony_ci trailingComma = ParsePropertyEnd(); 21963af6ab5fSopenharmony_ci } 21973af6ab5fSopenharmony_ci 21983af6ab5fSopenharmony_ci auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION; 21993af6ab5fSopenharmony_ci auto *objectExpression = 22003af6ab5fSopenharmony_ci AllocNode<ir::ObjectExpression>(nodeType, Allocator(), std::move(properties), trailingComma); 22013af6ab5fSopenharmony_ci objectExpression->SetRange({start, lexer_->GetToken().End()}); 22023af6ab5fSopenharmony_ci lexer_->NextToken(); 22033af6ab5fSopenharmony_ci 22043af6ab5fSopenharmony_ci if (inPattern) { 22053af6ab5fSopenharmony_ci objectExpression->SetDeclaration(); 22063af6ab5fSopenharmony_ci } 22073af6ab5fSopenharmony_ci 22083af6ab5fSopenharmony_ci if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) { 22093af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION && 22103af6ab5fSopenharmony_ci !objectExpression->ConvertibleToObjectPattern()) { 22113af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", objectExpression->Start()); 22123af6ab5fSopenharmony_ci } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 22133af6ab5fSopenharmony_ci ir::ValidationInfo info = objectExpression->ValidateExpression(); 22143af6ab5fSopenharmony_ci if (info.Fail()) { 22153af6ab5fSopenharmony_ci ThrowSyntaxError(info.msg.Utf8(), info.pos); 22163af6ab5fSopenharmony_ci } 22173af6ab5fSopenharmony_ci } 22183af6ab5fSopenharmony_ci } 22193af6ab5fSopenharmony_ci 22203af6ab5fSopenharmony_ci return objectExpression; 22213af6ab5fSopenharmony_ci} 22223af6ab5fSopenharmony_ci 22233af6ab5fSopenharmony_ciir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *startExpr, bool acceptRest) 22243af6ab5fSopenharmony_ci{ 22253af6ab5fSopenharmony_ci lexer::SourcePosition start = startExpr->Start(); 22263af6ab5fSopenharmony_ci 22273af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> sequence(Allocator()->Adapter()); 22283af6ab5fSopenharmony_ci sequence.push_back(startExpr); 22293af6ab5fSopenharmony_ci 22303af6ab5fSopenharmony_ci while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 22313af6ab5fSopenharmony_ci lexer_->NextToken(); 22323af6ab5fSopenharmony_ci 22333af6ab5fSopenharmony_ci if (acceptRest && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 22343af6ab5fSopenharmony_ci ir::SpreadElement *expr = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN); 22353af6ab5fSopenharmony_ci sequence.push_back(expr); 22363af6ab5fSopenharmony_ci break; 22373af6ab5fSopenharmony_ci } 22383af6ab5fSopenharmony_ci 22393af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && lexer_->CheckArrow()) { 22403af6ab5fSopenharmony_ci break; 22413af6ab5fSopenharmony_ci } 22423af6ab5fSopenharmony_ci 22433af6ab5fSopenharmony_ci sequence.push_back(ParseExpression()); 22443af6ab5fSopenharmony_ci } 22453af6ab5fSopenharmony_ci 22463af6ab5fSopenharmony_ci lexer::SourcePosition end = sequence.back()->End(); 22473af6ab5fSopenharmony_ci auto *sequenceNode = AllocNode<ir::SequenceExpression>(std::move(sequence)); 22483af6ab5fSopenharmony_ci sequenceNode->SetRange({start, end}); 22493af6ab5fSopenharmony_ci 22503af6ab5fSopenharmony_ci return sequenceNode; 22513af6ab5fSopenharmony_ci} 22523af6ab5fSopenharmony_ci 22533af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 22543af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags) 22553af6ab5fSopenharmony_ci{ 22563af6ab5fSopenharmony_ci if (!lexer_->GetToken().IsUnary()) { 22573af6ab5fSopenharmony_ci return ParseLeftHandSideExpression(flags); 22583af6ab5fSopenharmony_ci } 22593af6ab5fSopenharmony_ci 22603af6ab5fSopenharmony_ci lexer::TokenType operatorType = lexer_->GetToken().Type(); 22613af6ab5fSopenharmony_ci lexer::SourcePosition start = lexer_->GetToken().Start(); 22623af6ab5fSopenharmony_ci lexer_->NextToken(); 22633af6ab5fSopenharmony_ci 22643af6ab5fSopenharmony_ci ir::Expression *argument = 22653af6ab5fSopenharmony_ci lexer_->GetToken().IsUnary() ? ParseUnaryOrPrefixUpdateExpression() : ParseLeftHandSideExpression(); 22663af6ab5fSopenharmony_ci 22673af6ab5fSopenharmony_ci if (lexer::Token::IsUpdateToken(operatorType)) { 22683af6ab5fSopenharmony_ci if (!argument->IsIdentifier() && !argument->IsMemberExpression() && !argument->IsTSNonNullExpression()) { 22693af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid left-hand side in prefix operation"); 22703af6ab5fSopenharmony_ci } 22713af6ab5fSopenharmony_ci 22723af6ab5fSopenharmony_ci if (argument->IsIdentifier()) { 22733af6ab5fSopenharmony_ci const util::StringView &argumentStr = argument->AsIdentifier()->Name(); 22743af6ab5fSopenharmony_ci 22753af6ab5fSopenharmony_ci if (argumentStr.Is("eval")) { 22763af6ab5fSopenharmony_ci ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid"); 22773af6ab5fSopenharmony_ci } else if (argumentStr.Is("arguments")) { 22783af6ab5fSopenharmony_ci ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid"); 22793af6ab5fSopenharmony_ci } 22803af6ab5fSopenharmony_ci } 22813af6ab5fSopenharmony_ci } 22823af6ab5fSopenharmony_ci 22833af6ab5fSopenharmony_ci if (operatorType == lexer::TokenType::KEYW_DELETE) { 22843af6ab5fSopenharmony_ci if (argument->IsIdentifier()) { 22853af6ab5fSopenharmony_ci ThrowSyntaxError("Deleting local variable in strict mode"); 22863af6ab5fSopenharmony_ci } 22873af6ab5fSopenharmony_ci 22883af6ab5fSopenharmony_ci if (argument->IsMemberExpression() && argument->AsMemberExpression()->Property()->IsIdentifier() && 22893af6ab5fSopenharmony_ci argument->AsMemberExpression()->Property()->AsIdentifier()->IsPrivateIdent()) { 22903af6ab5fSopenharmony_ci ThrowSyntaxError("Private fields can not be deleted"); 22913af6ab5fSopenharmony_ci } 22923af6ab5fSopenharmony_ci } 22933af6ab5fSopenharmony_ci 22943af6ab5fSopenharmony_ci lexer::SourcePosition end = argument->End(); 22953af6ab5fSopenharmony_ci 22963af6ab5fSopenharmony_ci ir::Expression *returnExpr = nullptr; 22973af6ab5fSopenharmony_ci 22983af6ab5fSopenharmony_ci if (lexer::Token::IsUpdateToken(operatorType)) { 22993af6ab5fSopenharmony_ci returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true); 23003af6ab5fSopenharmony_ci } else if (operatorType == lexer::TokenType::KEYW_AWAIT) { 23013af6ab5fSopenharmony_ci returnExpr = AllocNode<ir::AwaitExpression>(argument); 23023af6ab5fSopenharmony_ci } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) { 23033af6ab5fSopenharmony_ci returnExpr = AllocNode<ir::TypeofExpression>(argument); 23043af6ab5fSopenharmony_ci } else { 23053af6ab5fSopenharmony_ci returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType); 23063af6ab5fSopenharmony_ci } 23073af6ab5fSopenharmony_ci 23083af6ab5fSopenharmony_ci returnExpr->SetRange({start, end}); 23093af6ab5fSopenharmony_ci 23103af6ab5fSopenharmony_ci return returnExpr; 23113af6ab5fSopenharmony_ci} 23123af6ab5fSopenharmony_ci 23133af6ab5fSopenharmony_ciir::Expression *ParserImpl::ParseImportExpression() 23143af6ab5fSopenharmony_ci{ 23153af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 23163af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = lexer_->GetToken().End(); 23173af6ab5fSopenharmony_ci lexer_->NextToken(); // eat import 23183af6ab5fSopenharmony_ci 23193af6ab5fSopenharmony_ci // parse import.Meta 23203af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 23213af6ab5fSopenharmony_ci if (!context_.IsModule()) { 23223af6ab5fSopenharmony_ci ThrowSyntaxError("'import.Meta' may appear only with 'sourceType: module'"); 23233af6ab5fSopenharmony_ci } else if (GetOptions().isDirectEval) { 23243af6ab5fSopenharmony_ci ThrowSyntaxError("'import.Meta' is not allowed in direct eval in module code."); 23253af6ab5fSopenharmony_ci } 23263af6ab5fSopenharmony_ci 23273af6ab5fSopenharmony_ci lexer_->NextToken(); // eat dot 23283af6ab5fSopenharmony_ci 23293af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT || 23303af6ab5fSopenharmony_ci lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_META) { 23313af6ab5fSopenharmony_ci ThrowSyntaxError("The only valid meta property for import is import.Meta"); 23323af6ab5fSopenharmony_ci } 23333af6ab5fSopenharmony_ci 23343af6ab5fSopenharmony_ci auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::IMPORT_META); 23353af6ab5fSopenharmony_ci metaProperty->SetRange({startLoc, endLoc}); 23363af6ab5fSopenharmony_ci 23373af6ab5fSopenharmony_ci lexer_->NextToken(); 23383af6ab5fSopenharmony_ci return metaProperty; 23393af6ab5fSopenharmony_ci } 23403af6ab5fSopenharmony_ci 23413af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 23423af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 23433af6ab5fSopenharmony_ci } 23443af6ab5fSopenharmony_ci 23453af6ab5fSopenharmony_ci lexer_->NextToken(); // eat left parentheses 23463af6ab5fSopenharmony_ci 23473af6ab5fSopenharmony_ci ir::Expression *source = ParseExpression(); 23483af6ab5fSopenharmony_ci 23493af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 23503af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token"); 23513af6ab5fSopenharmony_ci } 23523af6ab5fSopenharmony_ci 23533af6ab5fSopenharmony_ci auto *importExpression = AllocNode<ir::ImportExpression>(source); 23543af6ab5fSopenharmony_ci importExpression->SetRange({startLoc, lexer_->GetToken().End()}); 23553af6ab5fSopenharmony_ci 23563af6ab5fSopenharmony_ci lexer_->NextToken(); // eat right paren 23573af6ab5fSopenharmony_ci return importExpression; 23583af6ab5fSopenharmony_ci} 23593af6ab5fSopenharmony_ci 23603af6ab5fSopenharmony_cibool ParserImpl::IsNamedFunctionExpression() 23613af6ab5fSopenharmony_ci{ 23623af6ab5fSopenharmony_ci return lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS; 23633af6ab5fSopenharmony_ci} 23643af6ab5fSopenharmony_ci 23653af6ab5fSopenharmony_ciir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStatus) 23663af6ab5fSopenharmony_ci{ 23673af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 23683af6ab5fSopenharmony_ci ir::Identifier *ident = nullptr; 23693af6ab5fSopenharmony_ci 23703af6ab5fSopenharmony_ci if ((newStatus & ParserStatus::ARROW_FUNCTION) == 0) { 23713af6ab5fSopenharmony_ci ParserStatus savedStatus = context_.Status(); 23723af6ab5fSopenharmony_ci context_.Status() |= static_cast<ParserStatus>(newStatus & ParserStatus::ASYNC_FUNCTION); 23733af6ab5fSopenharmony_ci 23743af6ab5fSopenharmony_ci lexer_->NextToken(); 23753af6ab5fSopenharmony_ci 23763af6ab5fSopenharmony_ci if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { 23773af6ab5fSopenharmony_ci newStatus |= ParserStatus::GENERATOR_FUNCTION; 23783af6ab5fSopenharmony_ci lexer_->NextToken(); 23793af6ab5fSopenharmony_ci } 23803af6ab5fSopenharmony_ci 23813af6ab5fSopenharmony_ci if (IsNamedFunctionExpression()) { 23823af6ab5fSopenharmony_ci CheckRestrictedBinding(lexer_->GetToken().KeywordType()); 23833af6ab5fSopenharmony_ci ident = ExpectIdentifier(false, true); 23843af6ab5fSopenharmony_ci } 23853af6ab5fSopenharmony_ci 23863af6ab5fSopenharmony_ci context_.Status() = savedStatus; 23873af6ab5fSopenharmony_ci } 23883af6ab5fSopenharmony_ci 23893af6ab5fSopenharmony_ci ir::ScriptFunction *functionNode = ParseFunction(newStatus); 23903af6ab5fSopenharmony_ci functionNode->SetStart(startLoc); 23913af6ab5fSopenharmony_ci 23923af6ab5fSopenharmony_ci auto *funcExpr = AllocNode<ir::FunctionExpression>(ident, functionNode); 23933af6ab5fSopenharmony_ci funcExpr->SetRange(functionNode->Range()); 23943af6ab5fSopenharmony_ci 23953af6ab5fSopenharmony_ci return funcExpr; 23963af6ab5fSopenharmony_ci} 23973af6ab5fSopenharmony_ci} // namespace ark::es2panda::parser 2398