1/** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ETSparser.h" 17#include "ETSNolintParser.h" 18#include <utility> 19 20#include "macros.h" 21#include "parser/parserFlags.h" 22#include "parser/parserStatusContext.h" 23#include "util/helpers.h" 24#include "util/language.h" 25#include "utils/arena_containers.h" 26#include "varbinder/varbinder.h" 27#include "varbinder/ETSBinder.h" 28#include "lexer/lexer.h" 29#include "lexer/ETSLexer.h" 30#include "checker/types/ets/etsEnumType.h" 31#include "ir/astNode.h" 32#include "ir/base/classDefinition.h" 33#include "ir/base/decorator.h" 34#include "ir/base/catchClause.h" 35#include "ir/base/classProperty.h" 36#include "ir/base/scriptFunction.h" 37#include "ir/base/methodDefinition.h" 38#include "ir/base/classStaticBlock.h" 39#include "ir/base/spreadElement.h" 40#include "ir/expressions/identifier.h" 41#include "ir/expressions/functionExpression.h" 42#include "ir/statements/functionDeclaration.h" 43#include "ir/statements/expressionStatement.h" 44#include "ir/statements/classDeclaration.h" 45#include "ir/statements/variableDeclarator.h" 46#include "ir/statements/variableDeclaration.h" 47#include "ir/expressions/dummyNode.h" 48#include "ir/expressions/callExpression.h" 49#include "ir/expressions/thisExpression.h" 50#include "ir/expressions/typeofExpression.h" 51#include "ir/expressions/memberExpression.h" 52#include "ir/expressions/updateExpression.h" 53#include "ir/expressions/arrowFunctionExpression.h" 54#include "ir/expressions/unaryExpression.h" 55#include "ir/expressions/yieldExpression.h" 56#include "ir/expressions/awaitExpression.h" 57#include "ir/expressions/literals/nullLiteral.h" 58#include "ir/expressions/literals/numberLiteral.h" 59#include "ir/expressions/literals/stringLiteral.h" 60#include "ir/expressions/literals/undefinedLiteral.h" 61#include "ir/module/importDeclaration.h" 62#include "ir/module/importDefaultSpecifier.h" 63#include "ir/module/importSpecifier.h" 64#include "ir/module/exportSpecifier.h" 65#include "ir/module/exportNamedDeclaration.h" 66#include "ir/statements/assertStatement.h" 67#include "ir/statements/blockStatement.h" 68#include "ir/statements/ifStatement.h" 69#include "ir/statements/labelledStatement.h" 70#include "ir/statements/switchStatement.h" 71#include "ir/statements/throwStatement.h" 72#include "ir/statements/tryStatement.h" 73#include "ir/statements/whileStatement.h" 74#include "ir/statements/forOfStatement.h" 75#include "ir/statements/doWhileStatement.h" 76#include "ir/statements/breakStatement.h" 77#include "ir/statements/debuggerStatement.h" 78#include "ir/ets/etsLaunchExpression.h" 79#include "ir/ets/etsClassLiteral.h" 80#include "ir/ets/etsPrimitiveType.h" 81#include "ir/ets/etsPackageDeclaration.h" 82#include "ir/ets/etsReExportDeclaration.h" 83#include "ir/ets/etsWildcardType.h" 84#include "ir/ets/etsNewArrayInstanceExpression.h" 85#include "ir/ets/etsTuple.h" 86#include "ir/ets/etsFunctionType.h" 87#include "ir/ets/etsNewClassInstanceExpression.h" 88#include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" 89#include "ir/ets/etsScript.h" 90#include "ir/ets/etsTypeReference.h" 91#include "ir/ets/etsTypeReferencePart.h" 92#include "ir/ets/etsNullishTypes.h" 93#include "ir/ets/etsUnionType.h" 94#include "ir/ets/etsImportSource.h" 95#include "ir/ets/etsImportDeclaration.h" 96#include "ir/ets/etsStructDeclaration.h" 97#include "ir/ets/etsParameterExpression.h" 98#include "ir/module/importNamespaceSpecifier.h" 99#include "ir/ts/tsAsExpression.h" 100#include "ir/ts/tsInterfaceDeclaration.h" 101#include "ir/ts/tsEnumDeclaration.h" 102#include "ir/ts/tsTypeParameterInstantiation.h" 103#include "ir/ts/tsInterfaceBody.h" 104#include "ir/ts/tsImportEqualsDeclaration.h" 105#include "ir/ts/tsArrayType.h" 106#include "ir/ts/tsQualifiedName.h" 107#include "ir/ts/tsTypeReference.h" 108#include "ir/ts/tsTypeParameter.h" 109#include "ir/ts/tsInterfaceHeritage.h" 110#include "ir/ts/tsFunctionType.h" 111#include "ir/ts/tsClassImplements.h" 112#include "ir/ts/tsEnumMember.h" 113#include "ir/ts/tsTypeAliasDeclaration.h" 114#include "ir/ts/tsTypeParameterDeclaration.h" 115#include "ir/ts/tsNonNullExpression.h" 116#include "ir/ts/tsThisType.h" 117#include "generated/signatures.h" 118 119namespace ark::es2panda::parser { 120class FunctionContext; 121 122using namespace std::literals::string_literals; 123 124ArenaVector<ir::Statement *> ETSParser::ParseTopLevelStatements() 125{ 126 ArenaVector<ir::Statement *> statements(Allocator()->Adapter()); 127 while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) { 128 if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_SEMI_COLON)) { 129 continue; 130 } 131 auto stmt = ParseTopLevelStatement(); 132 GetContext().Status() &= ~ParserStatus::IN_AMBIENT_CONTEXT; 133 if (stmt != nullptr) { 134 statements.emplace_back(stmt); 135 } 136 } 137 138 return statements; 139} 140 141static ir::Statement *ValidateExportableStatement(ETSParser *parser, ir::Statement *stmt, 142 ark::es2panda::ir::ModifierFlags memberModifiers) 143{ 144 if (stmt != nullptr) { 145 if ((memberModifiers & ir::ModifierFlags::EXPORT_TYPE) != 0U && 146 !(stmt->IsClassDeclaration() || stmt->IsTSInterfaceDeclaration() || stmt->IsTSTypeAliasDeclaration())) { 147 parser->ThrowSyntaxError("Can only type export class or interface!", stmt->Start()); 148 } 149 stmt->AddModifier(memberModifiers); 150 } 151 return stmt; 152} 153 154ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags) 155{ 156 auto [memberModifiers, startLoc] = ParseMemberModifiers(); 157 if ((memberModifiers & (ir::ModifierFlags::EXPORTED)) != 0U && 158 (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY || 159 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { 160 return ParseExport(startLoc, memberModifiers); 161 } 162 163 ir::Statement *result = nullptr; 164 auto token = Lexer()->GetToken(); 165 switch (token.Type()) { 166 case lexer::TokenType::KEYW_FUNCTION: { 167 result = ParseFunctionDeclaration(false, memberModifiers); 168 if (result != nullptr) { // Error processing. 169 result->SetStart(startLoc); 170 } 171 break; 172 } 173 case lexer::TokenType::KEYW_CONST: { 174 memberModifiers |= ir::ModifierFlags::CONST; 175 [[fallthrough]]; 176 } 177 case lexer::TokenType::KEYW_LET: { 178 result = ParseStatement(flags); 179 break; 180 } 181 case lexer::TokenType::KEYW_NAMESPACE: 182 case lexer::TokenType::KEYW_STATIC: 183 case lexer::TokenType::KEYW_ABSTRACT: 184 case lexer::TokenType::KEYW_FINAL: 185 case lexer::TokenType::KEYW_ENUM: 186 case lexer::TokenType::KEYW_INTERFACE: 187 case lexer::TokenType::KEYW_CLASS: { 188 result = ParseTypeDeclaration(false); 189 break; 190 } 191 case lexer::TokenType::LITERAL_IDENT: { 192 result = ParseIdentKeyword(); 193 if (result == nullptr && (memberModifiers & (ir::ModifierFlags::EXPORTED)) != 0U) { 194 return ParseExport(startLoc, memberModifiers); 195 } 196 break; 197 } 198 default: { 199 } 200 } 201 202 return ValidateExportableStatement(this, result, memberModifiers); 203} 204 205ir::Statement *ETSParser::ParseTopLevelStatement() 206{ 207 const auto flags = StatementParsingFlags::ALLOW_LEXICAL; 208 209 auto result = ParseTopLevelDeclStatement(flags); 210 if (result == nullptr) { 211 result = ParseStatement(flags); 212 } 213 return result; 214} 215 216ArenaVector<ir::Statement *> ETSParser::ParseTopLevelDeclaration() 217{ 218 auto topStatements = ParseTopLevelStatements(); 219 Lexer()->NextToken(); 220 return topStatements; 221} 222 223void ETSParser::ValidateLabeledStatement(lexer::TokenType type) 224{ 225 if (type != lexer::TokenType::KEYW_DO && type != lexer::TokenType::KEYW_WHILE && 226 type != lexer::TokenType::KEYW_FOR && type != lexer::TokenType::KEYW_SWITCH) { 227 ThrowSyntaxError("Label must be followed by a loop statement", Lexer()->GetToken().Start()); 228 } 229} 230 231void ETSParser::ValidateForInStatement() 232{ 233 ThrowUnexpectedToken(lexer::TokenType::KEYW_IN); 234} 235 236ir::DebuggerStatement *ETSParser::ParseDebuggerStatement() 237{ 238 ThrowUnexpectedToken(lexer::TokenType::KEYW_DEBUGGER); 239} 240 241ir::Statement *ETSParser::ParseFunctionStatement(const StatementParsingFlags flags) 242{ 243 ASSERT((flags & StatementParsingFlags::GLOBAL) == 0); 244 LogSyntaxError("Nested functions are not allowed"); 245 ParserImpl::ParseFunctionStatement(flags); // Try to parse function body but skip result. 246 return nullptr; 247} 248 249ir::Statement *ETSParser::ParseAssertStatement() 250{ 251 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 252 Lexer()->NextToken(); 253 254 ir::Expression *test = ParseExpression(); 255 lexer::SourcePosition endLoc = test->End(); 256 ir::Expression *second = nullptr; 257 258 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 259 Lexer()->NextToken(); // eat ':' 260 second = ParseExpression(); 261 endLoc = second->End(); 262 } 263 264 auto *asStatement = AllocNode<ir::AssertStatement>(test, second); 265 asStatement->SetRange({startLoc, endLoc}); 266 ConsumeSemicolon(asStatement); 267 268 return asStatement; 269} 270 271ir::Statement *ETSParser::ParseTryStatement() 272{ 273 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 274 Lexer()->NextToken(); // eat the 'try' keyword 275 276 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 277 ThrowSyntaxError("Unexpected token, expected '{'"); 278 } 279 280 ir::BlockStatement *body = ParseBlockStatement(); 281 282 ArenaVector<ir::CatchClause *> catchClauses(Allocator()->Adapter()); 283 284 while (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_CATCH) { 285 ir::CatchClause *clause {}; 286 287 clause = ParseCatchClause(); 288 289 catchClauses.push_back(clause); 290 } 291 292 ir::BlockStatement *finalizer = nullptr; 293 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FINALLY) { 294 Lexer()->NextToken(); // eat 'finally' keyword 295 296 finalizer = ParseBlockStatement(); 297 } 298 299 if (catchClauses.empty() && finalizer == nullptr) { 300 ThrowSyntaxError("A try statement should contain either finally clause or at least one catch clause.", 301 startLoc); 302 } 303 304 lexer::SourcePosition endLoc = finalizer != nullptr ? finalizer->End() : catchClauses.back()->End(); 305 306 ArenaVector<std::pair<compiler::LabelPair, const ir::Statement *>> finalizerInsertions(Allocator()->Adapter()); 307 308 auto *tryStatement = AllocNode<ir::TryStatement>(body, std::move(catchClauses), finalizer, finalizerInsertions); 309 tryStatement->SetRange({startLoc, endLoc}); 310 ConsumeSemicolon(tryStatement); 311 312 return tryStatement; 313} 314 315// NOLINTNEXTLINE(google-default-arguments) 316ir::ClassDeclaration *ETSParser::ParseClassStatement([[maybe_unused]] StatementParsingFlags flags, 317 ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) 318{ 319 return ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | 320 ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, 321 modFlags); 322} 323 324// NOLINTNEXTLINE(google-default-arguments) 325ir::ETSStructDeclaration *ETSParser::ParseStructStatement([[maybe_unused]] StatementParsingFlags flags, 326 [[maybe_unused]] ir::ClassDefinitionModifiers modifiers, 327 [[maybe_unused]] ir::ModifierFlags modFlags) 328{ 329 ThrowSyntaxError("Illegal start of expression", Lexer()->GetToken().Start()); 330} 331 332} // namespace ark::es2panda::parser 333