• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 "ETSparser.h"
17 #include "parser/parserFlags.h"
18 #include "parser/parserStatusContext.h"
19 #include "util/errorRecovery.h"
20 #include "util/helpers.h"
21 #include "ir/astNode.h"
22 #include "ir/base/catchClause.h"
23 #include "ir/base/classDefinition.h"
24 #include "ir/base/scriptFunction.h"
25 #include "ir/expression.h"
26 #include "ir/expressions/arrayExpression.h"
27 #include "ir/expressions/binaryExpression.h"
28 #include "ir/expressions/conditionalExpression.h"
29 #include "ir/expressions/literals/stringLiteral.h"
30 #include "ir/expressions/objectExpression.h"
31 #include "ir/expressions/sequenceExpression.h"
32 #include "ir/module/exportAllDeclaration.h"
33 #include "ir/module/exportDefaultDeclaration.h"
34 #include "ir/module/exportNamedDeclaration.h"
35 #include "ir/module/exportSpecifier.h"
36 #include "ir/module/importDeclaration.h"
37 #include "ir/module/importDefaultSpecifier.h"
38 #include "ir/module/importNamespaceSpecifier.h"
39 #include "ir/module/importSpecifier.h"
40 #include "ir/statements/blockStatement.h"
41 #include "ir/statements/breakStatement.h"
42 #include "ir/statements/classDeclaration.h"
43 #include "ir/statements/continueStatement.h"
44 #include "ir/statements/debuggerStatement.h"
45 #include "ir/statements/doWhileStatement.h"
46 #include "ir/statements/emptyStatement.h"
47 #include "ir/statements/expressionStatement.h"
48 #include "ir/statements/forInStatement.h"
49 #include "ir/statements/forOfStatement.h"
50 #include "ir/statements/forUpdateStatement.h"
51 #include "ir/statements/functionDeclaration.h"
52 #include "ir/statements/ifStatement.h"
53 #include "ir/statements/labelledStatement.h"
54 #include "ir/statements/returnStatement.h"
55 #include "ir/statements/switchCaseStatement.h"
56 #include "ir/statements/switchStatement.h"
57 #include "ir/statements/throwStatement.h"
58 #include "ir/statements/tryStatement.h"
59 #include "ir/statements/variableDeclaration.h"
60 #include "ir/statements/variableDeclarator.h"
61 #include "ir/statements/whileStatement.h"
62 #include "ir/ets/etsStructDeclaration.h"
63 #include "lexer/lexer.h"
64 #include "lexer/token/letters.h"
65 #include "lexer/token/sourceLocation.h"
66 #include "util/recursiveGuard.h"
67 #include "util/ustring.h"
68 #include "generated/diagnostic.h"
69 
70 #include "parserImpl.h"
71 
72 namespace ark::es2panda::parser {
73 
74 using namespace std::literals::string_literals;
75 
76 // NOLINTNEXTLINE(google-default-arguments)
ParseStatementLiteralIdentHelper(StatementParsingFlags flags)77 ir::Statement *ParserImpl::ParseStatementLiteralIdentHelper(StatementParsingFlags flags)
78 {
79     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_STRUCT) {
80         return ParseStructStatement(flags, ir::ClassDefinitionModifiers::NONE);
81     }
82 
83     if (lexer_->Lookahead() == lexer::LEX_CHAR_COLON) {
84         const auto pos = lexer_->Save();
85         lexer_->NextToken();
86         return ParseLabelledStatement(pos);
87     }
88 
89     return ParsePotentialExpressionStatement(flags);
90 }
91 
92 // NOLINTNEXTLINE(google-default-arguments)
ParseStatementPunctuatorsHelper(StatementParsingFlags flags)93 ir::Statement *ParserImpl::ParseStatementPunctuatorsHelper(StatementParsingFlags flags)
94 {
95     TrackRecursive trackRecursive(RecursiveCtx());
96     if (!trackRecursive) {
97         LogError(diagnostic::DEEP_NESTING);
98         while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) {
99             Lexer()->NextToken();
100         }
101         return AllocBrokenStatement(Lexer()->GetToken().Loc());
102     }
103     switch (lexer_->GetToken().Type()) {
104         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE:
105             return ParseBlockStatement();
106         case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
107             return ParseEmptyStatement();
108         case lexer::TokenType::PUNCTUATOR_FORMAT:  // 1
109             if (lexer_->Lookahead() == static_cast<char32_t>(STATEMENT_FORMAT_NODE)) {
110                 return ParseStatementFormatPlaceholder();
111             }
112             [[fallthrough]];
113         default:
114             return ParseExpressionStatement(flags);
115     }
116 }
117 
118 // NOLINTNEXTLINE(google-default-arguments)
ParseStatementControlFlowTokenHelper(StatementParsingFlags flags)119 ir::Statement *ParserImpl::ParseStatementControlFlowTokenHelper(StatementParsingFlags flags)
120 {
121     switch (lexer_->GetToken().Type()) {
122         case lexer::TokenType::KEYW_IF:
123             return ParseIfStatement();
124         case lexer::TokenType::KEYW_DO:
125             return ParseDoWhileStatement();
126         case lexer::TokenType::KEYW_FOR:
127             return ParseForStatement();
128         case lexer::TokenType::KEYW_TRY:
129             return ParseTryStatement();
130         case lexer::TokenType::KEYW_WHILE:
131             return ParseWhileStatement();
132         case lexer::TokenType::KEYW_BREAK:
133             return ParseBreakStatement();
134         case lexer::TokenType::KEYW_CONTINUE:
135             return ParseContinueStatement();
136         case lexer::TokenType::KEYW_THROW:
137             return ParseThrowStatement();
138         case lexer::TokenType::KEYW_RETURN:
139             return ParseReturnStatement();
140         case lexer::TokenType::KEYW_SWITCH:
141             return ParseSwitchStatement();
142         default:
143             return ParseExpressionStatement(flags);
144     }
145 }
146 
147 // NOLINTNEXTLINE(google-default-arguments)
ParseStatement(StatementParsingFlags flags)148 ir::Statement *ParserImpl::ParseStatement(StatementParsingFlags flags)
149 {
150     if (IsETSParser()) {
151         AsETSParser()->HandleJsDocLikeComments();
152     }
153 
154     const auto tokenType = lexer_->GetToken().Type();
155     bool isPunctuatorToken = tokenType == lexer::TokenType::PUNCTUATOR_LEFT_BRACE ||
156                              tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON ||
157                              tokenType == lexer::TokenType::PUNCTUATOR_FORMAT;
158     if (isPunctuatorToken) {
159         return ParseStatementPunctuatorsHelper(flags);
160     }
161 
162     bool isControlFlowToken = tokenType == lexer::TokenType::KEYW_IF || tokenType == lexer::TokenType::KEYW_DO ||
163                               tokenType == lexer::TokenType::KEYW_FOR || tokenType == lexer::TokenType::KEYW_TRY ||
164                               tokenType == lexer::TokenType::KEYW_WHILE || tokenType == lexer::TokenType::KEYW_BREAK ||
165                               tokenType == lexer::TokenType::KEYW_CONTINUE ||
166                               tokenType == lexer::TokenType::KEYW_THROW || tokenType == lexer::TokenType::KEYW_RETURN ||
167                               tokenType == lexer::TokenType::KEYW_SWITCH;
168     if (isControlFlowToken) {
169         return ParseStatementControlFlowTokenHelper(flags);
170     }
171     return ParseStatementBasedOnTokenType(flags);
172 }
173 
ParseStatementBasedOnTokenType(StatementParsingFlags flags)174 ir::Statement *ParserImpl::ParseStatementBasedOnTokenType(StatementParsingFlags flags)
175 {
176     switch (lexer_->GetToken().Type()) {
177         case lexer::TokenType::KEYW_EXPORT:
178             return ParseExportDeclaration(flags);
179         case lexer::TokenType::KEYW_IMPORT:
180             return ParseImportDeclaration(flags);
181         case lexer::TokenType::KEYW_FUNCTION:
182             return ParseFunctionStatement(flags);
183         case lexer::TokenType::KEYW_ABSTRACT:
184         case lexer::TokenType::KEYW_FINAL:
185         case lexer::TokenType::KEYW_CLASS:
186             return ParseClassStatement(flags, ir::ClassDefinitionModifiers::NONE);
187         case lexer::TokenType::KEYW_VAR:
188             return ParseVarStatement();
189         case lexer::TokenType::KEYW_LET:
190             return ParseLetStatement(flags);
191         case lexer::TokenType::KEYW_CONST:
192             return ParseConstStatement(flags);
193         case lexer::TokenType::KEYW_DEBUGGER:
194             return ParseDebuggerStatement();
195         case lexer::TokenType::LITERAL_IDENT:
196             if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_VAR) {
197                 return ParseVarStatement();
198             }
199             return ParseStatementLiteralIdentHelper(flags);
200         case lexer::TokenType::KEYW_WITH:
201             LogError(diagnostic::WITH_DEPRECATED);
202             lexer_->NextToken();
203             return nullptr;
204         case lexer::TokenType::KEYW_ENUM:
205             return ParseEnumDeclaration();
206         case lexer::TokenType::KEYW_INTERFACE:
207             return ParseInterfaceStatement(flags);
208         case lexer::TokenType::PUNCTUATOR_AT:
209             if (IsETSParser()) {
210                 return ParseAnnotationsInStatement(flags);
211             }
212             [[fallthrough]];
213         default:
214             return ParseExpressionStatement(flags);
215     }
216 }
217 
ParseAnnotationsInStatement(StatementParsingFlags flags)218 ir::Statement *ParserImpl::ParseAnnotationsInStatement([[maybe_unused]] StatementParsingFlags flags)
219 {
220     ES2PANDA_UNREACHABLE();
221 }
222 
ParseVarStatement()223 ir::Statement *ParserImpl::ParseVarStatement()
224 {
225     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::VAR);
226     ConsumeSemicolon(variableDecl);
227     return variableDecl;
228 }
229 
ParseLetStatement(StatementParsingFlags flags)230 ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags)
231 {
232     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
233         LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
234     }
235 
236     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::LET);
237     ES2PANDA_ASSERT(variableDecl != nullptr);
238     if (variableDecl->IsBrokenStatement()) {  // Error processing.
239         return variableDecl;
240     }
241 
242     ConsumeSemicolon(variableDecl);
243     return variableDecl;
244 }
245 
ParseConstStatement(StatementParsingFlags flags)246 ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags)
247 {
248     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
249         LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
250     }
251 
252     lexer::SourcePosition constVarStar = lexer_->GetToken().Start();
253     lexer_->NextToken();
254 
255     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
256     ES2PANDA_ASSERT(variableDecl != nullptr);
257     if (variableDecl->IsBrokenStatement()) {  // Error processing.
258         return variableDecl;
259     }
260 
261     variableDecl->SetStart(constVarStar);
262     ConsumeSemicolon(variableDecl);
263 
264     return variableDecl;
265 }
266 
ParseEmptyStatement()267 ir::EmptyStatement *ParserImpl::ParseEmptyStatement()
268 {
269     auto *empty = AllocNode<ir::EmptyStatement>();
270     ES2PANDA_ASSERT(empty != nullptr);
271     empty->SetRange(lexer_->GetToken().Loc());
272     lexer_->NextToken();
273     return empty;
274 }
275 
ParseDebuggerStatement()276 ir::Statement *ParserImpl::ParseDebuggerStatement()
277 {
278     auto *debuggerNode = AllocNode<ir::DebuggerStatement>();
279     ES2PANDA_ASSERT(debuggerNode != nullptr);
280     debuggerNode->SetRange(lexer_->GetToken().Loc());
281     lexer_->NextToken();
282     ConsumeSemicolon(debuggerNode);
283     return debuggerNode;
284 }
285 
ParseFunctionStatement(StatementParsingFlags flags)286 ir::Statement *ParserImpl::ParseFunctionStatement(StatementParsingFlags flags)
287 {
288     CheckFunctionDeclaration(flags);
289 
290     if ((flags & StatementParsingFlags::STMT_LEXICAL_SCOPE_NEEDED) == 0) {
291         return ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
292     }
293 
294     auto *funcDecl = ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
295     ArenaVector<ir::Statement *> stmts(Allocator()->Adapter());
296     stmts.push_back(funcDecl);
297 
298     auto *localBlockStmt = AllocNode<ir::BlockStatement>(Allocator(), std::move(stmts));
299     ES2PANDA_ASSERT(localBlockStmt != nullptr);
300     localBlockStmt->SetRange(funcDecl->Range());
301 
302     return funcDecl;
303 }
304 
ParsePotentialExpressionStatement(StatementParsingFlags flags)305 ir::Statement *ParserImpl::ParsePotentialExpressionStatement(StatementParsingFlags flags)
306 {
307     return ParseExpressionStatement(flags);
308 }
309 
310 // NOLINTNEXTLINE(google-default-arguments)
ParseStructStatement(StatementParsingFlags flags,ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags modFlags)311 ir::Statement *ParserImpl::ParseStructStatement([[maybe_unused]] StatementParsingFlags flags,
312                                                 ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags)
313 {
314     LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"STRUCT"});
315     return ParseStructDeclaration(modifiers, modFlags);
316 }
317 
318 // NOLINTNEXTLINE(google-default-arguments)
ParseClassStatement(StatementParsingFlags flags,ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags modFlags)319 ir::Statement *ParserImpl::ParseClassStatement(StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers,
320                                                ir::ModifierFlags modFlags)
321 {
322     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
323         LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
324     }
325 
326     return ParseClassDeclaration(modifiers, modFlags);
327 }
328 
ParseInterfaceStatement(StatementParsingFlags flags)329 ir::Statement *ParserImpl::ParseInterfaceStatement(StatementParsingFlags flags)
330 {
331     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
332         LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
333     }
334 
335     return ParseInterfaceDeclaration(false);
336 }
337 
ParseStructDeclaration(ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)338 ir::Statement *ParserImpl::ParseStructDeclaration(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags)
339 {
340     const lexer::SourcePosition startLoc = lexer_->GetToken().Start();
341     modifiers |= ir::ClassDefinitionModifiers::DECLARATION;
342     if (IsExternal()) {
343         modifiers |= ir::ClassDefinitionModifiers::FROM_EXTERNAL;
344     }
345 
346     ir::ClassDefinition *classDefinition = ParseClassDefinition(modifiers, flags);
347     if (classDefinition == nullptr) {  // Error processing.
348         // Error is logged inside ParseClassDefinition
349         return AllocBrokenStatement(Lexer()->GetToken().Loc());
350     }
351 
352     lexer::SourcePosition endLoc = classDefinition->End();
353     auto *structDecl = AllocNode<ir::ETSStructDeclaration>(classDefinition, Allocator());
354     ES2PANDA_ASSERT(structDecl != nullptr);
355     structDecl->SetRange({startLoc, endLoc});
356     return structDecl;
357 }
358 
ParseClassDeclaration(ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)359 ir::Statement *ParserImpl::ParseClassDeclaration(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags)
360 {
361     const lexer::SourcePosition startLoc = lexer_->GetToken().Start();
362     modifiers |= ir::ClassDefinitionModifiers::DECLARATION;
363     if (IsExternal()) {
364         modifiers |= ir::ClassDefinitionModifiers::FROM_EXTERNAL;
365     }
366 
367     ir::ClassDefinition *classDefinition = ParseClassDefinition(modifiers, flags);
368     if (classDefinition == nullptr) {  // Error processing.
369         // Error is logged inside ParseClassDefinition
370         return AllocBrokenStatement(Lexer()->GetToken().Loc());
371     }
372 
373     lexer::SourcePosition endLoc = classDefinition->End();
374     auto *classDecl = AllocNode<ir::ClassDeclaration>(classDefinition, Allocator());
375     ES2PANDA_ASSERT(classDecl != nullptr);
376     classDecl->SetRange({startLoc, endLoc});
377     return classDecl;
378 }
379 
CheckFunctionDeclaration(StatementParsingFlags flags)380 void ParserImpl::CheckFunctionDeclaration(StatementParsingFlags flags)
381 {
382     if ((flags & StatementParsingFlags::LABELLED) != 0) {
383         LogError(diagnostic::STRICT_MODE_FUNC_DECL);
384     }
385 
386     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
387         if ((flags & (StatementParsingFlags::IF_ELSE | StatementParsingFlags::LABELLED)) == 0) {
388             LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
389         }
390 
391         if (lexer_->Lookahead() == lexer::LEX_CHAR_ASTERISK) {
392             LogError(diagnostic::GENERATORS_ONLY_TOP_LEVEL_OR_INSIDE_BLOCK);
393         }
394     }
395 }
396 
ConsumeSemicolon(ir::Statement * statement)397 void ParserImpl::ConsumeSemicolon(ir::Statement *statement)
398 {
399     auto const &token = lexer_->GetToken();
400     auto tokenType = token.Type();
401     if (tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
402         ES2PANDA_ASSERT(statement != nullptr);
403         statement->SetEnd(token.End());
404         lexer_->NextToken();
405         return;
406     }
407 
408     if (!token.NewLine() && tokenType != lexer::TokenType::EOS &&
409         tokenType != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
410         LogUnexpectedToken(token);
411     }
412 }
413 
ParseStatementList(StatementParsingFlags flags)414 ArenaVector<ir::Statement *> ParserImpl::ParseStatementList(StatementParsingFlags flags)
415 {
416     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
417         lexer_->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE)) {
418         return std::move(ParseStatementsArrayFormatPlaceholder());
419     }
420 
421     ArenaVector<ir::Statement *> statements(Allocator()->Adapter());
422     ParseDirectivePrologue(&statements);
423 
424     auto endType =
425         (flags & StatementParsingFlags::GLOBAL) != 0 ? lexer::TokenType::EOS : lexer::TokenType::PUNCTUATOR_RIGHT_BRACE;
426 
427     while (lexer_->GetToken().Type() != endType && lexer_->GetToken().Type() != lexer::TokenType::EOS) {
428         util::ErrorRecursionGuard infiniteLoopBlocker(lexer_);
429 
430         if (auto statement = ParseStatement(flags); statement != nullptr) {
431             statements.push_back(statement);
432         }
433     }
434 
435     return statements;
436 }
437 
ParseDirective(ArenaVector<ir::Statement * > * statements)438 bool ParserImpl::ParseDirective(ArenaVector<ir::Statement *> *statements)
439 {
440     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING);
441 
442     const util::StringView &str = lexer_->GetToken().String();
443 
444     const auto status = static_cast<ParserStatus>(
445         context_.Status() & (ParserStatus::CONSTRUCTOR_FUNCTION | ParserStatus::HAS_COMPLEX_PARAM));
446     if (status == ParserStatus::HAS_COMPLEX_PARAM && str.Is("use strict")) {
447         LogError(diagnostic::ILLEGAL_USE_STRICT);
448     }
449 
450     ir::Expression *exprNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
451     if (exprNode == nullptr) {  // Error processing.
452         return false;
453     }
454 
455     bool isDirective = exprNode->IsStringLiteral();
456 
457     auto *exprStatement = AllocNode<ir::ExpressionStatement>(exprNode);
458     ES2PANDA_ASSERT(exprStatement != nullptr);
459     exprStatement->SetRange(exprNode->Range());
460 
461     ConsumeSemicolon(exprStatement);
462     statements->push_back(exprStatement);
463 
464     return isDirective;
465 }
466 
ParseDirectivePrologue(ArenaVector<ir::Statement * > * statements)467 void ParserImpl::ParseDirectivePrologue(ArenaVector<ir::Statement *> *statements)
468 {
469     while (true) {
470         if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_STRING || !ParseDirective(statements)) {
471             break;
472         }
473     }
474 }
475 
ValidateLabeledStatement(lexer::TokenType type)476 bool ParserImpl::ValidateLabeledStatement([[maybe_unused]] lexer::TokenType type)
477 {
478     return true;
479 }
480 
ParseBlockStatement()481 ir::BlockStatement *ParserImpl::ParseBlockStatement()
482 {
483     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
484     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
485 
486     auto statements = ParseStatementList();
487 
488     auto *blockNode = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements));
489     ES2PANDA_ASSERT(blockNode != nullptr);
490     blockNode->SetRange({startLoc, lexer_->GetToken().End()});
491 
492     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
493 
494     return blockNode;
495 }
496 
ReportPossibleOutOfBoundaryJumpError(bool allowBreak)497 void ParserImpl::ReportPossibleOutOfBoundaryJumpError([[maybe_unused]] bool allowBreak) {}
498 
ReportIllegalBreakError(const lexer::SourcePosition & startLoc)499 void ParserImpl::ReportIllegalBreakError(const lexer::SourcePosition &startLoc)
500 {
501     LogError(diagnostic::ILLEGAL_BREAK, {}, startLoc);
502 }
503 
ParseBreakStatement()504 ir::Statement *ParserImpl::ParseBreakStatement()
505 {
506     bool allowBreak = (context_.Status() & (ParserStatus::IN_ITERATION | ParserStatus::IN_SWITCH)) != 0;
507 
508     ReportPossibleOutOfBoundaryJumpError(allowBreak);
509 
510     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
511     lexer_->NextToken();
512 
513     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON ||
514         lexer_->GetToken().Type() == lexer::TokenType::EOS || lexer_->GetToken().NewLine() ||
515         lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
516         if (!allowBreak) {
517             ReportIllegalBreakError(startLoc);
518         }
519 
520         auto *breakStatement = AllocNode<ir::BreakStatement>();
521         ES2PANDA_ASSERT(breakStatement != nullptr);
522         breakStatement->SetRange({startLoc, lexer_->GetToken().End()});
523 
524         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
525             lexer_->NextToken();
526         }
527 
528         return breakStatement;
529     }
530 
531     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
532         LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
533     }
534 
535     const auto &label = lexer_->GetToken().Ident();
536     if (!ValidateBreakLabel(label)) {
537         LogError(diagnostic::UNDEFINED_LABEL);
538     }
539 
540     auto *identNode = AllocNode<ir::Identifier>(label, Allocator());
541     ES2PANDA_ASSERT(identNode != nullptr);
542     identNode->SetRange(lexer_->GetToken().Loc());
543 
544     auto *breakStatement = AllocNode<ir::BreakStatement>(identNode);
545     ES2PANDA_ASSERT(breakStatement != nullptr);
546     breakStatement->SetRange({startLoc, lexer_->GetToken().End()});
547 
548     lexer_->NextToken();
549     ConsumeSemicolon(breakStatement);
550 
551     return breakStatement;
552 }
553 
ReportIllegalContinueError()554 void ParserImpl::ReportIllegalContinueError()
555 {
556     LogError(diagnostic::ILLEGALE_CONTINUE);
557 }
558 
ParseContinueStatement()559 ir::Statement *ParserImpl::ParseContinueStatement()
560 {
561     ReportPossibleOutOfBoundaryJumpError((context_.Status() & (ParserStatus::IN_ITERATION | ParserStatus::IN_SWITCH)) !=
562                                          0U);
563 
564     if ((context_.Status() & ParserStatus::IN_ITERATION) == 0) {
565         ReportIllegalContinueError();
566     }
567 
568     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
569     lexer::SourcePosition endLoc = lexer_->GetToken().End();
570     lexer_->NextToken();
571 
572     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
573         auto *continueStatement = AllocNode<ir::ContinueStatement>();
574         ES2PANDA_ASSERT(continueStatement != nullptr);
575         continueStatement->SetRange({startLoc, lexer_->GetToken().End()});
576         lexer_->NextToken();
577         return continueStatement;
578     }
579 
580     if (lexer_->GetToken().NewLine() || lexer_->GetToken().Type() == lexer::TokenType::EOS ||
581         lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
582         auto *continueStatement = AllocNode<ir::ContinueStatement>();
583         ES2PANDA_ASSERT(continueStatement != nullptr);
584         continueStatement->SetRange({startLoc, endLoc});
585         return continueStatement;
586     }
587 
588     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
589         LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
590     }
591 
592     const auto &label = lexer_->GetToken().Ident();
593     if (!ValidateContinueLabel(label)) {
594         LogError(diagnostic::UNDEFINED_LABEL);
595     }
596 
597     auto *identNode = AllocNode<ir::Identifier>(label, Allocator());
598     ES2PANDA_ASSERT(identNode != nullptr);
599     identNode->SetRange(lexer_->GetToken().Loc());
600 
601     auto *continueStatement = AllocNode<ir::ContinueStatement>(identNode);
602     ES2PANDA_ASSERT(continueStatement != nullptr);
603     continueStatement->SetRange({startLoc, lexer_->GetToken().End()});
604 
605     lexer_->NextToken();
606     ConsumeSemicolon(continueStatement);
607 
608     return continueStatement;
609 }
610 
ParseDoWhileStatement()611 ir::Statement *ParserImpl::ParseDoWhileStatement()
612 {
613     IterationContext iterCtx(&context_);
614 
615     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
616     lexer_->NextToken();
617 
618     ir::Statement *body = ParseStatement();
619     if (IsBrokenStatement(body)) {
620         LogError(diagnostic::MISSING_LOOP_BODY, {"do while"});
621     }
622 
623     if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_WHILE) {
624         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
625             // do {} (true)
626             LogError(diagnostic::UNEXPECTED_TOKEN_WHILE);  // just skip the token
627         } else {
628             // do {} whle (true)
629             LogExpectedToken(lexer::TokenType::KEYW_WHILE);
630             lexer_->NextToken();
631         }
632     } else {
633         lexer_->NextToken();
634     }
635 
636     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
637         LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
638     }
639 
640     lexer_->NextToken();
641 
642     ir::Expression *condition = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
643     if (condition->IsBrokenExpression()) {
644         LogError(diagnostic::MISSING_LOOP_CONDITION, {"do while"});
645     }
646 
647     auto endLoc = lexer_->GetToken().End();
648     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
649 
650     auto *doWhileStatement = AllocNode<ir::DoWhileStatement>(body, condition);
651     ES2PANDA_ASSERT(doWhileStatement != nullptr);
652     doWhileStatement->SetRange({startLoc, endLoc});
653 
654     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
655         doWhileStatement->SetEnd(lexer_->GetToken().End());
656         lexer_->NextToken();
657     }
658 
659     return doWhileStatement;
660 }
661 
ParseFunctionDeclaration(bool canBeAnonymous,ParserStatus newStatus)662 ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymous, ParserStatus newStatus)
663 {
664     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
665 
666     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION);
667     ParserStatus savedStatus = context_.Status();
668 
669     lexer_->NextToken();
670 
671     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
672         newStatus |= ParserStatus::GENERATOR_FUNCTION;
673         lexer_->NextToken();
674     }
675 
676     context_.Status() = savedStatus;
677 
678     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
679         if (canBeAnonymous) {
680             ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE);
681             ES2PANDA_ASSERT(func != nullptr);
682             func->SetStart(startLoc);
683 
684             auto *funcDecl = AllocNode<ir::FunctionDeclaration>(Allocator(), func, true);
685             ES2PANDA_ASSERT(funcDecl != nullptr);
686             funcDecl->SetRange(func->Range());
687             return funcDecl;
688         }
689         // test exists for ts extension
690         LogError(diagnostic::UNEXPECTED_TOKEN_ID_FUN);
691         lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
692         lexer_->GetToken().SetTokenStr(ERROR_LITERAL);
693     }
694 
695     CheckRestrictedBinding();
696     auto *identNode = ExpectIdentifier();
697 
698     newStatus |= ParserStatus::FUNCTION_DECLARATION;
699     ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE);
700     ES2PANDA_ASSERT(func != nullptr);
701 
702     func->SetIdent(identNode);
703     func->SetStart(startLoc);
704     auto *funcDecl = AllocNode<ir::FunctionDeclaration>(Allocator(), func);
705     ES2PANDA_ASSERT(funcDecl != nullptr);
706     funcDecl->SetRange(func->Range());
707 
708     if (func->IsOverload() && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
709         lexer_->NextToken();
710     }
711 
712     return funcDecl;
713 }
714 
ParseExpressionStatement(StatementParsingFlags flags)715 ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags)
716 {
717     const auto startPos = lexer_->Save();
718     ParserStatus savedStatus = context_.Status();
719 
720     auto tokenType = lexer_->GetToken().Type();
721     if (tokenType == lexer::TokenType::KEYW_PUBLIC || tokenType == lexer::TokenType::KEYW_PRIVATE ||
722         tokenType == lexer::TokenType::KEYW_PROTECTED) {
723         lexer_->NextToken();
724         if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_CLASS ||
725             lexer_->GetToken().Type() == lexer::TokenType::KEYW_INTERFACE) {
726             LogError(diagnostic::LOCAL_CLASS_ACCESS_MOD, {}, startPos.GetToken().Start());
727             // Suppose it is a class declaration.
728             return ParseClassDeclaration(ir::ClassDefinitionModifiers::NONE);
729         }
730         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
731             LogError(diagnostic::ANNOTATION_DECLARATION_ACCESS_MODIFIER, {}, startPos.GetToken().Start());
732         }
733         lexer_->Rewind(startPos);
734     }
735 
736     if (lexer_->GetToken().IsAsyncModifier()) {
737         lexer_->NextToken();
738 
739         if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION && !lexer_->GetToken().NewLine()) {
740             if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
741                 LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT);
742             }
743 
744             ir::FunctionDeclaration *functionDecl = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
745             functionDecl->SetStart(startPos.GetToken().Start());
746 
747             return functionDecl;
748         }
749 
750         lexer_->Rewind(startPos);
751     }
752 
753     ir::Expression *exprNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
754     context_.Status() = savedStatus;
755     lexer::SourcePosition endPos = exprNode->End();
756 
757     auto *exprStatementNode = AllocNode<ir::ExpressionStatement>(exprNode);
758     ES2PANDA_ASSERT(exprStatementNode != nullptr);
759     exprStatementNode->SetRange({startPos.GetToken().Start(), endPos});
760     ConsumeSemicolon(exprStatementNode);
761 
762     return exprStatementNode;
763 }
764 
765 // NOLINTBEGIN(cert-err58-cpp)
766 static std::string const INVALID_LEFT_HAND_IN_FOR_OF =
767     "Invalid left-hand side in 'for' statement: must have a single binding."s;
768 static std::string const MISSING_LEFT_IN_FOR = "Missing left parenthesis in 'for' statement."s;
769 static std::string const MISSING_RIGHT_IN_FOR = "Missing right parenthesis in 'for' statement."s;
770 static std::string const INVALID_TYPE_ANNOTATION_IN_FOR =
771     "Type annotation is not allowed when existing variable is used as loop iterator in 'for' statement."s;
772 // NOLINTEND(cert-err58-cpp)
773 
ParseForInOf(ir::AstNode * initNode,ExpressionParseFlags exprFlags,bool isAwait)774 std::tuple<ForStatementKind, ir::Expression *, ir::Expression *> ParserImpl::ParseForInOf(
775     ir::AstNode *initNode, ExpressionParseFlags exprFlags, bool isAwait)
776 {
777     ForStatementKind forKind = ForStatementKind::UPDATE;
778     ir::Expression *updateNode = nullptr;
779     ir::Expression *rightNode = nullptr;
780 
781     if (lexer_->GetToken().IsForInOf()) {
782         const ir::VariableDeclarator *varDecl = initNode->AsVariableDeclaration()->Declarators().front();
783 
784         if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IN) {
785             if (varDecl->Init() != nullptr) {
786                 LogError(diagnostic::FOR_IN_LOOP_HAS_INIT);
787             }
788             forKind = ForStatementKind::IN;
789             exprFlags = ExpressionParseFlags::ACCEPT_COMMA;
790             ValidateForInStatement();
791         } else {
792             if (varDecl->Init() != nullptr) {
793                 LogError(diagnostic::FOR_OF_LOOP_HAS_INIT);
794             }
795 
796             forKind = ForStatementKind::OF;
797         }
798 
799         lexer_->NextToken();
800         rightNode = ParseExpression(exprFlags);
801     } else {
802         if (IsETSParser()) {
803             ExpectToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
804         }
805         if (isAwait) {
806             LogUnexpectedToken(Lexer()->GetToken());
807         }
808 
809         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
810             LogError(diagnostic::INVALID_LEFT_FOR_IN_OF);
811             return {forKind, rightNode, updateNode};
812         }
813 
814         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
815             lexer_->NextToken();
816         } else {
817             rightNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
818             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
819                 LogExpectedToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
820             }
821             lexer_->NextToken();
822         }
823 
824         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
825             updateNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
826         }
827     }
828 
829     return {forKind, rightNode, updateNode};
830 }
831 
ParseIsForInOf(ir::Expression * leftNode,ExpressionParseFlags exprFlags)832 std::tuple<ForStatementKind, ir::AstNode *, ir::Expression *, ir::Expression *> ParserImpl::ParseIsForInOf(
833     ir::Expression *leftNode, ExpressionParseFlags exprFlags)
834 {
835     ES2PANDA_ASSERT(lexer_->GetToken().IsForInOf());
836     ForStatementKind forKind = ForStatementKind::OF;
837 
838     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_IN) {
839         forKind = ForStatementKind::IN;
840         exprFlags = ExpressionParseFlags::ACCEPT_COMMA;
841         ValidateForInStatement();
842     }
843 
844     bool isValid = true;
845     switch (leftNode->Type()) {
846         case ir::AstNodeType::IDENTIFIER:
847         case ir::AstNodeType::MEMBER_EXPRESSION: {
848             break;
849         }
850         case ir::AstNodeType::ARRAY_EXPRESSION: {
851             isValid = leftNode->AsArrayExpression()->ConvertibleToArrayPattern();
852             break;
853         }
854         case ir::AstNodeType::OBJECT_EXPRESSION: {
855             isValid = leftNode->AsObjectExpression()->ConvertibleToObjectPattern();
856             break;
857         }
858         default: {
859             isValid = false;
860         }
861     }
862 
863     if (!isValid) {
864         ValidateLvalueAssignmentTarget(leftNode);
865     }
866 
867     lexer_->NextToken();
868 
869     return {forKind, leftNode, ParseExpression(exprFlags), nullptr};
870 }
871 
ParseForInOf(ir::Expression * leftNode,ExpressionParseFlags exprFlags,bool isAwait)872 std::tuple<ForStatementKind, ir::AstNode *, ir::Expression *, ir::Expression *> ParserImpl::ParseForInOf(
873     ir::Expression *leftNode, ExpressionParseFlags exprFlags, bool isAwait)
874 {
875     ir::Expression *updateNode = nullptr;
876     ir::Expression *rightNode = nullptr;
877     if (lexer_->GetToken().IsForInOf()) {
878         return ParseIsForInOf(leftNode, exprFlags);
879     }
880 
881     if (isAwait) {
882         LogUnexpectedToken(Lexer()->GetToken());
883     }
884 
885     ir::Expression *expr = ParseAssignmentExpression(leftNode);
886 
887     ir::AstNode *initNode =
888         lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ? ParseSequenceExpression(expr) : expr;
889     ES2PANDA_ASSERT(initNode != nullptr);
890 
891     if (initNode->IsConditionalExpression()) {
892         ir::ConditionalExpression *condExpr = initNode->AsConditionalExpression();
893         if (condExpr->Alternate()->IsBinaryExpression() &&
894             condExpr->Alternate()->AsBinaryExpression()->OperatorType() == lexer::TokenType::KEYW_IN) {
895             LogError(diagnostic::INVALID_LEFT_FOR_IN);
896             rightNode = AllocBrokenExpression(Lexer()->GetToken().Loc());
897             updateNode = AllocBrokenExpression(Lexer()->GetToken().Loc());
898             // CC-OFFNXT(G.FMT.03-CPP) project code style
899             return {ForStatementKind::IN, initNode, rightNode, updateNode};
900         }
901     }
902 
903     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
904         rightNode = AllocBrokenExpression(Lexer()->GetToken().Loc());
905         updateNode = AllocBrokenExpression(Lexer()->GetToken().Loc());
906         LogError(diagnostic::INVALID_LEFT_FOR_IN_OF);
907         return {ForStatementKind::UPDATE, initNode, rightNode, updateNode};
908     }
909 
910     ExpectToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
911 
912     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
913         lexer_->NextToken();
914     } else {
915         rightNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
916         ExpectToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
917     }
918 
919     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
920         updateNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
921     }
922 
923     return {ForStatementKind::UPDATE, initNode, rightNode, updateNode};
924 }
925 
ParseForUpdate(bool isAwait)926 std::tuple<ir::Expression *, ir::Expression *> ParserImpl::ParseForUpdate(bool isAwait)
927 {
928     if (isAwait) {
929         LogUnexpectedToken(Lexer()->GetToken());
930     }
931 
932     ir::Expression *updateNode = nullptr;
933     ir::Expression *rightNode = nullptr;
934 
935     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
936         lexer_->NextToken();
937     } else {
938         rightNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
939         ExpectToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
940     }
941 
942     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
943         updateNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::IN_FOR);
944     }
945 
946     return {rightNode, updateNode};
947 }
948 
ParseForLoopInitializer()949 std::tuple<ir::Expression *, ir::Statement *> ParserImpl::ParseForLoopInitializer()
950 {
951     VariableParsingFlags varFlags = VariableParsingFlags::IN_FOR;
952 
953     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_AWAIT) {
954         varFlags |= VariableParsingFlags::DISALLOW_INIT;
955         lexer_->NextToken();
956     }
957 
958     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
959 
960     lexer::TokenType tokenType;
961     auto const currentPosition = lexer_->Save();
962     do {
963         tokenType = lexer_->GetToken().Type();
964         if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_OF) {
965             varFlags |= VariableParsingFlags::FOR_OF;
966             break;
967         }
968         if (tokenType == lexer::TokenType::KEYW_IN) {
969             varFlags |= VariableParsingFlags::STOP_AT_IN;
970             break;
971         }
972         lexer_->NextToken();
973     } while (tokenType != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS &&
974              tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE &&
975              tokenType != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && tokenType != lexer::TokenType::EOS);
976     lexer_->Rewind(currentPosition);
977 
978     switch (lexer_->GetToken().Type()) {
979         case lexer::TokenType::KEYW_VAR:
980             return {nullptr, ParseVariableDeclaration(varFlags | VariableParsingFlags::VAR)};
981         case lexer::TokenType::KEYW_LET:
982             return {nullptr, ParseVariableDeclaration(varFlags | VariableParsingFlags::LET)};
983         case lexer::TokenType::KEYW_CONST: {
984             return {nullptr, ParseVariableDeclaration(varFlags | VariableParsingFlags::CONST |
985                                                       VariableParsingFlags::ACCEPT_CONST_NO_INIT)};
986         }
987         case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
988             if ((varFlags & VariableParsingFlags::DISALLOW_INIT) != 0 /*isAsync*/) {
989                 LogUnexpectedToken(Lexer()->GetToken());
990             }
991             lexer_->NextToken();
992             return {nullptr, nullptr};
993         default:
994             return {ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags::POTENTIALLY_IN_PATTERN), nullptr};
995     }
996 }
GetCanBeForInOf(ir::Expression * leftNode,ir::AstNode * initNode)997 bool ParserImpl::GetCanBeForInOf(ir::Expression *leftNode, ir::AstNode *initNode)
998 {
999     bool statementIsCorrect = initNode != nullptr && !initNode->IsBrokenStatement();
1000     bool expressionIsCorrect = leftNode != nullptr && !leftNode->IsBrokenExpression();
1001     bool canBeForInOf = expressionIsCorrect || statementIsCorrect;
1002     if (statementIsCorrect) {
1003         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
1004             lexer_->NextToken();
1005             canBeForInOf = false;
1006         } else if (initNode->AsVariableDeclaration()->Declarators().size() > 1 && lexer_->GetToken().IsForInOf()) {
1007             LogError(diagnostic::INVALID_LEFT_HAND_IN_FOR_OF, {},
1008                      initNode->AsVariableDeclaration()->Declarators()[1]->Start());
1009         }
1010     }
1011     return canBeForInOf;
1012 }
1013 
1014 struct ForStatementNodes {
1015     ir::AstNode *init;
1016     ir::Expression *right;
1017     ir::Expression *update;
1018     ir::Statement *body;
1019 };
1020 
CreateForStatement(ForStatementNodes && nodes,ForStatementKind forKind,const lexer::SourcePosition & startLoc,bool isAwait)1021 ir::Statement *ParserImpl::CreateForStatement(ForStatementNodes &&nodes, ForStatementKind forKind,
1022                                               const lexer::SourcePosition &startLoc, bool isAwait)
1023 {
1024     ES2PANDA_ASSERT(nodes.body != nullptr);
1025     ir::Statement *forStatement = nullptr;
1026 
1027     if (forKind == ForStatementKind::UPDATE) {
1028         forStatement = AllocNode<ir::ForUpdateStatement>(nodes.init, nodes.right, nodes.update, nodes.body);
1029     } else {
1030         if (nodes.init == nullptr || nodes.right == nullptr) {  // Error processing.
1031             // Error is logged inside ParseForLoopInitializer or ParseForUpdate, or ParseForInOf
1032             return AllocBrokenStatement(Lexer()->GetToken().Loc());
1033         }
1034 
1035         if (forKind == ForStatementKind::IN) {
1036             forStatement = AllocNode<ir::ForInStatement>(nodes.init, nodes.right, nodes.body);
1037         } else {
1038             forStatement = AllocNode<ir::ForOfStatement>(nodes.init, nodes.right, nodes.body, isAwait);
1039         }
1040     }
1041 
1042     ES2PANDA_ASSERT(forStatement != nullptr);
1043     forStatement->SetRange({startLoc, nodes.body->End()});
1044 
1045     return forStatement;
1046 }
1047 
ParseForStatement()1048 ir::Statement *ParserImpl::ParseForStatement()
1049 {
1050     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1051     ForStatementKind forKind = ForStatementKind::UPDATE;
1052     ir::AstNode *initNode = nullptr;
1053     ir::Expression *updateNode = nullptr;
1054     ir::Expression *leftNode = nullptr;
1055     ir::Expression *rightNode = nullptr;
1056 
1057     lexer_->NextToken();
1058     bool isAwait = lexer_->GetToken().Type() == lexer::TokenType::KEYW_AWAIT;
1059     std::tie(leftNode, initNode) = ParseForLoopInitializer();
1060 
1061     IterationContext iterCtx(&context_);
1062 
1063     // VariableDeclaration->DeclarationSize > 1 or seen semi_colon
1064     if (!GetCanBeForInOf(leftNode, initNode)) {
1065         std::tie(rightNode, updateNode) = ParseForUpdate(isAwait);
1066     } else if (leftNode != nullptr) {
1067         // initNode was parsed as LHS
1068         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1069             LogError(diagnostic::INVALID_TYPE_ANNOTATION_IN_FOR);
1070             lexer_->NextToken();  // eat ':'
1071         }
1072         std::tie(forKind, initNode, rightNode, updateNode) =
1073             ParseForInOf(leftNode, ExpressionParseFlags::NO_OPTS, isAwait);
1074     } else if (initNode != nullptr) {
1075         // initNode was parsed as VariableDeclaration and declaration size = 1
1076         std::tie(forKind, rightNode, updateNode) = ParseForInOf(initNode, ExpressionParseFlags::NO_OPTS, isAwait);
1077     }
1078 
1079     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) {
1080         lexer_->NextToken();
1081     }
1082     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1083 
1084     ir::Statement *bodyNode = ParseStatement();
1085     if (bodyNode == nullptr) {
1086         return AllocBrokenStatement(Lexer()->GetToken().Loc());
1087     }
1088 
1089     return CreateForStatement({initNode, rightNode, updateNode, bodyNode}, forKind, startLoc, isAwait);
1090 }
1091 
ReportIfBodyEmptyError(ir::Statement * consequent)1092 void ParserImpl::ReportIfBodyEmptyError([[maybe_unused]] ir::Statement *consequent) {}
1093 
ParseIfStatement()1094 ir::Statement *ParserImpl::ParseIfStatement()
1095 {
1096     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1097     lexer::SourcePosition endLoc;
1098     lexer_->NextToken();
1099 
1100     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1101     ir::Expression *test = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1102 
1103     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1104     ir::Statement *consequent = ParseStatement(StatementParsingFlags::IF_ELSE | StatementParsingFlags::ALLOW_LEXICAL);
1105     ES2PANDA_ASSERT(consequent != nullptr);
1106 
1107     ReportIfBodyEmptyError(consequent);
1108     endLoc = consequent->End();
1109     ir::Statement *alternate = nullptr;
1110 
1111     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_ELSE) {
1112         lexer_->NextToken();  // eat ELSE keyword
1113         alternate = ParseStatement(StatementParsingFlags::IF_ELSE | StatementParsingFlags::ALLOW_LEXICAL);
1114         if (alternate != nullptr) {  // Error processing.
1115             endLoc = alternate->End();
1116         }
1117     }
1118 
1119     auto *ifStatement = AllocNode<ir::IfStatement>(test, consequent, alternate);
1120     ES2PANDA_ASSERT(ifStatement != nullptr);
1121     ifStatement->SetRange({startLoc, endLoc});
1122     return ifStatement;
1123 }
1124 
ParseLabelledStatement(const lexer::LexerPosition & pos)1125 ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &pos)
1126 {
1127     const util::StringView &actualLabel = pos.GetToken().Ident();
1128 
1129     if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AWAIT && context_.IsModule()) {
1130         LogError(diagnostic::AWAIT_RESERVED_IDENTIFIER_IN_MODULE, {}, pos.GetToken().Start());
1131     }
1132 
1133     if (context_.FindLabel(actualLabel) != nullptr) {
1134         LogError(diagnostic::LABEL_ALREADY_DECLARED, {}, pos.GetToken().Start());
1135     }
1136 
1137     SavedParserContext newCtx(this, ParserStatus::IN_LABELED, actualLabel);
1138 
1139     auto *identNode = AllocNode<ir::Identifier>(actualLabel, Allocator());
1140     ES2PANDA_ASSERT(identNode != nullptr);
1141     identNode->SetRange(pos.GetToken().Loc());
1142 
1143     lexer_->NextToken();
1144 
1145     if (!ValidateLabeledStatement(Lexer()->GetToken().Type())) {
1146         return AllocBrokenStatement(Lexer()->GetToken().Loc());  // Error processing.
1147     }
1148 
1149     ir::Statement *body = ParseStatement(StatementParsingFlags::LABELLED);
1150 
1151     auto *labeledStatement = AllocNode<ir::LabelledStatement>(identNode, body);
1152     ES2PANDA_ASSERT(labeledStatement != nullptr);
1153     labeledStatement->SetRange({pos.GetToken().Start(), body->End()});
1154 
1155     return labeledStatement;
1156 }
1157 
ParseReturnStatement()1158 ir::Statement *ParserImpl::ParseReturnStatement()
1159 {
1160     bool inClassInitializer =
1161         (context_.Status() & ParserStatus::IN_CLASS_BODY) != 0 && (context_.Status() & ParserStatus::STATIC_BLOCK) != 0;
1162     if ((context_.Status() & ParserStatus::FUNCTION) == 0 &&
1163         (context_.Status() & ParserStatus::PARSE_TRAILING_BLOCK) == 0 && !(inClassInitializer && IsETSParser())) {
1164         LogError(diagnostic::RETURN_IN_FUN_BODY);
1165     }
1166 
1167     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1168     lexer::SourcePosition endLoc = lexer_->GetToken().End();
1169     lexer_->NextToken();
1170 
1171     bool hasArgument = (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
1172                         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
1173                         lexer_->GetToken().Type() != lexer::TokenType::EOS && !lexer_->GetToken().NewLine());
1174 
1175     ir::ReturnStatement *returnStatement = nullptr;
1176 
1177     if (hasArgument) {
1178         if (inClassInitializer) {
1179             LogError(diagnostic::RETURN_WITH_VALUE);
1180         }
1181         ir::Expression *expression = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1182         if (expression != nullptr) {  // Error processing.
1183             endLoc = expression->End();
1184         }
1185 
1186         // returnStatement will have void return type if expression == nullptr
1187         returnStatement = AllocNode<ir::ReturnStatement>(expression);
1188     } else {
1189         returnStatement = AllocNode<ir::ReturnStatement>();
1190     }
1191 
1192     ES2PANDA_ASSERT(returnStatement != nullptr);
1193     returnStatement->SetRange({startLoc, endLoc});
1194     ConsumeSemicolon(returnStatement);
1195 
1196     context_.Status() |= ParserStatus::FUNCTION_HAS_RETURN_STATEMENT;
1197     return returnStatement;
1198 }
1199 
ReportMultipleDefaultError()1200 void ParserImpl::ReportMultipleDefaultError()
1201 {
1202     LogError(diagnostic::MULTIPLE_DEFAULT);
1203 }
1204 
ParseSwitchCaseStatement(bool * seenDefault)1205 ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault)
1206 {
1207     auto const &token = lexer_->GetToken();
1208     lexer::SourcePosition caseStartLoc = token.Start();
1209     ir::Expression *testExpr = nullptr;
1210 
1211     switch (token.KeywordType()) {
1212         case lexer::TokenType::KEYW_CASE: {
1213             lexer_->NextToken();  // eat 'case'
1214             testExpr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1215             break;
1216         }
1217         case lexer::TokenType::KEYW_DEFAULT: {
1218             if (*seenDefault) {
1219                 ReportMultipleDefaultError();
1220             }
1221             *seenDefault = true;
1222             lexer_->NextToken();  // eat 'default'
1223             break;
1224         }
1225         default: {
1226             LogError(diagnostic::UNEXPECTED_TOKEN_PARAM_EXPECTED_CASE_OR_DEFAULT,
1227                      {lexer::TokenToString(lexer_->GetToken().Type())});
1228             testExpr = AllocBrokenExpression(caseStartLoc);
1229         }
1230     }
1231 
1232     lexer::SourcePosition caseEndLoc = lexer_->GetToken().End();
1233 
1234     ExpectToken(lexer::TokenType::PUNCTUATOR_COLON);
1235 
1236     ArenaVector<ir::Statement *> consequents(Allocator()->Adapter());
1237     while (lexer_->GetToken().Type() != lexer::TokenType::KEYW_CASE &&
1238            lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_DEFAULT &&
1239            lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
1240            lexer_->GetToken().Type() != lexer::TokenType::EOS) {
1241         util::ErrorRecursionGuard infiniteLoopBlocker(Lexer());
1242         ir::Statement *consequent = ParseStatement(StatementParsingFlags::ALLOW_LEXICAL);
1243         ES2PANDA_ASSERT(consequent != nullptr);
1244         caseEndLoc = consequent->End();
1245         consequents.push_back(consequent);
1246     }
1247 
1248     auto *caseNode = AllocNode<ir::SwitchCaseStatement>(testExpr, std::move(consequents));
1249     ES2PANDA_ASSERT(caseNode != nullptr);
1250     caseNode->SetRange({caseStartLoc, caseEndLoc});
1251     return caseNode;
1252 }
1253 
ParseSwitchStatement()1254 ir::Statement *ParserImpl::ParseSwitchStatement()
1255 {
1256     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1257     ExpectToken(lexer::TokenType::KEYW_SWITCH);
1258     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1259     ir::Expression *discriminant = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1260     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1261 
1262     SwitchContext switchContext(&context_);
1263     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
1264 
1265     bool seenDefault = false;
1266     ArenaVector<ir::SwitchCaseStatement *> cases(Allocator()->Adapter());
1267 
1268     while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
1269            lexer_->GetToken().Type() != lexer::TokenType::EOS) {
1270         util::ErrorRecursionGuard infiniteLoopBlocker(lexer_);
1271         auto caseStatement = ParseSwitchCaseStatement(&seenDefault);
1272         if (caseStatement != nullptr) {
1273             cases.push_back(caseStatement);
1274         }
1275     }
1276 
1277     auto endLoc = lexer_->GetToken().End();
1278     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
1279 
1280     auto *switchStatement = AllocNode<ir::SwitchStatement>(discriminant, std::move(cases));
1281     ES2PANDA_ASSERT(switchStatement != nullptr);
1282     switchStatement->SetRange({startLoc, endLoc});
1283     return switchStatement;
1284 }
1285 
ReportIllegalNewLineErrorAfterThrow()1286 void ParserImpl::ReportIllegalNewLineErrorAfterThrow()
1287 {
1288     LogError(diagnostic::ILLEGAL_NEW_LINE);
1289 }
1290 
ParseThrowStatement()1291 ir::Statement *ParserImpl::ParseThrowStatement()
1292 {
1293     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1294     lexer_->NextToken();
1295 
1296     if (lexer_->GetToken().NewLine()) {
1297         ReportIllegalNewLineErrorAfterThrow();
1298     }
1299 
1300     ir::Expression *expression = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1301     ES2PANDA_ASSERT(expression != nullptr);
1302 
1303     lexer::SourcePosition endLoc = expression->End();
1304 
1305     auto *throwStatement = AllocNode<ir::ThrowStatement>(expression);
1306     ES2PANDA_ASSERT(throwStatement != nullptr);
1307     throwStatement->SetRange({startLoc, endLoc});
1308     ConsumeSemicolon(throwStatement);
1309 
1310     context_.Status() |= ParserStatus::FUNCTION_HAS_THROW_STATEMENT;
1311     return throwStatement;
1312 }
1313 
ParseCatchParamTypeAnnotation(ir::AnnotatedExpression * param)1314 void ParserImpl::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param) {}
1315 
ParseCatchParam()1316 ir::Expression *ParserImpl::ParseCatchParam()
1317 {
1318     ir::AnnotatedExpression *param = nullptr;
1319 
1320     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1321         return param;
1322     }
1323 
1324     lexer_->NextToken();  // eat '('
1325 
1326     if (auto const tokenType = lexer_->GetToken().Type(); tokenType == lexer::TokenType::LITERAL_IDENT) {
1327         CheckRestrictedBinding();
1328         param = ExpectIdentifier();
1329     } else if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1330         param = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1331     } else if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1332         param = ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1333     } else {
1334         LogError(diagnostic::UNEXPECTED_TOKEN_PARAM, {lexer::TokenToString(lexer_->GetToken().Type())});
1335     }
1336 
1337     if (param != nullptr) {  // Error processing.
1338         ParseCatchParamTypeAnnotation(param);
1339     }
1340 
1341     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1342 
1343     return param;
1344 }
1345 
ParseCatchClause()1346 ir::CatchClause *ParserImpl::ParseCatchClause()
1347 {
1348     lexer::SourcePosition catchStartLoc = lexer_->GetToken().Start();
1349     lexer_->NextToken();  // eat 'catch' keyword
1350 
1351     ir::Expression *param = ParseCatchParam();
1352 
1353     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1354         LogError(diagnostic::EXPECTED_PARAM_GOT_PARAM, {"{", lexer::TokenToString(lexer_->GetToken().Type())});
1355     }
1356 
1357     ir::BlockStatement *catchBlock = ParseBlockStatement();
1358     ES2PANDA_ASSERT(catchBlock != nullptr);
1359     lexer::SourcePosition endLoc = catchBlock->End();
1360 
1361     auto *catchClause = AllocNode<ir::CatchClause>(param, catchBlock);
1362     ES2PANDA_ASSERT(catchClause != nullptr);
1363     catchClause->SetRange({catchStartLoc, endLoc});
1364 
1365     return catchClause;
1366 }
1367 
ParseTryStatement()1368 ir::Statement *ParserImpl::ParseTryStatement()
1369 {
1370     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1371     lexer::SourcePosition endLoc = lexer_->GetToken().End();
1372 
1373     lexer_->NextToken();  // eat 'try'
1374 
1375     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1376         LogError(diagnostic::EXPECTED_PARAM_GOT_PARAM, {"{", lexer::TokenToString(lexer_->GetToken().Type())});
1377     }
1378 
1379     ir::BlockStatement *body = ParseBlockStatement();
1380 
1381     if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_CATCH &&
1382         lexer_->GetToken().Type() != lexer::TokenType::KEYW_FINALLY) {
1383         /*  If we are here, there are two options:
1384             1. there is neither 'catch', nor 'finally';
1385             2. we made typo and got identifier instead of a first keyword after Try statement.
1386             So, this check does not work if we write Try, Catch statements and then make a mistake
1387             -> only setting current token as 'catch' is a possible option to fix most cases
1388             Test exixts for ts extension only: catch_or_finally_1.ts
1389         */
1390         LogError(diagnostic::MISSING_CATCH_OR_FINALLY);
1391     }
1392 
1393     ir::CatchClause *catchClause = nullptr;
1394     ir::BlockStatement *finallyClause = nullptr;
1395     ArenaVector<ir::CatchClause *> catchClauses(Allocator()->Adapter());
1396 
1397     while (lexer_->GetToken().Type() == lexer::TokenType::KEYW_CATCH) {
1398         catchClause = ParseCatchClause();
1399         ES2PANDA_ASSERT(catchClause != nullptr);
1400         endLoc = catchClause->End();
1401         catchClauses.push_back(catchClause);
1402     }
1403 
1404     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_FINALLY) {
1405         lexer_->NextToken();  // eat 'finally' keyword
1406 
1407         finallyClause = ParseBlockStatement();
1408         ES2PANDA_ASSERT(finallyClause != nullptr);
1409         endLoc = finallyClause->End();
1410     }
1411 
1412     ArenaVector<std::pair<compiler::LabelPair, const ir::Statement *>> finalizerInsertions(Allocator()->Adapter());
1413 
1414     auto *tryStatement = AllocNode<ir::TryStatement>(body, std::move(catchClauses), finallyClause, finalizerInsertions);
1415     ES2PANDA_ASSERT(tryStatement != nullptr);
1416     tryStatement->SetRange({startLoc, endLoc});
1417     return tryStatement;
1418 }
1419 
ValidateDeclaratorId()1420 void ParserImpl::ValidateDeclaratorId()
1421 {
1422     if (InAmbientContext()) {
1423         return;
1424     }
1425 
1426     CheckRestrictedBinding();
1427 }
1428 
ParseVariableDeclaratorInitializer(ir::Expression * init,VariableParsingFlags flags,const lexer::SourcePosition & startLoc)1429 ir::VariableDeclarator *ParserImpl::ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags,
1430                                                                        const lexer::SourcePosition &startLoc)
1431 {
1432     if ((flags & VariableParsingFlags::DISALLOW_INIT) != 0) {
1433         LogError(diagnostic::FOR_AWAIT_OF_VAR_NOT_INIT);
1434     }
1435 
1436     lexer_->NextToken();
1437 
1438     if (InAmbientContext() && (flags & VariableParsingFlags::CONST) == 0) {
1439         LogError(diagnostic::INITIALIZERS_IN_AMBIENT_CONTEXTS);
1440     }
1441 
1442     auto exprFlags = ((flags & VariableParsingFlags::STOP_AT_IN) != 0 ? ExpressionParseFlags::STOP_AT_IN
1443                                                                       : ExpressionParseFlags::NO_OPTS);
1444 
1445     ir::Expression *initializer = ParseExpression(exprFlags);
1446     if (initializer == nullptr) {  // Error processing.
1447         return nullptr;
1448     }
1449 
1450     lexer::SourcePosition endLoc = initializer->End();
1451 
1452     auto *declarator = AllocNode<ir::VariableDeclarator>(GetFlag(flags), init, initializer);
1453     declarator->SetRange({startLoc, endLoc});
1454 
1455     return declarator;
1456 }
1457 
ParseVariableDeclaratorKey(VariableParsingFlags flags)1458 ir::AnnotatedExpression *ParserImpl::ParseVariableDeclaratorKey([[maybe_unused]] VariableParsingFlags flags)
1459 {
1460     switch (lexer_->GetToken().Type()) {
1461         case lexer::TokenType::LITERAL_IDENT: {
1462             ValidateDeclaratorId();
1463             return ExpectIdentifier(true);
1464         }
1465         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1466             return ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1467         }
1468         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1469             return ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1470         }
1471         default: {
1472             break;
1473         }
1474     }
1475 
1476     LogError(diagnostic::UNEXPECTED_TOKEN);
1477     return nullptr;
1478 }
1479 
GetFlag(VariableParsingFlags flags)1480 ir::VariableDeclaratorFlag ParserImpl::GetFlag(VariableParsingFlags flags)
1481 {
1482     constexpr auto VARIABLE_FLAGS =
1483         (VariableParsingFlags::VAR | VariableParsingFlags::LET | VariableParsingFlags::CONST);
1484     switch (static_cast<VariableParsingFlags>(flags & VARIABLE_FLAGS)) {
1485         case VariableParsingFlags::CONST:
1486             return ir::VariableDeclaratorFlag::CONST;
1487         case VariableParsingFlags::VAR:
1488             return ir::VariableDeclaratorFlag::VAR;
1489         case VariableParsingFlags::LET:
1490             return ir::VariableDeclaratorFlag::LET;
1491         default:
1492             ES2PANDA_UNREACHABLE();
1493     }
1494 }
1495 
ParseVariableDeclarator(ir::Expression * init,lexer::SourcePosition startLoc,VariableParsingFlags flags)1496 ir::VariableDeclarator *ParserImpl::ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc,
1497                                                             VariableParsingFlags flags)
1498 {
1499     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1500         return ParseVariableDeclaratorInitializer(init, flags, startLoc);
1501     }
1502 
1503     if ((flags & VariableParsingFlags::CONST) != 0U && (flags & VariableParsingFlags::ACCEPT_CONST_NO_INIT) == 0U) {
1504         LogError(diagnostic::MISSING_INIT_OR_CONST_DEC);
1505     }
1506 
1507     if ((flags & VariableParsingFlags::IN_FOR) == 0U && (init->IsArrayPattern() || init->IsObjectPattern())) {
1508         LogError(diagnostic::MISSING_INIT_IN_DEST_DEC);
1509     }
1510 
1511     lexer::SourcePosition endLoc = init->End();
1512     auto declarator = AllocNode<ir::VariableDeclarator>(GetFlag(flags), init);
1513     declarator->SetRange({startLoc, endLoc});
1514 
1515     return declarator;
1516 }
1517 
ParseVariableDeclarator(VariableParsingFlags flags)1518 ir::VariableDeclarator *ParserImpl::ParseVariableDeclarator(VariableParsingFlags flags)
1519 {
1520     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1521     ir::Expression *init = ParseVariableDeclaratorKey(flags);
1522     if (init == nullptr) {  // Error processing.
1523         return nullptr;
1524     }
1525 
1526     return ParseVariableDeclarator(init, startLoc, flags);
1527 }
1528 
ParsePotentialConstEnum(VariableParsingFlags flags)1529 ir::Statement *ParserImpl::ParsePotentialConstEnum([[maybe_unused]] VariableParsingFlags flags)
1530 {
1531     LogError(diagnostic::VAR_DEC_EXPECTED);
1532     return ParseEnumDeclaration(true);
1533 }
1534 
ReportIfVarDeclaration(VariableParsingFlags flags)1535 void ParserImpl::ReportIfVarDeclaration([[maybe_unused]] VariableParsingFlags flags) {}
1536 
ParseVariableDeclaration(VariableParsingFlags flags)1537 ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags)
1538 {
1539     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1540 
1541     if ((flags & VariableParsingFlags::NO_SKIP_VAR_KIND) == 0) {
1542         lexer_->NextToken();
1543     }
1544 
1545     ReportIfVarDeclaration(flags);
1546 
1547     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1548         return ParsePotentialConstEnum(flags);
1549     }
1550 
1551     ArenaVector<ir::VariableDeclarator *> declarators(Allocator()->Adapter());
1552 
1553     while (true) {
1554         ir::VariableDeclarator *declarator = ParseVariableDeclarator(flags);
1555         if (declarator != nullptr) {  // Error processing.
1556             declarators.push_back(declarator);
1557         }
1558 
1559         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
1560             break;
1561         }
1562         lexer_->NextToken();
1563     }
1564 
1565     if (declarators.empty()) {  // Error processing.
1566         // Error is logged inside ParseVariableDeclaratorKey or ParseVariableDeclaratorInitializer
1567         return AllocBrokenStatement(Lexer()->GetToken().Loc());
1568     }
1569 
1570     auto varKind = ir::VariableDeclaration::VariableDeclarationKind::VAR;
1571 
1572     if ((flags & VariableParsingFlags::LET) != 0) {
1573         varKind = ir::VariableDeclaration::VariableDeclarationKind::LET;
1574     } else if ((flags & VariableParsingFlags::CONST) != 0) {
1575         varKind = ir::VariableDeclaration::VariableDeclarationKind::CONST;
1576     }
1577 
1578     lexer::SourcePosition endLoc = declarators.back()->End();
1579     auto *declaration = AllocNode<ir::VariableDeclaration>(varKind, Allocator(), std::move(declarators));
1580     ES2PANDA_ASSERT(declaration != nullptr);
1581     declaration->SetRange({startLoc, endLoc});
1582 
1583     return declaration;
1584 }
1585 
ParseWhileStatement()1586 ir::Statement *ParserImpl::ParseWhileStatement()
1587 {
1588     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1589     lexer_->NextToken();
1590     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1591 
1592     ir::Expression *condition = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1593 
1594     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1595 
1596     IterationContext iterCtx(&context_);
1597     ir::Statement *body = ParseStatement();
1598     if (IsBrokenStatement(body)) {
1599         LogError(diagnostic::MISSING_LOOP_BODY, {"while"});
1600     }
1601 
1602     if (condition->IsBrokenExpression()) {
1603         LogError(diagnostic::MISSING_LOOP_CONDITION, {"while"});
1604     }
1605 
1606     lexer::SourcePosition endLoc = body->End();
1607     auto *whileStatement = AllocNode<ir::WhileStatement>(condition, body);
1608     ES2PANDA_ASSERT(whileStatement != nullptr);
1609     whileStatement->SetRange({startLoc, endLoc});
1610 
1611     return whileStatement;
1612 }
1613 
1614 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition & startLoc,bool isExportEquals)1615 ir::ExportDefaultDeclaration *ParserImpl::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1616                                                                         bool isExportEquals)
1617 {
1618     lexer_->NextToken();  // eat `default` keyword or `=`
1619 
1620     ir::AstNode *declNode = nullptr;
1621     bool eatSemicolon = false;
1622 
1623     switch (lexer_->GetToken().Type()) {
1624         case lexer::TokenType::KEYW_FUNCTION:
1625             declNode = ParseFunctionDeclaration(true);
1626             break;
1627         case lexer::TokenType::KEYW_CLASS:
1628             declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::NONE);
1629             break;
1630         case lexer::TokenType::LITERAL_IDENT:
1631             switch (lexer_->GetToken().KeywordType()) {
1632                 case lexer::TokenType::KEYW_STRUCT:
1633                     declNode = ParseStructDeclaration(ir::ClassDefinitionModifiers::NONE);
1634                     break;
1635                 case lexer::TokenType::KEYW_ASYNC:
1636                     if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1637                         lexer_->NextToken();  // eat `async`
1638                         declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1639                         break;
1640                     }
1641 
1642                     [[fallthrough]];
1643                 default:
1644                     declNode = ParseExpression();
1645                     eatSemicolon = true;
1646                     break;
1647             }
1648 
1649             break;
1650         default:
1651             declNode = ParseExpression();
1652             eatSemicolon = true;
1653             break;
1654     }
1655 
1656     ES2PANDA_ASSERT(declNode != nullptr);
1657     lexer::SourcePosition endLoc = declNode->End();
1658     auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1659     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1660     exportDeclaration->SetRange({startLoc, endLoc});
1661 
1662     if (eatSemicolon) {
1663         ConsumeSemicolon(exportDeclaration);
1664     }
1665 
1666     return exportDeclaration;
1667 }
1668 
ParseNamedExport(lexer::Token * exportedToken)1669 ir::Identifier *ParserImpl::ParseNamedExport(lexer::Token *exportedToken)
1670 {
1671     if (exportedToken->Type() != lexer::TokenType::LITERAL_IDENT) {
1672         // test exists for js and ts extensions
1673         LogError(diagnostic::UNEXPECTED_TOKEN_ID);
1674         exportedToken->SetTokenType(lexer::TokenType::LITERAL_IDENT);
1675         exportedToken->SetTokenStr(ERROR_LITERAL);
1676     }
1677 
1678     CheckRestrictedBinding(exportedToken->KeywordType());
1679 
1680     const util::StringView &exportedString = exportedToken->Ident();
1681 
1682     auto *exported = AllocNode<ir::Identifier>(exportedString, Allocator());
1683     ES2PANDA_ASSERT(exported != nullptr);
1684     exported->SetRange(exportedToken->Loc());
1685 
1686     return exported;
1687 }
1688 
ParseExportAllDeclaration(const lexer::SourcePosition & startLoc)1689 ir::ExportAllDeclaration *ParserImpl::ParseExportAllDeclaration(const lexer::SourcePosition &startLoc)
1690 {
1691     lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat `*` character
1692 
1693     ir::Identifier *exported = nullptr;
1694 
1695     if (CheckModuleAsModifier()) {
1696         lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1697         exported = ParseNamedExport(&lexer_->GetToken());
1698         lexer_->NextToken();  // eat exported name
1699     }
1700     ir::StringLiteral *source = ParseFromClause();
1701     ES2PANDA_ASSERT(source != nullptr);
1702     lexer::SourcePosition endLoc = source->End();
1703 
1704     auto *exportDeclaration = AllocNode<ir::ExportAllDeclaration>(source, exported);
1705     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1706     exportDeclaration->SetRange({startLoc, endLoc});
1707 
1708     ConsumeSemicolon(exportDeclaration);
1709 
1710     return exportDeclaration;
1711 }
1712 
ParseExportNamedSpecifiers(const lexer::SourcePosition & startLoc)1713 ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer::SourcePosition &startLoc)
1714 {
1715     lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat `{` character
1716 
1717     ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1718     lexer::SourcePosition endPos;
1719 
1720     ParseList(
1721         lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT,
1722         [this, &specifiers]() {
1723             if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1724                 // test exists for ts extension only
1725                 LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
1726             }
1727 
1728             lexer::Token localToken = lexer_->GetToken();
1729             auto *local = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1730             local->SetRange(lexer_->GetToken().Loc());
1731 
1732             lexer_->NextToken();  // eat local name
1733 
1734             ir::Identifier *exported = nullptr;
1735 
1736             if (CheckModuleAsModifier()) {
1737                 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat `as` literal
1738                 exported = ParseNamedExport(&lexer_->GetToken());
1739                 lexer_->NextToken();  // eat exported name
1740             } else {
1741                 exported = ParseNamedExport(&localToken);
1742             }
1743 
1744             if (exported != nullptr) {  // Error processing.
1745                 auto *specifier = AllocNode<ir::ExportSpecifier>(local, exported);
1746                 specifier->SetRange({local->Start(), exported->End()});
1747                 specifiers.push_back(specifier);
1748             }
1749             return true;
1750         },
1751         &endPos, true);
1752 
1753     ir::StringLiteral *source = nullptr;
1754 
1755     if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM) {
1756         source = ParseFromClause();
1757     }
1758 
1759     auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), source, std::move(specifiers));
1760     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1761     exportDeclaration->SetRange({startLoc, endPos});
1762     ConsumeSemicolon(exportDeclaration);
1763 
1764     return exportDeclaration;
1765 }
1766 
ParseNamedExportDeclaration(const lexer::SourcePosition & startLoc)1767 ir::Statement *ParserImpl::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1768 {
1769     ir::Statement *decl = nullptr;
1770 
1771     switch (lexer_->GetToken().Type()) {
1772         case lexer::TokenType::KEYW_VAR:
1773             decl = ParseVariableDeclaration(VariableParsingFlags::VAR);
1774             break;
1775         case lexer::TokenType::KEYW_CONST:
1776             decl = ParseVariableDeclaration(VariableParsingFlags::CONST);
1777             break;
1778         case lexer::TokenType::KEYW_LET:
1779             decl = ParseVariableDeclaration(VariableParsingFlags::LET);
1780             break;
1781         case lexer::TokenType::KEYW_FUNCTION:
1782             decl = ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1783             break;
1784         case lexer::TokenType::KEYW_CLASS:
1785             decl = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1786             break;
1787         case lexer::TokenType::LITERAL_IDENT:
1788             if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_STRUCT) {
1789                 decl = ParseStructDeclaration(ir::ClassDefinitionModifiers::NONE);
1790                 break;
1791             }
1792             [[fallthrough]];
1793         default:
1794             if (!lexer_->GetToken().IsAsyncModifier()) {
1795                 LogExpectedToken(lexer::TokenType::KEYW_ASYNC);
1796             }
1797 
1798             lexer_->NextToken();  // eat `async` keyword
1799             if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_FUNCTION) {
1800                 LogExpectedToken(lexer::TokenType::KEYW_FUNCTION);
1801                 return AllocBrokenStatement(Lexer()->GetToken().Loc());
1802             }
1803             decl = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1804             break;
1805     }
1806 
1807     ES2PANDA_ASSERT(decl != nullptr);
1808     if (decl->IsVariableDeclaration()) {
1809         ConsumeSemicolon(decl);
1810     }
1811 
1812     lexer::SourcePosition endLoc = decl->End();
1813     ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1814     auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1815     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1816     exportDeclaration->SetRange({startLoc, endLoc});
1817 
1818     return exportDeclaration;
1819 }
1820 
ParseExportDeclaration(StatementParsingFlags flags)1821 ir::Statement *ParserImpl::ParseExportDeclaration(StatementParsingFlags flags)
1822 {
1823     if ((flags & StatementParsingFlags::GLOBAL) == 0) {
1824         LogError(diagnostic::IMPORT_EXPORT_ONLY_AT_TOP_LEVEL);
1825     }
1826 
1827     if (!context_.IsModule()) {
1828         LogError(diagnostic::IMPORT_META_ONLY_MODULE);
1829     }
1830 
1831     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1832     lexer_->NextToken();  // eat `export` keyword
1833 
1834     switch (lexer_->GetToken().Type()) {
1835         case lexer::TokenType::PUNCTUATOR_MULTIPLY: {
1836             return ParseExportAllDeclaration(startLoc);
1837         }
1838         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1839             return ParseExportNamedSpecifiers(startLoc);
1840         }
1841         default: {
1842             if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_DEFAULT) {
1843                 return ParseExportDefaultDeclaration(startLoc);
1844             }
1845             return ParseNamedExportDeclaration(startLoc);
1846         }
1847     }
1848 }
1849 
ParseNameSpaceImport(ArenaVector<ir::AstNode * > * specifiers)1850 void ParserImpl::ParseNameSpaceImport(ArenaVector<ir::AstNode *> *specifiers)
1851 {
1852     lexer::SourcePosition namespaceStart = lexer_->GetToken().Start();
1853     lexer_->NextToken();  // eat `*` character
1854 
1855     if (!CheckModuleAsModifier()) {
1856         LogExpectedToken(lexer::TokenType::KEYW_AS);
1857     }
1858 
1859     lexer_->NextToken();  // eat `as` literal
1860 
1861     ir::Identifier *local = ParseNamedImport(&lexer_->GetToken());
1862 
1863     auto *specifier = AllocNode<ir::ImportNamespaceSpecifier>(local);
1864     ES2PANDA_ASSERT(specifier != nullptr);
1865     specifier->SetRange({namespaceStart, lexer_->GetToken().End()});
1866     specifiers->push_back(specifier);
1867 
1868     lexer_->NextToken();  // eat local name
1869 }
1870 
ParseNamedImport(lexer::Token * importedToken)1871 ir::Identifier *ParserImpl::ParseNamedImport(lexer::Token *importedToken)
1872 {
1873     if (importedToken->Type() != lexer::TokenType::LITERAL_IDENT) {
1874         LogError(diagnostic::UNEXPECTED_TOKEN_ID);
1875         importedToken->SetTokenType(lexer::TokenType::LITERAL_IDENT);
1876         importedToken->SetTokenStr(ERROR_LITERAL);
1877     }
1878 
1879     CheckRestrictedBinding(importedToken->KeywordType());
1880 
1881     auto *local = AllocNode<ir::Identifier>(importedToken->Ident(), Allocator());
1882     ES2PANDA_ASSERT(local != nullptr);
1883     local->SetRange(importedToken->Loc());
1884 
1885     return local;
1886 }
1887 
ParseNamedImportSpecifiers(ArenaVector<ir::AstNode * > * specifiers)1888 void ParserImpl::ParseNamedImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1889 {
1890     lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat `{` character
1891 
1892     ParseList(
1893         lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT,
1894         [this, specifiers]() {
1895             if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1896                 // test exists for ts extension only
1897                 LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
1898             }
1899 
1900             lexer::Token importedToken = lexer_->GetToken();
1901             auto *imported = AllocNode<ir::Identifier>(importedToken.Ident(), Allocator());
1902             ir::Identifier *local = nullptr;
1903             imported->SetRange(lexer_->GetToken().Loc());
1904 
1905             lexer_->NextToken();  // eat import name
1906 
1907             if (CheckModuleAsModifier()) {
1908                 lexer_->NextToken();  // eat `as` literal
1909                 local = ParseNamedImport(&lexer_->GetToken());
1910                 lexer_->NextToken();  // eat local name
1911             } else {
1912                 local = ParseNamedImport(&importedToken);
1913             }
1914 
1915             auto *specifier = AllocNode<ir::ImportSpecifier>(imported, local);
1916             specifier->SetRange({imported->Start(), local->End()});
1917             specifiers->push_back(specifier);
1918             return true;
1919         },
1920         nullptr, true);
1921 }
1922 
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode * > * specifiers)1923 ir::AstNode *ParserImpl::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1924 {
1925     ir::Identifier *local = ParseNamedImport(&lexer_->GetToken());
1926     lexer_->NextToken();  // eat local name
1927 
1928     auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1929     ES2PANDA_ASSERT(specifier != nullptr);
1930     specifier->SetRange(specifier->Local()->Range());
1931     specifiers->push_back(specifier);
1932 
1933     lexer_->NextToken();  // eat specifier name
1934 
1935     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1936         lexer_->NextToken();  // eat comma
1937     }
1938 
1939     return nullptr;
1940 }
1941 
ParseFromClause(bool requireFrom)1942 ir::StringLiteral *ParserImpl::ParseFromClause(bool requireFrom)
1943 {
1944     if (lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) {
1945         // unexpected_token_5.ts
1946         if (requireFrom) {
1947             LogExpectedToken(lexer::TokenType::KEYW_FROM);
1948             lexer_->NextToken();  // eat `from` literal
1949         }
1950     } else {
1951         lexer_->NextToken();  // eat `from` literal
1952     }
1953 
1954     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1955         // test exists for ts extension only
1956         LogExpectedToken(lexer::TokenType::LITERAL_STRING);
1957         lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_STRING);
1958         lexer_->GetToken().SetTokenStr(ERROR_LITERAL);
1959     }
1960 
1961     auto *source = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
1962     ES2PANDA_ASSERT(source != nullptr);
1963     source->SetRange(lexer_->GetToken().Loc());
1964 
1965     lexer_->NextToken();
1966 
1967     return source;
1968 }
1969 
ParseImportSpecifiers(ArenaVector<ir::AstNode * > * specifiers)1970 ir::AstNode *ParserImpl::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1971 {
1972     ES2PANDA_ASSERT(specifiers->empty());
1973 
1974     if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1975         ir::AstNode *astNode = ParseImportDefaultSpecifier(specifiers);
1976 
1977         if (astNode != nullptr) {
1978             return astNode;
1979         }
1980     }
1981 
1982     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1983         ParseNameSpaceImport(specifiers);
1984     } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1985         ParseNamedImportSpecifiers(specifiers);
1986     }
1987     return nullptr;
1988 }
1989 
ParseImportDeclaration(StatementParsingFlags flags)1990 ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags)
1991 {
1992     if ((flags & StatementParsingFlags::GLOBAL) == 0) {
1993         LogError(diagnostic::IMPORT_EXPORT_ONLY_AT_TOP_LEVEL);
1994     }
1995 
1996     if (!context_.IsModule()) {
1997         LogError(diagnostic::IMPORT_META_ONLY_MODULE);
1998     }
1999 
2000     char32_t nextChar = lexer_->Lookahead();
2001     if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
2002         return ParseExpressionStatement();
2003     }
2004 
2005     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2006     lexer_->NextToken();  // eat import
2007 
2008     ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
2009 
2010     ir::StringLiteral *source = nullptr;
2011 
2012     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
2013         ParseImportSpecifiers(&specifiers);
2014         source = ParseFromClause(true);
2015     } else {
2016         source = ParseFromClause(false);
2017     }
2018 
2019     ES2PANDA_ASSERT(source != nullptr);
2020     lexer::SourcePosition endLoc = source->End();
2021     auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
2022     ES2PANDA_ASSERT(importDeclaration != nullptr);
2023     importDeclaration->SetRange({startLoc, endLoc});
2024 
2025     ConsumeSemicolon(importDeclaration);
2026 
2027     return importDeclaration;
2028 }
2029 
AllocBrokenStatement(const lexer::SourcePosition & pos)2030 ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourcePosition &pos)
2031 {
2032     return AllocBrokenStatement({pos, pos});
2033 }
2034 
AllocBrokenStatement(const lexer::SourceRange & range)2035 ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourceRange &range)
2036 {
2037     auto *broken = AllocNode<ir::EmptyStatement>(true);
2038     ES2PANDA_ASSERT(broken != nullptr);
2039     broken->SetRange(range);
2040     return broken;
2041 }
2042 
IsBrokenStatement(ir::Statement * st)2043 bool ParserImpl::IsBrokenStatement(ir::Statement *st)
2044 {
2045     if (st->IsEmptyStatement()) {
2046         return st->AsEmptyStatement()->IsBrokenStatement();
2047     }
2048     return false;
2049 }
2050 
AllocEmptyStatement()2051 ir::Statement *ParserImpl::AllocEmptyStatement()
2052 {
2053     auto *empty = AllocNode<ir::EmptyStatement>();
2054     ES2PANDA_ASSERT(empty != nullptr);
2055     empty->SetRange(lexer_->GetToken().Loc());
2056     return empty;
2057 }
2058 
2059 }  // namespace ark::es2panda::parser
2060