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