• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024-2025 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 
118 namespace ark::es2panda::parser {
119 // NOLINTNEXTLINE(google-default-arguments)
ParseStatement(StatementParsingFlags flags)120 ir::Statement *TSParser::ParseStatement(StatementParsingFlags flags)
121 {
122     return ParseDeclareAndDecorators(flags);
123 }
ParseTsImportEqualsDeclaration(const lexer::SourcePosition & startLoc,bool isExport)124 ir::TSImportEqualsDeclaration *TSParser::ParseTsImportEqualsDeclaration(const lexer::SourcePosition &startLoc,
125                                                                         bool isExport)
126 {
127     ES2PANDA_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     ES2PANDA_ASSERT(id != nullptr);
135     id->SetRange(Lexer()->GetToken().Loc());
136     Lexer()->NextToken();  // eat id name
137 
138     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
139         ThrowSyntaxError("'=' expected");
140     }
141     Lexer()->NextToken();  // eat substitution
142 
143     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
144         ThrowSyntaxError("identifier expected");
145     }
146 
147     auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(id, ParseModuleReference(), isExport);
148     importEqualsDecl->SetRange({startLoc, Lexer()->GetToken().End()});
149 
150     ConsumeSemicolon(importEqualsDecl);
151 
152     return importEqualsDecl;
153 }
154 
155 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition & startLoc,bool isExportEquals)156 ir::ExportDefaultDeclaration *TSParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
157                                                                       bool isExportEquals)
158 {
159     Lexer()->NextToken();  // eat `default` keyword or `=`
160 
161     ir::AstNode *declNode = nullptr;
162     bool eatSemicolon = false;
163 
164     switch (Lexer()->GetToken().KeywordType()) {
165         case lexer::TokenType::KEYW_FUNCTION: {
166             declNode = ParseFunctionDeclaration(true);
167             break;
168         }
169         case lexer::TokenType::KEYW_CLASS: {
170             declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
171             break;
172         }
173         case lexer::TokenType::KEYW_INTERFACE: {
174             declNode = ParseInterfaceDeclaration(false);
175             break;
176         }
177         case lexer::TokenType::KEYW_ASYNC: {
178             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
179                 Lexer()->NextToken();  // eat `async`
180                 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
181                 break;
182             }
183             [[fallthrough]];
184         }
185         default: {
186             declNode = ParseExpression();
187             eatSemicolon = true;
188             break;
189         }
190     }
191 
192     lexer::SourcePosition endLoc = declNode->End();
193     auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
194     ES2PANDA_ASSERT(exportDeclaration != nullptr);
195     exportDeclaration->SetRange({startLoc, endLoc});
196 
197     if (eatSemicolon) {
198         ConsumeSemicolon(exportDeclaration);
199     }
200 
201     return exportDeclaration;
202 }
203 
GetDeclarationForNamedExport(ir::ClassDefinitionModifiers & classModifiers,ir::ModifierFlags & flags)204 ir::Statement *TSParser::GetDeclarationForNamedExport(ir::ClassDefinitionModifiers &classModifiers,
205                                                       ir::ModifierFlags &flags)
206 {
207     switch (Lexer()->GetToken().KeywordType()) {
208         case lexer::TokenType::KEYW_VAR: {
209             return ParseVariableDeclaration(VariableParsingFlags::VAR);
210         }
211         case lexer::TokenType::KEYW_CONST: {
212             return ParseVariableDeclaration(VariableParsingFlags::CONST);
213         }
214         case lexer::TokenType::KEYW_LET: {
215             return ParseVariableDeclaration(VariableParsingFlags::LET);
216         }
217         case lexer::TokenType::KEYW_FUNCTION: {
218             return ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
219         }
220         case lexer::TokenType::KEYW_CLASS: {
221             return ParseClassDeclaration(classModifiers, flags);
222         }
223         case lexer::TokenType::KEYW_ENUM: {
224             return ParseEnumDeclaration();
225         }
226         case lexer::TokenType::KEYW_INTERFACE: {
227             return ParseInterfaceDeclaration(false);
228         }
229         case lexer::TokenType::KEYW_TYPE: {
230             return ParseTypeAliasDeclaration();
231         }
232         case lexer::TokenType::KEYW_GLOBAL:
233         case lexer::TokenType::KEYW_MODULE:
234         case lexer::TokenType::KEYW_NAMESPACE: {
235             return ParseModuleDeclaration();
236         }
237         default: {
238             if (!Lexer()->GetToken().IsAsyncModifier()) {
239                 ThrowSyntaxError("Unexpected token");
240             }
241 
242             Lexer()->NextToken();  // eat `async` keyword
243             return ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
244         }
245     }
246 }
ParseNamedExportDeclaration(const lexer::SourcePosition & startLoc)247 ir::Statement *TSParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
248 {
249     ir::ClassDefinitionModifiers classModifiers = ir::ClassDefinitionModifiers::ID_REQUIRED;
250     ir::ModifierFlags flags = ir::ModifierFlags::NONE;
251 
252     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
253         CheckDeclare();
254     }
255 
256     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
257         Lexer()->NextToken();  // eat 'abstract'
258         flags |= ir::ModifierFlags::ABSTRACT;
259     }
260 
261     ir::Statement *decl = GetDeclarationForNamedExport(classModifiers, flags);
262 
263     if (decl->IsVariableDeclaration()) {
264         ConsumeSemicolon(decl);
265     }
266 
267     lexer::SourcePosition endLoc = decl->End();
268     ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
269     auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
270     ES2PANDA_ASSERT(exportDeclaration != nullptr);
271     exportDeclaration->SetRange({startLoc, endLoc});
272 
273     return exportDeclaration;
274 }
275 
ParseExportDeclaration(StatementParsingFlags flags)276 ir::Statement *TSParser::ParseExportDeclaration(StatementParsingFlags flags)
277 {
278     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
279     Lexer()->NextToken();  // eat `export` keyword
280 
281     switch (Lexer()->GetToken().Type()) {
282         case lexer::TokenType::KEYW_DEFAULT: {
283             return ParseExportDefaultDeclaration(startLoc);
284         }
285         case lexer::TokenType::PUNCTUATOR_MULTIPLY: {
286             return ParseExportAllDeclaration(startLoc);
287         }
288         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
289             return ParseExportNamedSpecifiers(startLoc);
290         }
291         case lexer::TokenType::KEYW_IMPORT: {
292             return ParseTsImportEqualsDeclaration(startLoc, true);
293         }
294         case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: {
295             return ParseExportDefaultDeclaration(startLoc, true);
296         }
297         default: {
298             auto ret = ParseNamedExportDeclaration(startLoc);
299             ES2PANDA_ASSERT(ret != nullptr);
300             if (ret->IsBrokenStatement()) {
301                 return ret;
302             }
303             ir::ExportNamedDeclaration *exportDecl = ret->AsExportNamedDeclaration();
304             if (exportDecl->Decl()->IsVariableDeclaration() && ((flags & StatementParsingFlags::GLOBAL) == 0) &&
305                 exportDecl->Parent() != nullptr && !exportDecl->Parent()->IsTSModuleBlock() &&
306                 !GetContext().IsModule()) {
307                 ThrowSyntaxError("Modifiers cannot appear here'");
308             }
309 
310             return exportDecl;
311         }
312     }
313 }
314 
ParseConstStatement(StatementParsingFlags flags)315 ir::Statement *TSParser::ParseConstStatement(StatementParsingFlags flags)
316 {
317     lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
318     Lexer()->NextToken();
319 
320     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
321         return ParseEnumDeclaration(true);
322     }
323 
324     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
325         ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
326     }
327 
328     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
329     ES2PANDA_ASSERT(variableDecl != nullptr);
330     variableDecl->SetStart(constVarStar);
331     ConsumeSemicolon(variableDecl);
332 
333     return variableDecl;
334 }
335 
ParsePotentialConstEnum(VariableParsingFlags flags)336 ir::Statement *TSParser::ParsePotentialConstEnum(VariableParsingFlags flags)
337 {
338     if ((flags & VariableParsingFlags::CONST) == 0) {
339         ThrowSyntaxError("Variable declaration expected.");
340     }
341 
342     return ParseEnumDeclaration(true);
343 }
344 
ParseImportDeclaration(StatementParsingFlags flags)345 ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
346 {
347     char32_t nextChar = Lexer()->Lookahead();
348     if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
349         return ParseExpressionStatement();
350     }
351 
352     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
353     Lexer()->NextToken();  // eat import
354 
355     ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
356 
357     ir::StringLiteral *source = nullptr;
358 
359     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
360         ir::AstNode *astNode = ParseImportSpecifiers(&specifiers);
361         if (astNode != nullptr) {
362             ES2PANDA_ASSERT(astNode->IsTSImportEqualsDeclaration());
363             astNode->SetRange({startLoc, Lexer()->GetToken().End()});
364             ConsumeSemicolon(astNode->AsTSImportEqualsDeclaration());
365             return astNode->AsTSImportEqualsDeclaration();
366         }
367         source = ParseFromClause(true);
368     } else {
369         source = ParseFromClause(false);
370     }
371 
372     ES2PANDA_ASSERT(source != nullptr);
373     lexer::SourcePosition endLoc = source->End();
374     auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
375     ES2PANDA_ASSERT(importDeclaration != nullptr);
376     importDeclaration->SetRange({startLoc, endLoc});
377 
378     ConsumeSemicolon(importDeclaration);
379 
380     return importDeclaration;
381 }
382 
383 }  // namespace ark::es2panda::parser