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