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 "ASparser.h"
17
18 #include "parser/parserStatusContext.h"
19 #include "parserFlags.h"
20 #include "util/helpers.h"
21 #include "varbinder/privateBinding.h"
22 #include "varbinder/scope.h"
23 #include "varbinder/tsBinding.h"
24 #include "lexer/ASLexer.h"
25 #include "ir/base/decorator.h"
26 #include "ir/base/property.h"
27 #include "ir/base/spreadElement.h"
28 #include "ir/base/classElement.h"
29 #include "ir/base/classDefinition.h"
30 #include "ir/base/methodDefinition.h"
31 #include "ir/base/scriptFunction.h"
32 #include "ir/module/importDefaultSpecifier.h"
33 #include "ir/module/exportDefaultDeclaration.h"
34 #include "ir/module/exportNamedDeclaration.h"
35 #include "ir/module/importDeclaration.h"
36 #include "ir/expressions/arrowFunctionExpression.h"
37 #include "ir/expressions/templateLiteral.h"
38 #include "ir/expressions/callExpression.h"
39 #include "ir/expressions/taggedTemplateExpression.h"
40 #include "ir/expressions/assignmentExpression.h"
41 #include "ir/expressions/identifier.h"
42 #include "ir/expressions/memberExpression.h"
43 #include "ir/expressions/functionExpression.h"
44 #include "ir/expressions/sequenceExpression.h"
45 #include "ir/expressions/literals/stringLiteral.h"
46 #include "ir/expressions/literals/numberLiteral.h"
47 #include "ir/expressions/literals/bigIntLiteral.h"
48 #include "ir/statements/emptyStatement.h"
49 #include "ir/statements/blockStatement.h"
50 #include "ir/statements/ifStatement.h"
51 #include "ir/statements/doWhileStatement.h"
52 #include "ir/statements/whileStatement.h"
53 #include "ir/statements/tryStatement.h"
54 #include "ir/statements/breakStatement.h"
55 #include "ir/statements/continueStatement.h"
56 #include "ir/statements/throwStatement.h"
57 #include "ir/statements/switchStatement.h"
58 #include "ir/statements/returnStatement.h"
59 #include "ir/statements/debuggerStatement.h"
60 #include "ir/statements/classDeclaration.h"
61 #include "ir/statements/labelledStatement.h"
62 #include "ir/statements/variableDeclarator.h"
63 #include "ir/statements/functionDeclaration.h"
64 #include "ir/as/namedType.h"
65 #include "ir/as/prefixAssertionExpression.h"
66 #include "ir/ts/tsFunctionType.h"
67 #include "ir/ts/tsNonNullExpression.h"
68 #include "ir/ts/tsAsExpression.h"
69 #include "ir/ts/tsEnumDeclaration.h"
70 #include "ir/ts/tsInterfaceDeclaration.h"
71 #include "ir/ts/tsTypeAliasDeclaration.h"
72 #include "ir/ts/tsModuleDeclaration.h"
73 #include "ir/ts/tsInterfaceHeritage.h"
74 #include "ir/base/tsIndexSignature.h"
75 #include "ir/base/tsMethodSignature.h"
76 #include "ir/base/tsPropertySignature.h"
77 #include "ir/ts/tsClassImplements.h"
78 #include "ir/ts/tsTypeParameterInstantiation.h"
79
80 namespace ark::es2panda::parser {
InitLexer(const SourceFile & sourceFile)81 std::unique_ptr<lexer::Lexer> ASParser::InitLexer(const SourceFile &sourceFile)
82 {
83 GetProgram()->SetSource(sourceFile);
84 auto lexer = std::make_unique<lexer::ASLexer>(&GetContext(), DiagnosticEngine());
85 SetLexer(lexer.get());
86 return lexer;
87 }
88
ParseDecorator()89 ir::Decorator *ASParser::ParseDecorator()
90 {
91 ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
92
93 lexer::SourcePosition start = Lexer()->GetToken().Start();
94 Lexer()->NextToken(); // eat '@'
95
96 auto *expr = ParseLeftHandSideExpression();
97 auto *decorator = AllocNode<ir::Decorator>(expr);
98 ES2PANDA_ASSERT(decorator != nullptr);
99 decorator->SetRange({start, expr->End()});
100 return decorator;
101 }
102
AddDecorators(ir::AstNode * node,ArenaVector<ir::Decorator * > & decorators)103 void ASParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
104 {
105 if (decorators.empty()) {
106 return;
107 }
108
109 if (!node->CanHaveDecorator(false)) {
110 ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
111 }
112
113 node->AddDecorators(std::move(decorators));
114 }
115
ParseTypeAliasDeclaration()116 ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration()
117 {
118 ES2PANDA_ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
119 lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
120 Lexer()->NextToken(); // eat type keyword
121 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
122 ThrowSyntaxError("Identifier expected");
123 }
124
125 const util::StringView &ident = Lexer()->GetToken().Ident();
126
127 auto *id = AllocNode<ir::Identifier>(ident, Allocator());
128 ES2PANDA_ASSERT(id != nullptr);
129 id->SetRange(Lexer()->GetToken().Loc());
130 Lexer()->NextToken();
131
132 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
133 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
134 auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
135 typeParamDecl = ParseTypeParameterDeclaration(&options);
136 }
137
138 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
139 ThrowSyntaxError("'=' expected");
140 }
141
142 Lexer()->NextToken(); // eat '='
143
144 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
145 Lexer()->NextToken(); // eat '|'
146 }
147
148 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
149 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
150
151 auto *typeAliasDecl = AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation);
152 typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()});
153
154 return typeAliasDecl;
155 }
156
157 // NOLINTNEXTLINE(google-default-arguments)
ParseStatement(StatementParsingFlags flags)158 ir::Statement *ASParser::ParseStatement(StatementParsingFlags flags)
159 {
160 return ParseDeclareAndDecorators(flags);
161 }
162
ParseOptionalFunctionParameter(ir::AnnotatedExpression * returnNode,bool inRest)163 void ASParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool inRest)
164 {
165 bool isOptional = false;
166
167 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
168 if (inRest) {
169 ThrowSyntaxError("A rest parameter cannot be optional");
170 }
171
172 ES2PANDA_ASSERT(returnNode->IsIdentifier());
173 returnNode->AsIdentifier()->SetOptional(true);
174
175 isOptional = true;
176 Lexer()->NextToken(); // eat '?'
177 }
178
179 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
180 Lexer()->NextToken(); // eat ':'
181 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
182 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
183 } else if (!isOptional) {
184 ThrowSyntaxError("':' expected");
185 }
186
187 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
188 return;
189 }
190
191 if (inRest) {
192 ThrowSyntaxError("A rest parameter cannot have an initializer");
193 }
194
195 if (returnNode->IsIdentifier() && isOptional) {
196 ThrowSyntaxError("Parameter cannot have question mark and initializer");
197 }
198 }
199
ValidateArrowExprIdentifier(ir::Expression * expr,bool * seenOptional)200 ParserStatus ASParser::ValidateArrowExprIdentifier(ir::Expression *expr, bool *seenOptional)
201 {
202 const util::StringView &identifier = expr->AsIdentifier()->Name();
203 bool isOptional = expr->AsIdentifier()->IsOptional();
204 if ((*seenOptional) != isOptional) {
205 ThrowSyntaxError("A required parameter cannot follow an optional parameter.", expr->Start());
206 }
207
208 (*seenOptional) |= isOptional;
209
210 if (expr->AsIdentifier()->TypeAnnotation() == nullptr) {
211 ThrowSyntaxError("':' expected", expr->End());
212 }
213
214 if (identifier.Is("arguments")) {
215 ThrowSyntaxError("Binding 'arguments' in strict mode is invalid");
216 } else if (identifier.Is("eval")) {
217 ThrowSyntaxError("Binding 'eval' in strict mode is invalid");
218 }
219
220 ValidateArrowParameterBindings(expr);
221 return ParserStatus::NO_OPTS;
222 }
223
ValidateArrowAssignmentExpr(ir::Expression * expr)224 ParserStatus ASParser::ValidateArrowAssignmentExpr(ir::Expression *expr)
225 {
226 auto *assignmentExpr = expr->AsAssignmentExpression();
227 if (assignmentExpr->Right()->IsYieldExpression()) {
228 ThrowSyntaxError("yield is not allowed in arrow function parameters");
229 }
230
231 if (assignmentExpr->Right()->IsAwaitExpression()) {
232 ThrowSyntaxError("await is not allowed in arrow function parameters");
233 }
234
235 if (!assignmentExpr->ConvertibleToAssignmentPattern()) {
236 ThrowSyntaxError("Invalid destructuring assignment target");
237 }
238
239 if (assignmentExpr->Left()->IsIdentifier() && assignmentExpr->Left()->AsIdentifier()->IsOptional()) {
240 ThrowSyntaxError("Parameter cannot have question mark and initializer.", expr->Start());
241 }
242
243 ValidateArrowParameterBindings(expr);
244 return ParserStatus::HAS_COMPLEX_PARAM;
245 }
246
ValidateArrowParameter(ir::Expression * expr,bool * seenOptional)247 ParserStatus ASParser::ValidateArrowParameter(ir::Expression *expr, bool *seenOptional)
248 {
249 switch (expr->Type()) {
250 case ir::AstNodeType::SPREAD_ELEMENT: {
251 if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
252 ThrowSyntaxError("Invalid rest element.");
253 }
254
255 [[fallthrough]];
256 }
257 case ir::AstNodeType::REST_ELEMENT: {
258 if (expr->AsRestElement()->IsOptional()) {
259 ThrowSyntaxError("A rest parameter cannot be optional.", expr->Start());
260 }
261
262 ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
263 return ParserStatus::HAS_COMPLEX_PARAM;
264 }
265 case ir::AstNodeType::IDENTIFIER: {
266 return ValidateArrowExprIdentifier(expr, seenOptional);
267 }
268 case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
269 return ValidateArrowAssignmentExpr(expr);
270 }
271 default: {
272 break;
273 }
274 }
275 ThrowSyntaxError("Insufficient formal parameter in arrow function.");
276 return ParserStatus::NO_OPTS;
277 }
278
ConvertToArrowParameter(ir::Expression * expr,bool isAsync)279 ArrowFunctionDescriptor ASParser::ConvertToArrowParameter(ir::Expression *expr, bool isAsync)
280 {
281 auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
282 ArenaVector<ir::Expression *> params(Allocator()->Adapter());
283
284 if (expr == nullptr) {
285 return ArrowFunctionDescriptor {std::move(params), Lexer()->GetToken().Start(), arrowStatus};
286 }
287
288 bool seenOptional = false;
289
290 switch (expr->Type()) {
291 case ir::AstNodeType::REST_ELEMENT:
292 case ir::AstNodeType::IDENTIFIER:
293 case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
294 arrowStatus |= ValidateArrowParameter(expr, &seenOptional);
295
296 params.push_back(expr);
297 break;
298 }
299 case ir::AstNodeType::SEQUENCE_EXPRESSION: {
300 auto &sequence = expr->AsSequenceExpression()->Sequence();
301
302 for (auto *it : sequence) {
303 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
304 }
305
306 params.swap(sequence);
307 break;
308 }
309 case ir::AstNodeType::CALL_EXPRESSION: {
310 if (isAsync) {
311 auto &arguments = expr->AsCallExpression()->Arguments();
312
313 for (auto *it : arguments) {
314 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
315 }
316
317 params.swap(arguments);
318 break;
319 }
320
321 [[fallthrough]];
322 }
323 default: {
324 ThrowSyntaxError("Unexpected token, arrow (=>)");
325 }
326 }
327
328 return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus};
329 }
330
331 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElementToken(ExpressionParseFlags flags)332 std::tuple<ir::AnnotatedExpression *, bool> ASParser::ParsePatternElementToken(ExpressionParseFlags flags)
333 {
334 ir::AnnotatedExpression *returnNode = nullptr;
335 bool isOptional = false;
336
337 switch (Lexer()->GetToken().Type()) {
338 case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
339 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
340 ThrowSyntaxError("Unexpected token");
341 }
342
343 returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
344 break;
345 }
346 case lexer::TokenType::LITERAL_IDENT: {
347 returnNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
348 ES2PANDA_ASSERT(returnNode != nullptr);
349 returnNode->SetRange(Lexer()->GetToken().Loc());
350 Lexer()->NextToken();
351
352 bool questionMark = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK;
353 if (questionMark && ((flags & ExpressionParseFlags::IN_REST) != 0)) {
354 ThrowSyntaxError("A rest parameter cannot be optional");
355 }
356
357 if (questionMark) {
358 isOptional = true;
359
360 returnNode->AsIdentifier()->SetOptional(true);
361 Lexer()->NextToken();
362 }
363
364 if (!isOptional && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
365 ThrowSyntaxError("':' expected");
366 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
367 Lexer()->NextToken(); // eat ':'
368 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
369 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
370 }
371
372 break;
373 }
374 default: {
375 ThrowSyntaxError("Identifier expected");
376 }
377 }
378 return {returnNode, isOptional};
379 }
380
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault)381 ir::Expression *ASParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
382 {
383 ir::AnnotatedExpression *returnNode = nullptr;
384 bool isOptional = false;
385 std::tie(returnNode, isOptional) = ParsePatternElementToken(flags);
386
387 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
388 return returnNode;
389 }
390
391 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
392 ThrowSyntaxError("A rest parameter cannot have an initializer.");
393 }
394
395 if (!allowDefault) {
396 ThrowSyntaxError("Invalid destructuring assignment target");
397 }
398
399 if (isOptional) {
400 ThrowSyntaxError("Parameter cannot have question mark and initializer");
401 }
402
403 Lexer()->NextToken();
404
405 if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) &&
406 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
407 ThrowSyntaxError("Yield is not allowed in generator parameters");
408 }
409
410 ir::Expression *rightNode = ParseExpression();
411
412 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
413 ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
414 assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
415
416 return assignmentExpression;
417 }
418
419 // NOLINTNEXTLINE(google-default-arguments)
ParsePropertyDefinition(ExpressionParseFlags flags)420 ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)
421 {
422 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
423
424 ir::Expression *key = nullptr;
425
426 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
427 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
428 ThrowSyntaxError("Identifier expected");
429 }
430
431 key = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
432 } else {
433 key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
434 }
435
436 ES2PANDA_ASSERT(key != nullptr);
437 key->SetRange(Lexer()->GetToken().Loc());
438
439 Lexer()->NextToken();
440
441 ir::Expression *value = nullptr;
442
443 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
444 Lexer()->NextToken();
445 value = ParseExpression();
446 } else if (!key->IsStringLiteral()) {
447 value = key;
448 } else {
449 ThrowSyntaxError("':' expected");
450 }
451
452 auto *property = AllocNode<ir::Property>(key, value);
453 ES2PANDA_ASSERT(property != nullptr);
454 property->SetRange({key->Start(), value->End()});
455 return property;
456 }
457
CurrentIsBasicType()458 bool ASParser::CurrentIsBasicType()
459 {
460 switch (Lexer()->GetToken().Type()) {
461 case lexer::TokenType::LITERAL_STRING:
462 case lexer::TokenType::LITERAL_FALSE:
463 case lexer::TokenType::LITERAL_TRUE:
464 case lexer::TokenType::LITERAL_NULL:
465 case lexer::TokenType::KEYW_VOID: {
466 return true;
467 }
468 case lexer::TokenType::LITERAL_IDENT: {
469 switch (Lexer()->GetToken().KeywordType()) {
470 case lexer::TokenType::KEYW_I8:
471 case lexer::TokenType::KEYW_I16:
472 case lexer::TokenType::KEYW_I32:
473 case lexer::TokenType::KEYW_I64:
474 case lexer::TokenType::KEYW_ISIZE:
475 case lexer::TokenType::KEYW_U8:
476 case lexer::TokenType::KEYW_U16:
477 case lexer::TokenType::KEYW_U32:
478 case lexer::TokenType::KEYW_U64:
479 case lexer::TokenType::KEYW_USIZE:
480 case lexer::TokenType::KEYW_F32:
481 case lexer::TokenType::KEYW_F64:
482 case lexer::TokenType::KEYW_V128:
483 case lexer::TokenType::KEYW_FUNCREF:
484 case lexer::TokenType::KEYW_EXTERNREF:
485 case lexer::TokenType::KEYW_ANYREF:
486 case lexer::TokenType::KEYW_EQREF:
487 case lexer::TokenType::KEYW_I31REF:
488 case lexer::TokenType::KEYW_DATAREF: {
489 return true;
490 }
491 default: {
492 break;
493 }
494 }
495
496 break;
497 }
498 default: {
499 break;
500 }
501 }
502 return false;
503 }
504
ParseFunctionType(lexer::SourcePosition startLoc)505 ir::TypeNode *ASParser::ParseFunctionType(lexer::SourcePosition startLoc)
506 {
507 auto params = ParseFunctionParams();
508
509 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
510 ThrowSyntaxError("'=>' expected");
511 }
512
513 Lexer()->NextToken(); // eat '=>'
514
515 TypeAnnotationParsingOptions options =
516 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
517 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
518
519 auto signature = ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation);
520 auto funcType = AllocNode<ir::TSFunctionType>(std::move(signature), Allocator());
521
522 funcType->SetRange({startLoc, returnTypeAnnotation->End()});
523
524 return funcType;
525 }
526
ParseParenthesizedOrFunctionType(bool throwError)527 ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError)
528 {
529 lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
530 const auto startPos = Lexer()->Save();
531 ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
532 Lexer()->NextToken(); // eat '('
533
534 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
535 ir::TypeNode *type = ParseTypeAnnotation(&options);
536
537 if (type == nullptr) {
538 Lexer()->Rewind(startPos);
539
540 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
541 if (throwError) {
542 ThrowSyntaxError("Identifier expected");
543 }
544
545 return nullptr;
546 }
547
548 return ParseFunctionType(typeStart);
549 }
550
551 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
552 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
553 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
554 Lexer()->Rewind(startPos);
555 return ParseFunctionType(typeStart);
556 }
557
558 if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
559 ThrowSyntaxError("')' expected");
560 }
561
562 lexer::SourcePosition endLoc = Lexer()->GetToken().End();
563 Lexer()->NextToken(); // eat ')'
564
565 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
566 Lexer()->Rewind(startPos);
567
568 return ParseFunctionType(typeStart);
569 }
570
571 type->SetRange({typeStart, endLoc});
572 return type;
573 }
574
ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode * type,TypeAnnotationParsingOptions * options)575 ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)
576 {
577 auto *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
578 ES2PANDA_ASSERT(typeName != nullptr);
579 typeName->SetRange(Lexer()->GetToken().Loc());
580 type = AllocNode<ir::NamedType>(typeName, Allocator());
581 ES2PANDA_ASSERT(type != nullptr);
582 type->SetRange(Lexer()->GetToken().Loc());
583 Lexer()->NextToken();
584
585 ir::NamedType *current = type->AsNamedType();
586 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
587 Lexer()->NextToken();
588
589 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
590 ThrowSyntaxError("Identifier expected");
591 }
592
593 typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
594 ES2PANDA_ASSERT(typeName != nullptr);
595 typeName->SetRange(Lexer()->GetToken().Loc());
596 auto *next = AllocNode<ir::NamedType>(typeName, Allocator());
597 current->SetRange(Lexer()->GetToken().Loc());
598 current->SetNext(next);
599 current = next;
600 Lexer()->NextToken();
601 }
602
603 ir::TSTypeParameterInstantiation *typeParams = nullptr;
604 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
605 typeParams = ParseTypeParameterInstantiation(options);
606 if (typeParams == nullptr) {
607 return nullptr;
608 }
609
610 type->AsNamedType()->SetTypeParams(typeParams);
611 }
612 return type;
613 }
614
ParseTypeAnnotationTokens(ir::TypeNode * type,bool throwError,TypeAnnotationParsingOptions * options)615 ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError,
616 TypeAnnotationParsingOptions *options)
617 {
618 util::StringView name = "";
619 switch (Lexer()->GetToken().Type()) {
620 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
621 return ParseParenthesizedOrFunctionType(throwError);
622 }
623 case lexer::TokenType::KEYW_VOID: {
624 name = "void";
625 break;
626 }
627 case lexer::TokenType::KEYW_THIS: {
628 name = "this";
629 break;
630 }
631 case lexer::TokenType::LITERAL_FALSE:
632 case lexer::TokenType::LITERAL_TRUE: {
633 name = "bool";
634 break;
635 }
636 case lexer::TokenType::LITERAL_NULL: {
637 name = "null";
638 break;
639 }
640 case lexer::TokenType::LITERAL_STRING: {
641 name = "string";
642 break;
643 }
644 case lexer::TokenType::LITERAL_IDENT: {
645 return ParseTypeAnnotationLiteralIdentHelper(type, options);
646 }
647 default: {
648 if (throwError) {
649 ThrowSyntaxError("Type expected");
650 }
651
652 return nullptr;
653 }
654 }
655
656 auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
657 ES2PANDA_ASSERT(typeName != nullptr);
658 typeName->SetRange(Lexer()->GetToken().Loc());
659 type = AllocNode<ir::NamedType>(typeName, Allocator());
660 ES2PANDA_ASSERT(type != nullptr);
661 type->SetRange(Lexer()->GetToken().Loc());
662 Lexer()->NextToken();
663 return type;
664 }
665
ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode * type,bool throwError,bool isNullable)666 ir::TypeNode *ASParser::ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)
667 {
668 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
669 Lexer()->NextToken();
670
671 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL) {
672 if (throwError) {
673 ThrowSyntaxError("'null' expected");
674 }
675
676 return nullptr;
677 }
678
679 if (!isNullable) {
680 isNullable = true;
681 if (type->IsTSFunctionType()) {
682 type->AsTSFunctionType()->SetNullable(isNullable);
683 } else {
684 ES2PANDA_ASSERT(type->IsNamedType());
685 type->AsNamedType()->SetNullable(isNullable);
686 }
687 }
688
689 type->SetEnd(Lexer()->GetToken().End());
690 Lexer()->NextToken();
691 }
692 return type;
693 }
694
ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode * type,bool throwError,bool isNullable)695 ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)
696 {
697 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
698 Lexer()->NextToken();
699
700 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
701 if (throwError) {
702 ThrowSyntaxError("']' expected");
703 }
704
705 return nullptr;
706 }
707
708 Lexer()->NextToken();
709
710 isNullable = false;
711
712 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
713 Lexer()->NextToken();
714
715 bool isLiteralNull = Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL;
716 if (isLiteralNull && throwError) {
717 ThrowSyntaxError("'null' expected");
718 }
719 if (isLiteralNull) {
720 return nullptr;
721 }
722
723 isNullable = true;
724 }
725
726 const lexer::SourcePosition &startPos = type->Start();
727
728 util::StringView name = "Array";
729 auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
730 ES2PANDA_ASSERT(typeName != nullptr);
731 typeName->SetRange(Lexer()->GetToken().Loc());
732
733 ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
734 params.push_back(type);
735 auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
736
737 type = AllocNode<ir::NamedType>(typeName, Allocator());
738 type->AsNamedType()->SetTypeParams(typeParamInst);
739 type->AsNamedType()->SetNullable(isNullable);
740 type->SetRange({startPos, Lexer()->GetToken().End()});
741
742 if (isNullable) {
743 Lexer()->NextToken();
744 break;
745 }
746 }
747 return type;
748 }
749
ParseTypeAnnotation(TypeAnnotationParsingOptions * options)750 ir::TypeNode *ASParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
751 {
752 bool reportError = (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
753 ir::TypeNode *type = ParseTypeAnnotationTokens(nullptr, reportError, options);
754 if (type == nullptr) {
755 return nullptr;
756 }
757
758 bool isNullable = false;
759 type = ParseTypeAnnotationTokensBitwiseOr(type, reportError, isNullable);
760 if (type == nullptr) {
761 return nullptr;
762 }
763
764 type = ParseTypeAnnotationTokenLeftSquareBracket(type, reportError, isNullable);
765 return type;
766 }
767
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)768 ir::ArrowFunctionExpression *ASParser::ParsePotentialArrowExpression(
769 // CC-OFFNXT(G.FMT.06-CPP) project code style
770 [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)
771 {
772 return nullptr;
773 }
774
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)775 bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
776 {
777 if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
778 return true;
779 }
780
781 *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
782 ES2PANDA_ASSERT(*returnExpression != nullptr);
783 // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
784 (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
785 Lexer()->NextToken();
786 return false;
787 }
788
ParsePotentialGenericFunctionCall(ir::Expression * primaryExpr,ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)789 bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
790 const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
791 {
792 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
793 (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
794 return true;
795 }
796
797 const auto savedPos = Lexer()->Save();
798
799 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
800 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
801 }
802
803 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
804 ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
805
806 if (typeParams == nullptr) {
807 Lexer()->Rewind(savedPos);
808 return true;
809 }
810
811 if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
812 ThrowSyntaxError("'(' or '`' expected");
813 }
814
815 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
816 if (!ignoreCallExpression) {
817 *returnExpression = ParseCallExpression(*returnExpression, false);
818 (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
819 return false;
820 }
821
822 return true;
823 }
824
825 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
826 ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
827 lexer::SourcePosition endLoc = propertyNode->End();
828
829 *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
830 ES2PANDA_ASSERT(returnExpression != nullptr);
831 // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
832 (*returnExpression)->SetRange({startLoc, endLoc});
833 return false;
834 }
835
836 Lexer()->Rewind(savedPos);
837 return true;
838 }
839
IsNamedFunctionExpression()840 bool ASParser::IsNamedFunctionExpression()
841 {
842 return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
843 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
844 }
845
ParsePotentialAsExpression(ir::Expression * primaryExpression)846 ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpression)
847 {
848 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
849 return nullptr;
850 }
851
852 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
853 Lexer()->NextToken();
854 ir::TypeNode *type = ParseTypeAnnotation(&options);
855 auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpression, type, false);
856 return asExpression;
857 }
858
ParsePrimaryExpressionIdent(ExpressionParseFlags flags)859 ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
860 {
861 auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
862 ES2PANDA_ASSERT(identNode != nullptr);
863 identNode->SetRange(Lexer()->GetToken().Loc());
864
865 Lexer()->NextToken();
866
867 ParsePotentialOptionalFunctionParameter(identNode);
868
869 return identNode;
870 }
871
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)872 bool ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
873 {
874 ParseOptionalFunctionParameter(restElement, true);
875
876 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
877 ThrowSyntaxError("')' expected");
878 }
879
880 return true;
881 }
882
883 // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic
ParseInterfaceExtendsClause()884 ArenaVector<ir::TSInterfaceHeritage *> ASParser::ParseInterfaceExtendsClause()
885 {
886 Lexer()->NextToken(); // eat extends keyword
887
888 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
889 ThrowSyntaxError("Identifier expected");
890 }
891
892 const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
893 lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
894 auto *extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
895 ES2PANDA_ASSERT(extendsName != nullptr);
896 extendsName->SetRange(Lexer()->GetToken().Loc());
897 auto *extendsClause = AllocNode<ir::NamedType>(extendsName, Allocator());
898 ES2PANDA_ASSERT(extendsClause != nullptr);
899 extendsClause->SetRange(Lexer()->GetToken().Loc());
900 Lexer()->NextToken();
901
902 ir::NamedType *current = extendsClause->AsNamedType();
903 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
904 Lexer()->NextToken();
905
906 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
907 ThrowSyntaxError("Identifier expected");
908 }
909
910 extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
911 extendsName->SetRange(Lexer()->GetToken().Loc());
912 auto *next = AllocNode<ir::NamedType>(extendsName, Allocator());
913 current->SetRange(Lexer()->GetToken().Loc());
914 current->SetNext(next);
915 current = next;
916 heritageEnd = Lexer()->GetToken().End();
917 Lexer()->NextToken();
918 }
919
920 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
921 Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
922 } else {
923 Lexer()->NextToken();
924 }
925
926 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
927 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
928 extendsClause->AsNamedType()->SetTypeParams(ParseTypeParameterInstantiation(&options));
929 heritageEnd = Lexer()->GetToken().End();
930 }
931
932 extendsClause->SetRange({heritageStart, heritageEnd});
933
934 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
935 ThrowSyntaxError("Interface declaration cannot have 'implements' clause");
936 }
937
938 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
939 ThrowSyntaxError("'{' expected");
940 }
941
942 ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
943 auto *heritage = AllocNode<ir::TSInterfaceHeritage>(extendsClause);
944 heritage->SetRange(extendsClause->Range());
945 extends.push_back(heritage);
946 return extends;
947 }
948
949 // NOLINTNEXTLINE(google-default-arguments)
ParseIndexSignature(const lexer::SourcePosition & startLoc,bool isReadonly)950 ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
951 {
952 Lexer()->NextToken(); // eat '['
953
954 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
955 ThrowSyntaxError("Identifier expected.");
956 }
957
958 if (!Lexer()->GetToken().Ident().Is("key")) {
959 ThrowSyntaxError("'key' expected.");
960 }
961
962 auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
963 ES2PANDA_ASSERT(key != nullptr);
964 key->SetRange(Lexer()->GetToken().Loc());
965
966 Lexer()->NextToken(); // eat key
967
968 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
969 ThrowSyntaxError("':' expected.");
970 }
971
972 Lexer()->NextToken(); // eat ':'
973
974 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
975 ir::TypeNode *keyType = ParseTypeAnnotation(&options);
976 key->SetTsTypeAnnotation(keyType);
977
978 if (!keyType->IsNamedType()) {
979 ThrowSyntaxError("Type expected.");
980 }
981
982 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
983 ThrowSyntaxError("']' expected.");
984 }
985
986 Lexer()->NextToken(); // eat ']'
987
988 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
989 ThrowSyntaxError("':' expected.");
990 }
991
992 Lexer()->NextToken(); // eat ':'
993
994 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
995
996 if (!typeAnnotation->IsNamedType()) {
997 ThrowSyntaxError("Identifier expected.");
998 }
999
1000 auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
1001 indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1002 return indexSignature;
1003 }
1004
ParseInterfacePropertyKey()1005 std::tuple<ir::Expression *, bool> ASParser::ParseInterfacePropertyKey()
1006 {
1007 ir::Expression *key = nullptr;
1008
1009 switch (Lexer()->GetToken().Type()) {
1010 case lexer::TokenType::LITERAL_IDENT: {
1011 const util::StringView &ident = Lexer()->GetToken().Ident();
1012 key = AllocNode<ir::Identifier>(ident, Allocator());
1013 ES2PANDA_ASSERT(key != nullptr);
1014 key->SetRange(Lexer()->GetToken().Loc());
1015 break;
1016 }
1017 case lexer::TokenType::LITERAL_STRING: {
1018 const util::StringView &string = Lexer()->GetToken().String();
1019 key = AllocNode<ir::StringLiteral>(string);
1020 ES2PANDA_ASSERT(key != nullptr);
1021 key->SetRange(Lexer()->GetToken().Loc());
1022 break;
1023 }
1024 case lexer::TokenType::LITERAL_NUMBER: {
1025 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1026 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1027 } else {
1028 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1029 }
1030
1031 ES2PANDA_ASSERT(key != nullptr);
1032 key->SetRange(Lexer()->GetToken().Loc());
1033 break;
1034 }
1035 default: {
1036 ThrowSyntaxError("Unexpected token in property key");
1037 }
1038 }
1039
1040 Lexer()->NextToken();
1041 return {key, false};
1042 }
1043
ParsePropertyOrMethodSignature(const lexer::SourcePosition & startLoc,bool isReadonly)1044 ir::AstNode *ASParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1045 {
1046 auto [key, isComputed] = ParseInterfacePropertyKey();
1047
1048 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1049 ThrowSyntaxError("Optional properties are not supported.");
1050 }
1051
1052 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1053 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1054 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1055
1056 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1057 auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1058 typeParamDecl = ParseTypeParameterDeclaration(&options);
1059 }
1060
1061 FunctionParameterContext funcParamContext(&GetContext());
1062 auto params = ParseFunctionParams();
1063
1064 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1065 ThrowSyntaxError("Type expected.");
1066 }
1067
1068 Lexer()->NextToken(); // eat ':'
1069 TypeAnnotationParsingOptions options =
1070 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1071 ir::TypeNode *returnType = ParseTypeAnnotation(&options);
1072
1073 auto signature = ir::FunctionSignature(typeParamDecl, std::move(params), returnType);
1074 auto *methodSignature = AllocNode<ir::TSMethodSignature>(key, std::move(signature), isComputed, false);
1075 methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1076 return methodSignature;
1077 }
1078
1079 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1080 ThrowSyntaxError("Type expected.");
1081 }
1082
1083 Lexer()->NextToken(); // eat ':'
1084 TypeAnnotationParsingOptions options =
1085 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1086 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1087
1088 auto *propertySignature = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, false, isReadonly);
1089 propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1090 return propertySignature;
1091 }
1092
ParseTypeLiteralOrInterfaceMember()1093 ir::AstNode *ASParser::ParseTypeLiteralOrInterfaceMember()
1094 {
1095 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1096 ThrowSyntaxError("Decorators are not allowed here");
1097 }
1098
1099 char32_t nextCp = Lexer()->Lookahead();
1100 lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1101 bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1102 nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON;
1103 if (isReadonly) {
1104 Lexer()->NextToken(); // eat 'readonly"
1105 }
1106
1107 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1108 return ParseIndexSignature(startLoc, isReadonly);
1109 }
1110
1111 return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1112 }
1113
ParseClassImplementClause()1114 ArenaVector<ir::TSClassImplements *> ASParser::ParseClassImplementClause()
1115 {
1116 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
1117
1118 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1119 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1120 ThrowSyntaxError("Identifier expected");
1121 }
1122
1123 const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start();
1124 auto *implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1125 ES2PANDA_ASSERT(implementsName != nullptr);
1126 implementsName->SetRange(Lexer()->GetToken().Loc());
1127 auto *implementsClause = AllocNode<ir::NamedType>(implementsName, Allocator());
1128 ES2PANDA_ASSERT(implementsClause != nullptr);
1129 implementsClause->SetRange(Lexer()->GetToken().Loc());
1130 Lexer()->NextToken();
1131
1132 ir::NamedType *current = implementsClause->AsNamedType();
1133 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1134 Lexer()->NextToken();
1135
1136 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1137 ThrowSyntaxError("Identifier expected");
1138 }
1139
1140 implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1141 ES2PANDA_ASSERT(implementsName != nullptr);
1142 implementsName->SetRange(Lexer()->GetToken().Loc());
1143 auto *next = AllocNode<ir::NamedType>(implementsName, Allocator());
1144 current->SetRange(Lexer()->GetToken().Loc());
1145 current->SetNext(next);
1146 current = next;
1147 Lexer()->NextToken();
1148 }
1149
1150 ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
1151 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1152 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1153 }
1154
1155 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
1156 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1157 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1158 implTypeParams = ParseTypeParameterInstantiation(&options);
1159 }
1160
1161 auto *impl = AllocNode<ir::TSClassImplements>(current, implTypeParams);
1162 ES2PANDA_ASSERT(impl != nullptr);
1163 impl->SetRange({implementStart, Lexer()->GetToken().End()});
1164 implements.push_back(impl);
1165
1166 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1167 Lexer()->NextToken();
1168 continue;
1169 }
1170 ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
1171 }
1172
1173 if (implements.empty()) {
1174 ThrowSyntaxError("Implements clause can not be empty");
1175 }
1176
1177 return implements;
1178 }
1179
ParseClassKeyAnnotation()1180 ir::TypeNode *ASParser::ParseClassKeyAnnotation()
1181 {
1182 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1183 Lexer()->NextToken(); // eat ':'
1184 TypeAnnotationParsingOptions options =
1185 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1186 return ParseTypeAnnotation(&options);
1187 }
1188
1189 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1190 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1191 ThrowSyntaxError("Type expected");
1192 }
1193
1194 return nullptr;
1195 }
1196
ValidateClassMethodStart(ClassElementDescriptor * desc,ir::TypeNode * typeAnnotation)1197 void ASParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1198 {
1199 if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1200 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1201 if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) {
1202 ThrowSyntaxError("'declare' modifier cannot appear on class elements of this kind");
1203 }
1204
1205 desc->classMethod = true;
1206 } else {
1207 if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1208 ThrowSyntaxError("Expected '('");
1209 }
1210 desc->classField = true;
1211
1212 if (desc->invalidComputedProperty) {
1213 ThrowSyntaxError(
1214 "Computed property name must refer to a symbol or "
1215 "literal expression whose value is "
1216 "number or string");
1217 }
1218 }
1219
1220 if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1221 desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1222 }
1223
1224 if (desc->isGenerator) {
1225 desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1226 }
1227 }
1228
ValidateClassSetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1229 void ASParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1230 ir::Expression *propName, ir::ScriptFunction *func)
1231 {
1232 ValidateGetterSetter(ir::MethodDefinitionKind::SET, func->Params().size());
1233
1234 if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1235 ir::ModifierFlags access = GetAccessability(desc->modifiers);
1236 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1237 }
1238 }
1239
ValidateClassGetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1240 void ASParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1241 ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)
1242 {
1243 if ((desc->modifiers & ir::ModifierFlags::STATIC) != 0) {
1244 ir::ModifierFlags access = GetAccessability(desc->modifiers);
1245
1246 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1247 }
1248 }
1249
ParseClassStaticBlock()1250 ir::ClassElement *ASParser::ParseClassStaticBlock()
1251 {
1252 ThrowSyntaxError("Unexpected token");
1253 return nullptr;
1254 }
1255
ParseOptionalClassElement(ClassElementDescriptor * desc)1256 void ASParser::ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)
1257 {
1258 ThrowSyntaxError("Optional properties are not supported");
1259 }
1260
ValidateIndexSignatureTypeAnnotation(ir::TypeNode * typeAnnotation)1261 void ASParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1262 {
1263 if (typeAnnotation == nullptr) {
1264 ThrowSyntaxError("':' expected");
1265 }
1266
1267 if (!typeAnnotation->IsNamedType()) {
1268 ThrowSyntaxError("Identifier expected");
1269 }
1270 }
1271
IsModifierKind(const lexer::Token & token)1272 bool ASParser::IsModifierKind(const lexer::Token &token)
1273 {
1274 switch (token.KeywordType()) {
1275 case lexer::TokenType::KEYW_PUBLIC:
1276 case lexer::TokenType::KEYW_PRIVATE:
1277 case lexer::TokenType::KEYW_PROTECTED:
1278 case lexer::TokenType::KEYW_STATIC:
1279 case lexer::TokenType::KEYW_ASYNC:
1280 case lexer::TokenType::KEYW_DECLARE:
1281 case lexer::TokenType::KEYW_READONLY:
1282 return true;
1283 default:
1284 break;
1285 }
1286
1287 return false;
1288 }
1289
ConsumeClassPrivateIdentifier(ClassElementDescriptor * desc,char32_t * nextCp)1290 void ASParser::ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc,
1291 [[maybe_unused]] char32_t *nextCp)
1292 {
1293 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1294 ThrowSyntaxError("Invalid character");
1295 }
1296 }
1297
ParseComputedClassFieldOrIndexSignature(ir::Expression ** propName)1298 std::tuple<bool, bool, bool> ASParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1299 {
1300 Lexer()->NextToken(); // eat left square bracket
1301
1302 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1303 Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1304 if (!Lexer()->GetToken().Ident().Is("key")) {
1305 ThrowSyntaxError("'key' expected.");
1306 }
1307
1308 auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1309 ES2PANDA_ASSERT(id != nullptr);
1310 id->SetRange(Lexer()->GetToken().Loc());
1311
1312 Lexer()->NextToken(); // eat param
1313
1314 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1315 ThrowSyntaxError("':' expected");
1316 }
1317
1318 Lexer()->NextToken(); // eat ':'
1319 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1320 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1321
1322 if (!typeAnnotation->IsNamedType()) {
1323 ThrowSyntaxError("Type expected");
1324 }
1325
1326 id->SetTsTypeAnnotation(typeAnnotation);
1327 *propName = id;
1328
1329 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1330 ThrowSyntaxError("']' expected");
1331 }
1332
1333 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1334
1335 return {false, false, true};
1336 }
1337
1338 *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1339
1340 bool invalidComputedProperty =
1341 !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
1342 !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
1343 (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
1344
1345 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1346 ThrowSyntaxError("Unexpected token, expected ']'");
1347 }
1348
1349 return {true, invalidComputedProperty, false};
1350 }
1351
ParseFunctionBody(const ArenaVector<ir::Expression * > & params,ParserStatus newStatus,ParserStatus contextStatus)1352 std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> ASParser::ParseFunctionBody(
1353 // CC-OFFNXT(G.FMT.06-CPP) project code style
1354 [[maybe_unused]] const ArenaVector<ir::Expression *> ¶ms, [[maybe_unused]] ParserStatus newStatus,
1355 ParserStatus contextStatus)
1356 {
1357 bool isDeclare = InAmbientContext();
1358 bool isOverload = false;
1359 bool letDeclare = true;
1360 ir::BlockStatement *body = nullptr;
1361 lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1362
1363 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1364 if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
1365 ThrowSyntaxError("Unexpected token, expected '{'");
1366 } else {
1367 letDeclare = false;
1368 }
1369
1370 isOverload = true;
1371 } else if (isDeclare) {
1372 ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
1373 } else {
1374 body = ParseBlockStatement();
1375 ES2PANDA_ASSERT(body != nullptr);
1376 endLoc = body->End();
1377 }
1378
1379 return {letDeclare, body, endLoc, isOverload};
1380 }
1381
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode * > * specifiers)1382 ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1383 {
1384 ir::Identifier *local = ParseNamedImport(&Lexer()->GetToken());
1385 Lexer()->NextToken(); // eat local name
1386
1387 auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1388 ES2PANDA_ASSERT(specifier != nullptr);
1389 specifier->SetRange(specifier->Local()->Range());
1390 specifiers->push_back(specifier);
1391
1392 return nullptr;
1393 }
1394
ParseArrowFunctionRestParameter(lexer::SourcePosition start)1395 ir::Expression *ASParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
1396 {
1397 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1398
1399 restElement->SetGrouped();
1400 restElement->SetStart(start);
1401
1402 ValidateArrowFunctionRestParameter(restElement);
1403
1404 Lexer()->NextToken();
1405
1406 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1407 ThrowSyntaxError(":' expected");
1408 }
1409
1410 Lexer()->NextToken(); // eat ':'
1411
1412 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1413 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1414
1415 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1416 ThrowSyntaxError("'=>' expected");
1417 }
1418
1419 return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
1420 }
1421
ParseArrowFunctionNoParameter(lexer::SourcePosition start)1422 ir::Expression *ASParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
1423 {
1424 Lexer()->NextToken();
1425
1426 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1427 ThrowSyntaxError(":' expected");
1428 }
1429
1430 Lexer()->NextToken(); // eat ':'
1431
1432 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1433 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1434
1435 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1436 ThrowSyntaxError("'=>' expected");
1437 }
1438
1439 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
1440 arrowExpr->SetStart(start);
1441 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
1442
1443 return arrowExpr;
1444 }
1445
1446 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)1447 ir::Expression *ASParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
1448 [[maybe_unused]] ExpressionParseFlags flags) // CC-OFF(G.FMT.06-CPP) project code style
1449 {
1450 ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1451 lexer::SourcePosition start = Lexer()->GetToken().Start();
1452 Lexer()->NextToken();
1453 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1454
1455 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1456 return ParseArrowFunctionRestParameter(start);
1457 }
1458
1459 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1460 return ParseArrowFunctionNoParameter(start);
1461 }
1462
1463 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
1464 ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
1465
1466 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1467 ThrowSyntaxError("')' expected");
1468 }
1469
1470 expr->SetGrouped();
1471 expr->SetRange({start, Lexer()->GetToken().End()});
1472 Lexer()->NextToken();
1473
1474 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1475 ThrowSyntaxError("':' expected.");
1476 }
1477
1478 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1479 auto savedPos = Lexer()->Save();
1480 Lexer()->NextToken(); // eat ':'
1481 options = TypeAnnotationParsingOptions::NO_OPTS;
1482 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1483
1484 if (returnTypeAnnotation == nullptr) {
1485 Lexer()->Rewind(savedPos);
1486 return expr;
1487 }
1488
1489 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1490 Lexer()->Rewind(savedPos);
1491 return expr;
1492 }
1493
1494 return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
1495 }
1496
1497 return expr;
1498 }
1499
ParsePrefixAssertionExpression()1500 ir::Expression *ASParser::ParsePrefixAssertionExpression()
1501 {
1502 lexer::SourcePosition startPos = Lexer()->GetToken().Start();
1503 Lexer()->NextToken(); // eat <
1504 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1505 ir::TypeNode *type = ParseTypeAnnotation(&options);
1506
1507 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1508 ThrowSyntaxError("'>' expected");
1509 }
1510
1511 Lexer()->NextToken(); // eat >
1512
1513 ir::Expression *expr = ParseExpression();
1514
1515 auto *node = AllocNode<ir::PrefixAssertionExpression>(expr, type);
1516 node->SetRange({startPos, Lexer()->GetToken().End()});
1517 return node;
1518 }
1519
ParseConstStatement(StatementParsingFlags flags)1520 ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags)
1521 {
1522 lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
1523 Lexer()->NextToken();
1524
1525 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1526 return ParseEnumDeclaration(true);
1527 }
1528
1529 if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
1530 ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
1531 }
1532
1533 auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
1534 ES2PANDA_ASSERT(variableDecl != nullptr);
1535 variableDecl->SetStart(constVarStar);
1536 ConsumeSemicolon(variableDecl);
1537
1538 return variableDecl;
1539 }
1540
ParseVariableDeclaratorKey(VariableParsingFlags flags)1541 ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
1542 {
1543 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1544 ThrowSyntaxError("Identifier expected");
1545 }
1546
1547 ValidateDeclaratorId();
1548
1549 const util::StringView &identStr = Lexer()->GetToken().Ident();
1550 auto init = AllocNode<ir::Identifier>(identStr, Allocator());
1551 ES2PANDA_ASSERT(init != nullptr);
1552 init->SetRange(Lexer()->GetToken().Loc());
1553 Lexer()->NextToken();
1554
1555 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1556 Lexer()->NextToken(); // eat ':'
1557 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1558 init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1559 } else if (((flags & VariableParsingFlags::IN_FOR) == 0) &&
1560 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1561 ThrowSyntaxError("Type expected");
1562 }
1563
1564 return init;
1565 }
1566
ParsePotentialConstEnum(VariableParsingFlags flags)1567 ir::Statement *ASParser::ParsePotentialConstEnum(VariableParsingFlags flags)
1568 {
1569 if ((flags & VariableParsingFlags::CONST) == 0) {
1570 ThrowSyntaxError("Variable declaration expected.");
1571 }
1572
1573 return ParseEnumDeclaration(true);
1574 }
1575
1576 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition & startLoc,bool isExportEquals)1577 ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1578 bool isExportEquals)
1579 {
1580 Lexer()->NextToken(); // eat `default` keyword or `=`
1581
1582 ir::AstNode *declNode = nullptr;
1583 bool eatSemicolon = false;
1584
1585 switch (Lexer()->GetToken().Type()) {
1586 case lexer::TokenType::KEYW_FUNCTION: {
1587 declNode = ParseFunctionDeclaration(true);
1588 break;
1589 }
1590 case lexer::TokenType::KEYW_CLASS: {
1591 declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1592 break;
1593 }
1594 case lexer::TokenType::KEYW_INTERFACE: {
1595 declNode = ParseInterfaceDeclaration(false);
1596 break;
1597 }
1598 case lexer::TokenType::KEYW_NAMESPACE: {
1599 Lexer()->NextToken(); // eat 'namespace'
1600 declNode = ParseModuleOrNamespaceDeclaration(startLoc);
1601 break;
1602 }
1603 case lexer::TokenType::KEYW_ENUM: {
1604 declNode = ParseEnumDeclaration();
1605 break;
1606 }
1607 case lexer::TokenType::KEYW_ASYNC: {
1608 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1609 Lexer()->NextToken(); // eat `async`
1610 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1611 break;
1612 }
1613
1614 [[fallthrough]];
1615 }
1616 default: {
1617 declNode = ParseExpression();
1618 eatSemicolon = true;
1619 break;
1620 }
1621 }
1622
1623 lexer::SourcePosition endLoc = declNode->End();
1624 auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1625 ES2PANDA_ASSERT(exportDeclaration != nullptr);
1626 exportDeclaration->SetRange({startLoc, endLoc});
1627
1628 if (eatSemicolon) {
1629 ConsumeSemicolon(exportDeclaration);
1630 }
1631
1632 return exportDeclaration;
1633 }
1634
1635 class ASParser::ParseNamedExportDeclarationHelper {
1636 friend ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc);
1637
1638 private:
GetParsedDeclaration(ASParser * parser,lexer::TokenType type)1639 static ir::Statement *GetParsedDeclaration(ASParser *parser, lexer::TokenType type)
1640 {
1641 ir::ModifierFlags flags = ir::ModifierFlags::NONE;
1642 if (parser->Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1643 parser->Lexer()->NextToken(); // eat 'abstract'
1644 flags = ir::ModifierFlags::ABSTRACT;
1645 }
1646
1647 switch (type) {
1648 case lexer::TokenType::KEYW_VAR: {
1649 return parser->ParseVariableDeclaration(VariableParsingFlags::VAR);
1650 }
1651 case lexer::TokenType::KEYW_CONST: {
1652 return parser->ParseVariableDeclaration(VariableParsingFlags::CONST);
1653 }
1654 case lexer::TokenType::KEYW_LET: {
1655 return parser->ParseVariableDeclaration(VariableParsingFlags::LET);
1656 }
1657 case lexer::TokenType::KEYW_FUNCTION: {
1658 return parser->ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1659 }
1660 case lexer::TokenType::KEYW_CLASS: {
1661 return parser->ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED, flags);
1662 }
1663 case lexer::TokenType::KEYW_ENUM: {
1664 return parser->ParseEnumDeclaration();
1665 }
1666 case lexer::TokenType::KEYW_INTERFACE: {
1667 return parser->ParseInterfaceDeclaration(false);
1668 }
1669 case lexer::TokenType::KEYW_TYPE: {
1670 return parser->ParseTypeAliasDeclaration();
1671 }
1672 case lexer::TokenType::KEYW_GLOBAL:
1673 case lexer::TokenType::KEYW_MODULE:
1674 case lexer::TokenType::KEYW_NAMESPACE: {
1675 return parser->ParseModuleDeclaration();
1676 }
1677 default: {
1678 parser->ExpectToken(lexer::TokenType::KEYW_ASYNC);
1679 return parser->ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1680 }
1681 }
1682 }
1683 };
1684
ParseNamedExportDeclaration(const lexer::SourcePosition & startLoc)1685 ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1686 {
1687 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1688 CheckDeclare();
1689 }
1690
1691 ir::Statement *decl =
1692 ParseNamedExportDeclarationHelper::GetParsedDeclaration(this, Lexer()->GetToken().KeywordType());
1693
1694 if (decl->IsVariableDeclaration()) {
1695 ConsumeSemicolon(decl);
1696 }
1697
1698 ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1699 auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1700 ES2PANDA_ASSERT(exportDeclaration != nullptr);
1701 exportDeclaration->SetRange({startLoc, decl->End()});
1702
1703 return exportDeclaration;
1704 }
1705
ParseImportSpecifiers(ArenaVector<ir::AstNode * > * specifiers)1706 ir::AstNode *ASParser::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1707 {
1708 ES2PANDA_ASSERT(specifiers->empty());
1709
1710 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1711 ParseImportDefaultSpecifier(specifiers);
1712 return nullptr;
1713 }
1714
1715 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1716 ParseNameSpaceImport(specifiers);
1717 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1718 ParseNamedImportSpecifiers(specifiers);
1719 }
1720
1721 return nullptr;
1722 }
1723
ParseImportDeclaration(StatementParsingFlags flags)1724 ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
1725 {
1726 char32_t nextChar = Lexer()->Lookahead();
1727 if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
1728 return ParseExpressionStatement();
1729 }
1730
1731 lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1732 Lexer()->NextToken(); // eat import
1733
1734 ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
1735
1736 ir::StringLiteral *source = nullptr;
1737
1738 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1739 ParseImportSpecifiers(&specifiers);
1740 source = ParseFromClause(true);
1741 } else {
1742 source = ParseFromClause(false);
1743 }
1744
1745 ES2PANDA_ASSERT(source != nullptr);
1746 lexer::SourcePosition endLoc = source->End();
1747 auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
1748 ES2PANDA_ASSERT(importDeclaration != nullptr);
1749 importDeclaration->SetRange({startLoc, endLoc});
1750
1751 ConsumeSemicolon(importDeclaration);
1752
1753 return importDeclaration;
1754 }
1755
ReportIllegalBreakError(const lexer::SourcePosition & pos)1756 void ASParser::ReportIllegalBreakError(const lexer::SourcePosition &pos)
1757 {
1758 ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement", pos);
1759 }
1760
ReportIllegalContinueError()1761 void ASParser::ReportIllegalContinueError()
1762 {
1763 ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
1764 }
1765
1766 } // namespace ark::es2panda::parser
1767