1/** 2 * Copyright (c) 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 "TSparser.h" 17 18#include "parserFlags.h" 19#include "util/helpers.h" 20#include "varbinder/privateBinding.h" 21#include "varbinder/scope.h" 22#include "varbinder/tsBinding.h" 23#include "lexer/TSLexer.h" 24#include "ir/base/spreadElement.h" 25#include "ir/base/decorator.h" 26#include "ir/base/classElement.h" 27#include "ir/base/classDefinition.h" 28#include "ir/base/methodDefinition.h" 29#include "ir/base/scriptFunction.h" 30#include "ir/module/importDefaultSpecifier.h" 31#include "ir/module/exportDefaultDeclaration.h" 32#include "ir/module/exportAllDeclaration.h" 33#include "ir/module/exportNamedDeclaration.h" 34#include "ir/module/importDeclaration.h" 35#include "ir/expressions/memberExpression.h" 36#include "ir/expressions/sequenceExpression.h" 37#include "ir/expressions/templateLiteral.h" 38#include "ir/expressions/taggedTemplateExpression.h" 39#include "ir/expressions/callExpression.h" 40#include "ir/expressions/functionExpression.h" 41#include "ir/expressions/arrowFunctionExpression.h" 42#include "ir/expressions/yieldExpression.h" 43#include "ir/expressions/assignmentExpression.h" 44#include "ir/expressions/identifier.h" 45#include "ir/expressions/objectExpression.h" 46#include "ir/expressions/arrayExpression.h" 47#include "ir/expressions/literals/bigIntLiteral.h" 48#include "ir/expressions/literals/booleanLiteral.h" 49#include "ir/expressions/literals/nullLiteral.h" 50#include "ir/expressions/literals/numberLiteral.h" 51#include "ir/expressions/literals/stringLiteral.h" 52#include "ir/statements/emptyStatement.h" 53#include "ir/statements/blockStatement.h" 54#include "ir/statements/ifStatement.h" 55#include "ir/statements/doWhileStatement.h" 56#include "ir/statements/whileStatement.h" 57#include "ir/statements/tryStatement.h" 58#include "ir/statements/breakStatement.h" 59#include "ir/statements/continueStatement.h" 60#include "ir/statements/throwStatement.h" 61#include "ir/statements/switchStatement.h" 62#include "ir/statements/returnStatement.h" 63#include "ir/statements/debuggerStatement.h" 64#include "ir/statements/classDeclaration.h" 65#include "ir/statements/labelledStatement.h" 66#include "ir/statements/variableDeclarator.h" 67#include "ir/statements/functionDeclaration.h" 68#include "ir/ts/tsLiteralType.h" 69#include "ir/ts/tsMappedType.h" 70#include "ir/ts/tsImportType.h" 71#include "ir/ts/tsThisType.h" 72#include "ir/ts/tsConditionalType.h" 73#include "ir/ts/tsTypeOperator.h" 74#include "ir/ts/tsInferType.h" 75#include "ir/ts/tsTupleType.h" 76#include "ir/ts/tsNamedTupleMember.h" 77#include "ir/ts/tsQualifiedName.h" 78#include "ir/ts/tsIndexedAccessType.h" 79#include "ir/ts/tsTypeQuery.h" 80#include "ir/ts/tsTypeReference.h" 81#include "ir/ts/tsTypePredicate.h" 82#include "ir/ts/tsTypeLiteral.h" 83#include "ir/ts/tsArrayType.h" 84#include "ir/ts/tsUnionType.h" 85#include "ir/ts/tsIntersectionType.h" 86#include "ir/ts/tsAnyKeyword.h" 87#include "ir/ts/tsUndefinedKeyword.h" 88#include "ir/ts/tsVoidKeyword.h" 89#include "ir/ts/tsNumberKeyword.h" 90#include "ir/ts/tsStringKeyword.h" 91#include "ir/ts/tsBooleanKeyword.h" 92#include "ir/ts/tsBigintKeyword.h" 93#include "ir/ts/tsUnknownKeyword.h" 94#include "ir/ts/tsNullKeyword.h" 95#include "ir/ts/tsNeverKeyword.h" 96#include "ir/ts/tsObjectKeyword.h" 97#include "ir/ts/tsFunctionType.h" 98#include "ir/ts/tsConstructorType.h" 99#include "ir/ts/tsParenthesizedType.h" 100#include "ir/ts/tsTypeAssertion.h" 101#include "ir/ts/tsAsExpression.h" 102#include "ir/ts/tsNonNullExpression.h" 103#include "ir/ts/tsEnumDeclaration.h" 104#include "ir/ts/tsInterfaceDeclaration.h" 105#include "ir/ts/tsTypeAliasDeclaration.h" 106#include "ir/ts/tsModuleDeclaration.h" 107#include "ir/ts/tsTypeParameterInstantiation.h" 108#include "ir/ts/tsInterfaceHeritage.h" 109#include "ir/base/tsSignatureDeclaration.h" 110#include "ir/base/tsIndexSignature.h" 111#include "ir/base/tsMethodSignature.h" 112#include "ir/base/tsPropertySignature.h" 113#include "ir/ts/tsParameterProperty.h" 114#include "ir/ts/tsClassImplements.h" 115#include "ir/ts/tsImportEqualsDeclaration.h" 116#include "ir/ts/tsExternalModuleReference.h" 117 118namespace ark::es2panda::parser { 119// NOLINTNEXTLINE(google-default-arguments) 120ir::Statement *TSParser::ParseStatement(StatementParsingFlags flags) 121{ 122 return ParseDeclareAndDecorators(flags); 123} 124ir::TSImportEqualsDeclaration *TSParser::ParseTsImportEqualsDeclaration(const lexer::SourcePosition &startLoc, 125 bool isExport) 126{ 127 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT); 128 Lexer()->NextToken(); 129 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 130 ThrowSyntaxError("Unexpected token"); 131 } 132 133 auto *id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 134 id->SetRange(Lexer()->GetToken().Loc()); 135 Lexer()->NextToken(); // eat id name 136 137 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 138 ThrowSyntaxError("'=' expected"); 139 } 140 Lexer()->NextToken(); // eat substitution 141 142 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 143 ThrowSyntaxError("identifier expected"); 144 } 145 146 auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(id, ParseModuleReference(), isExport); 147 importEqualsDecl->SetRange({startLoc, Lexer()->GetToken().End()}); 148 149 ConsumeSemicolon(importEqualsDecl); 150 151 return importEqualsDecl; 152} 153 154// NOLINTNEXTLINE(google-default-arguments) 155ir::ExportDefaultDeclaration *TSParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc, 156 bool isExportEquals) 157{ 158 Lexer()->NextToken(); // eat `default` keyword or `=` 159 160 ir::AstNode *declNode = nullptr; 161 bool eatSemicolon = false; 162 163 switch (Lexer()->GetToken().KeywordType()) { 164 case lexer::TokenType::KEYW_FUNCTION: { 165 declNode = ParseFunctionDeclaration(true); 166 break; 167 } 168 case lexer::TokenType::KEYW_CLASS: { 169 declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED); 170 break; 171 } 172 case lexer::TokenType::KEYW_INTERFACE: { 173 declNode = ParseInterfaceDeclaration(false); 174 break; 175 } 176 case lexer::TokenType::KEYW_ASYNC: { 177 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) { 178 Lexer()->NextToken(); // eat `async` 179 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION); 180 break; 181 } 182 [[fallthrough]]; 183 } 184 default: { 185 declNode = ParseExpression(); 186 eatSemicolon = true; 187 break; 188 } 189 } 190 191 lexer::SourcePosition endLoc = declNode->End(); 192 auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals); 193 exportDeclaration->SetRange({startLoc, endLoc}); 194 195 if (eatSemicolon) { 196 ConsumeSemicolon(exportDeclaration); 197 } 198 199 return exportDeclaration; 200} 201 202ir::Statement *TSParser::GetDeclarationForNamedExport(ir::ClassDefinitionModifiers &classModifiers, 203 ir::ModifierFlags &flags) 204{ 205 switch (Lexer()->GetToken().KeywordType()) { 206 case lexer::TokenType::KEYW_VAR: { 207 return ParseVariableDeclaration(VariableParsingFlags::VAR); 208 } 209 case lexer::TokenType::KEYW_CONST: { 210 return ParseVariableDeclaration(VariableParsingFlags::CONST); 211 } 212 case lexer::TokenType::KEYW_LET: { 213 return ParseVariableDeclaration(VariableParsingFlags::LET); 214 } 215 case lexer::TokenType::KEYW_FUNCTION: { 216 return ParseFunctionDeclaration(false, ParserStatus::NO_OPTS); 217 } 218 case lexer::TokenType::KEYW_CLASS: { 219 return ParseClassDeclaration(classModifiers, flags); 220 } 221 case lexer::TokenType::KEYW_ENUM: { 222 return ParseEnumDeclaration(); 223 } 224 case lexer::TokenType::KEYW_INTERFACE: { 225 return ParseInterfaceDeclaration(false); 226 } 227 case lexer::TokenType::KEYW_TYPE: { 228 return ParseTypeAliasDeclaration(); 229 } 230 case lexer::TokenType::KEYW_GLOBAL: 231 case lexer::TokenType::KEYW_MODULE: 232 case lexer::TokenType::KEYW_NAMESPACE: { 233 return ParseModuleDeclaration(); 234 } 235 default: { 236 if (!Lexer()->GetToken().IsAsyncModifier()) { 237 ThrowSyntaxError("Unexpected token"); 238 } 239 240 Lexer()->NextToken(); // eat `async` keyword 241 return ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION); 242 } 243 } 244} 245ir::ExportNamedDeclaration *TSParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc) 246{ 247 ir::ClassDefinitionModifiers classModifiers = ir::ClassDefinitionModifiers::ID_REQUIRED; 248 ir::ModifierFlags flags = ir::ModifierFlags::NONE; 249 250 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { 251 CheckDeclare(); 252 } 253 254 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) { 255 Lexer()->NextToken(); // eat 'abstract' 256 flags |= ir::ModifierFlags::ABSTRACT; 257 } 258 259 ir::Statement *decl = GetDeclarationForNamedExport(classModifiers, flags); 260 261 if (decl->IsVariableDeclaration()) { 262 ConsumeSemicolon(decl); 263 } 264 265 lexer::SourcePosition endLoc = decl->End(); 266 ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter()); 267 auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers)); 268 exportDeclaration->SetRange({startLoc, endLoc}); 269 270 return exportDeclaration; 271} 272 273ir::Statement *TSParser::ParseExportDeclaration(StatementParsingFlags flags) 274{ 275 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 276 Lexer()->NextToken(); // eat `export` keyword 277 278 switch (Lexer()->GetToken().Type()) { 279 case lexer::TokenType::KEYW_DEFAULT: { 280 return ParseExportDefaultDeclaration(startLoc); 281 } 282 case lexer::TokenType::PUNCTUATOR_MULTIPLY: { 283 return ParseExportAllDeclaration(startLoc); 284 } 285 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 286 return ParseExportNamedSpecifiers(startLoc); 287 } 288 case lexer::TokenType::KEYW_IMPORT: { 289 return ParseTsImportEqualsDeclaration(startLoc, true); 290 } 291 case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: { 292 return ParseExportDefaultDeclaration(startLoc, true); 293 } 294 default: { 295 ir::ExportNamedDeclaration *exportDecl = ParseNamedExportDeclaration(startLoc); 296 297 if (exportDecl->Decl()->IsVariableDeclaration() && ((flags & StatementParsingFlags::GLOBAL) == 0) && 298 exportDecl->Parent() != nullptr && !exportDecl->Parent()->IsTSModuleBlock() && 299 !GetContext().IsModule()) { 300 ThrowSyntaxError("Modifiers cannot appear here'"); 301 } 302 303 return exportDecl; 304 } 305 } 306} 307 308ir::Statement *TSParser::ParseConstStatement(StatementParsingFlags flags) 309{ 310 lexer::SourcePosition constVarStar = Lexer()->GetToken().Start(); 311 Lexer()->NextToken(); 312 313 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) { 314 return ParseEnumDeclaration(true); 315 } 316 317 if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) { 318 ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); 319 } 320 321 auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); 322 variableDecl->SetStart(constVarStar); 323 ConsumeSemicolon(variableDecl); 324 325 return variableDecl; 326} 327 328ir::Statement *TSParser::ParsePotentialConstEnum(VariableParsingFlags flags) 329{ 330 if ((flags & VariableParsingFlags::CONST) == 0) { 331 ThrowSyntaxError("Variable declaration expected."); 332 } 333 334 return ParseEnumDeclaration(true); 335} 336 337ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags) 338{ 339 char32_t nextChar = Lexer()->Lookahead(); 340 if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) { 341 return ParseExpressionStatement(); 342 } 343 344 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 345 Lexer()->NextToken(); // eat import 346 347 ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter()); 348 349 ir::StringLiteral *source = nullptr; 350 351 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) { 352 ir::AstNode *astNode = ParseImportSpecifiers(&specifiers); 353 if (astNode != nullptr) { 354 ASSERT(astNode->IsTSImportEqualsDeclaration()); 355 astNode->SetRange({startLoc, Lexer()->GetToken().End()}); 356 ConsumeSemicolon(astNode->AsTSImportEqualsDeclaration()); 357 return astNode->AsTSImportEqualsDeclaration(); 358 } 359 source = ParseFromClause(true); 360 } else { 361 source = ParseFromClause(false); 362 } 363 364 lexer::SourcePosition endLoc = source->End(); 365 auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers)); 366 importDeclaration->SetRange({startLoc, endLoc}); 367 368 ConsumeSemicolon(importDeclaration); 369 370 return importDeclaration; 371} 372 373} // namespace ark::es2panda::parser