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());
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
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 id->SetRange(Lexer()->GetToken().Loc());
129 Lexer()->NextToken();
130
131 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
132 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
133 auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
134 typeParamDecl = ParseTypeParameterDeclaration(&options);
135 }
136
137 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
138 ThrowSyntaxError("'=' expected");
139 }
140
141 Lexer()->NextToken(); // eat '='
142
143 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
144 Lexer()->NextToken(); // eat '|'
145 }
146
147 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
148 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
149
150 auto *typeAliasDecl =
151 AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext());
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 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 returnNode->AsIdentifier()->SetReference();
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([[maybe_unused]] 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 key->SetRange(Lexer()->GetToken().Loc());
437
438 Lexer()->NextToken();
439
440 ir::Expression *value = nullptr;
441
442 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
443 Lexer()->NextToken();
444 value = ParseExpression();
445 } else if (!key->IsStringLiteral()) {
446 value = key;
447 } else {
448 ThrowSyntaxError("':' expected");
449 }
450
451 auto *property = AllocNode<ir::Property>(key, value);
452 property->SetRange({key->Start(), value->End()});
453 return property;
454 }
455
CurrentIsBasicType()456 bool ASParser::CurrentIsBasicType()
457 {
458 switch (Lexer()->GetToken().Type()) {
459 case lexer::TokenType::LITERAL_STRING:
460 case lexer::TokenType::LITERAL_FALSE:
461 case lexer::TokenType::LITERAL_TRUE:
462 case lexer::TokenType::LITERAL_NULL:
463 case lexer::TokenType::KEYW_VOID: {
464 return true;
465 }
466 case lexer::TokenType::LITERAL_IDENT: {
467 switch (Lexer()->GetToken().KeywordType()) {
468 case lexer::TokenType::KEYW_I8:
469 case lexer::TokenType::KEYW_I16:
470 case lexer::TokenType::KEYW_I32:
471 case lexer::TokenType::KEYW_I64:
472 case lexer::TokenType::KEYW_ISIZE:
473 case lexer::TokenType::KEYW_U8:
474 case lexer::TokenType::KEYW_U16:
475 case lexer::TokenType::KEYW_U32:
476 case lexer::TokenType::KEYW_U64:
477 case lexer::TokenType::KEYW_USIZE:
478 case lexer::TokenType::KEYW_F32:
479 case lexer::TokenType::KEYW_F64:
480 case lexer::TokenType::KEYW_V128:
481 case lexer::TokenType::KEYW_FUNCREF:
482 case lexer::TokenType::KEYW_EXTERNREF:
483 case lexer::TokenType::KEYW_ANYREF:
484 case lexer::TokenType::KEYW_EQREF:
485 case lexer::TokenType::KEYW_I31REF:
486 case lexer::TokenType::KEYW_DATAREF: {
487 return true;
488 }
489 default: {
490 break;
491 }
492 }
493
494 break;
495 }
496 default: {
497 break;
498 }
499 }
500 return false;
501 }
502
ParseFunctionType(lexer::SourcePosition startLoc)503 ir::TypeNode *ASParser::ParseFunctionType(lexer::SourcePosition startLoc)
504 {
505 auto params = ParseFunctionParams();
506
507 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
508 ThrowSyntaxError("'=>' expected");
509 }
510
511 Lexer()->NextToken(); // eat '=>'
512
513 TypeAnnotationParsingOptions options =
514 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
515 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
516
517 auto signature = ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation);
518 auto funcType = AllocNode<ir::TSFunctionType>(std::move(signature));
519
520 funcType->SetRange({startLoc, returnTypeAnnotation->End()});
521
522 return funcType;
523 }
524
ParseParenthesizedOrFunctionType(bool throwError)525 ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError)
526 {
527 lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
528 const auto startPos = Lexer()->Save();
529 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
530 Lexer()->NextToken(); // eat '('
531
532 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
533 ir::TypeNode *type = ParseTypeAnnotation(&options);
534
535 if (type == nullptr) {
536 Lexer()->Rewind(startPos);
537
538 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
539 if (throwError) {
540 ThrowSyntaxError("Identifier expected");
541 }
542
543 return nullptr;
544 }
545
546 return ParseFunctionType(typeStart);
547 }
548
549 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
550 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
551 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
552 Lexer()->Rewind(startPos);
553 return ParseFunctionType(typeStart);
554 }
555
556 if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
557 ThrowSyntaxError("')' expected");
558 }
559
560 lexer::SourcePosition endLoc = Lexer()->GetToken().End();
561 Lexer()->NextToken(); // eat ')'
562
563 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
564 Lexer()->Rewind(startPos);
565
566 return ParseFunctionType(typeStart);
567 }
568
569 type->SetRange({typeStart, endLoc});
570 return type;
571 }
572
ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)573 ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)
574 {
575 auto *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
576 typeName->SetRange(Lexer()->GetToken().Loc());
577 type = AllocNode<ir::NamedType>(typeName);
578 type->SetRange(Lexer()->GetToken().Loc());
579 Lexer()->NextToken();
580
581 ir::NamedType *current = type->AsNamedType();
582 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
583 Lexer()->NextToken();
584
585 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
586 ThrowSyntaxError("Identifier expected");
587 }
588
589 typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
590 typeName->SetRange(Lexer()->GetToken().Loc());
591 auto *next = AllocNode<ir::NamedType>(typeName);
592 current->SetRange(Lexer()->GetToken().Loc());
593 current->SetNext(next);
594 current = next;
595 Lexer()->NextToken();
596 }
597
598 ir::TSTypeParameterInstantiation *typeParams = nullptr;
599 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
600 typeParams = ParseTypeParameterInstantiation(options);
601 if (typeParams == nullptr) {
602 return nullptr;
603 }
604
605 type->AsNamedType()->SetTypeParams(typeParams);
606 }
607 return type;
608 }
609
ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError, TypeAnnotationParsingOptions *options)610 ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError,
611 TypeAnnotationParsingOptions *options)
612 {
613 util::StringView name = "";
614 switch (Lexer()->GetToken().Type()) {
615 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
616 return ParseParenthesizedOrFunctionType(throwError);
617 }
618 case lexer::TokenType::KEYW_VOID: {
619 name = "void";
620 break;
621 }
622 case lexer::TokenType::KEYW_THIS: {
623 name = "this";
624 break;
625 }
626 case lexer::TokenType::LITERAL_FALSE:
627 case lexer::TokenType::LITERAL_TRUE: {
628 name = "bool";
629 break;
630 }
631 case lexer::TokenType::LITERAL_NULL: {
632 name = "null";
633 break;
634 }
635 case lexer::TokenType::LITERAL_STRING: {
636 name = "string";
637 break;
638 }
639 case lexer::TokenType::LITERAL_IDENT: {
640 return ParseTypeAnnotationLiteralIdentHelper(type, options);
641 }
642 default: {
643 if (throwError) {
644 ThrowSyntaxError("Type expected");
645 }
646
647 return nullptr;
648 }
649 }
650
651 auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
652 typeName->SetRange(Lexer()->GetToken().Loc());
653 type = AllocNode<ir::NamedType>(typeName);
654 type->SetRange(Lexer()->GetToken().Loc());
655 Lexer()->NextToken();
656 return type;
657 }
658
ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)659 ir::TypeNode *ASParser::ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)
660 {
661 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
662 Lexer()->NextToken();
663
664 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL) {
665 if (throwError) {
666 ThrowSyntaxError("'null' expected");
667 }
668
669 return nullptr;
670 }
671
672 if (!isNullable) {
673 isNullable = true;
674 if (type->IsTSFunctionType()) {
675 type->AsTSFunctionType()->SetNullable(isNullable);
676 } else {
677 ASSERT(type->IsNamedType());
678 type->AsNamedType()->SetNullable(isNullable);
679 }
680 }
681
682 type->SetEnd(Lexer()->GetToken().End());
683 Lexer()->NextToken();
684 }
685 return type;
686 }
687
ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)688 ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)
689 {
690 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
691 Lexer()->NextToken();
692
693 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
694 if (throwError) {
695 ThrowSyntaxError("']' expected");
696 }
697
698 return nullptr;
699 }
700
701 Lexer()->NextToken();
702
703 isNullable = false;
704
705 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
706 Lexer()->NextToken();
707
708 bool isLiteralNull = Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL;
709 if (isLiteralNull && throwError) {
710 ThrowSyntaxError("'null' expected");
711 }
712 if (isLiteralNull) {
713 return nullptr;
714 }
715
716 isNullable = true;
717 }
718
719 const lexer::SourcePosition &startPos = type->Start();
720
721 util::StringView name = "Array";
722 auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
723 typeName->SetRange(Lexer()->GetToken().Loc());
724
725 ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
726 params.push_back(type);
727 auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
728
729 type = AllocNode<ir::NamedType>(typeName);
730 type->AsNamedType()->SetTypeParams(typeParamInst);
731 type->AsNamedType()->SetNullable(isNullable);
732 type->SetRange({startPos, Lexer()->GetToken().End()});
733
734 if (isNullable) {
735 Lexer()->NextToken();
736 break;
737 }
738 }
739 return type;
740 }
741
ParseTypeAnnotation(TypeAnnotationParsingOptions *options)742 ir::TypeNode *ASParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
743 {
744 bool reportError = (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
745 ir::TypeNode *type = ParseTypeAnnotationTokens(nullptr, reportError, options);
746 if (type == nullptr) {
747 return nullptr;
748 }
749
750 bool isNullable = false;
751 type = ParseTypeAnnotationTokensBitwiseOr(type, reportError, isNullable);
752 if (type == nullptr) {
753 return nullptr;
754 }
755
756 type = ParseTypeAnnotationTokenLeftSquareBracket(type, reportError, isNullable);
757 return type;
758 }
759
ParsePotentialArrowExpression( [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)760 ir::ArrowFunctionExpression *ASParser::ParsePotentialArrowExpression(
761 [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)
762 {
763 return nullptr;
764 }
765
ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)766 bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
767 {
768 if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
769 return true;
770 }
771
772 *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
773 (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
774 Lexer()->NextToken();
775 return false;
776 }
777
ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression, const lexer::SourcePosition &startLoc, bool ignoreCallExpression)778 bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
779 const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
780 {
781 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
782 (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
783 return true;
784 }
785
786 const auto savedPos = Lexer()->Save();
787
788 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
789 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
790 }
791
792 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
793 ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
794
795 if (typeParams == nullptr) {
796 Lexer()->Rewind(savedPos);
797 return true;
798 }
799
800 if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
801 ThrowSyntaxError("'(' or '`' expected");
802 }
803
804 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
805 if (!ignoreCallExpression) {
806 *returnExpression = ParseCallExpression(*returnExpression, false);
807 (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
808 return false;
809 }
810
811 return true;
812 }
813
814 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
815 ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
816 lexer::SourcePosition endLoc = propertyNode->End();
817
818 *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
819 (*returnExpression)->SetRange({startLoc, endLoc});
820 return false;
821 }
822
823 Lexer()->Rewind(savedPos);
824 return true;
825 }
826
IsNamedFunctionExpression()827 bool ASParser::IsNamedFunctionExpression()
828 {
829 return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
830 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
831 }
832
ParsePotentialAsExpression(ir::Expression *primaryExpression)833 ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpression)
834 {
835 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
836 return nullptr;
837 }
838
839 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
840 Lexer()->NextToken();
841 ir::TypeNode *type = ParseTypeAnnotation(&options);
842 auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpression, type, false);
843 return asExpression;
844 }
845
ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)846 ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
847 {
848 auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
849 identNode->SetReference();
850 identNode->SetRange(Lexer()->GetToken().Loc());
851
852 Lexer()->NextToken();
853
854 ParsePotentialOptionalFunctionParameter(identNode);
855
856 return identNode;
857 }
858
ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)859 void ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
860 {
861 ParseOptionalFunctionParameter(restElement, true);
862
863 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
864 ThrowSyntaxError("')' expected");
865 }
866 }
867
ParseInterfaceExtendsClause()868 ArenaVector<ir::TSInterfaceHeritage *> ASParser::ParseInterfaceExtendsClause()
869 {
870 Lexer()->NextToken(); // eat extends keyword
871
872 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
873 ThrowSyntaxError("Identifier expected");
874 }
875
876 const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
877 lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
878 auto *extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
879 extendsName->SetRange(Lexer()->GetToken().Loc());
880 auto *extendsClause = AllocNode<ir::NamedType>(extendsName);
881 extendsClause->SetRange(Lexer()->GetToken().Loc());
882 Lexer()->NextToken();
883
884 ir::NamedType *current = extendsClause->AsNamedType();
885 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
886 Lexer()->NextToken();
887
888 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
889 ThrowSyntaxError("Identifier expected");
890 }
891
892 extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
893 extendsName->SetRange(Lexer()->GetToken().Loc());
894 auto *next = AllocNode<ir::NamedType>(extendsName);
895 current->SetRange(Lexer()->GetToken().Loc());
896 current->SetNext(next);
897 current = next;
898 heritageEnd = Lexer()->GetToken().End();
899 Lexer()->NextToken();
900 }
901
902 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
903 Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
904 } else {
905 Lexer()->NextToken();
906 }
907
908 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
909 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
910 extendsClause->AsNamedType()->SetTypeParams(ParseTypeParameterInstantiation(&options));
911 heritageEnd = Lexer()->GetToken().End();
912 }
913
914 extendsClause->SetRange({heritageStart, heritageEnd});
915
916 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
917 ThrowSyntaxError("Interface declaration cannot have 'implements' clause");
918 }
919
920 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
921 ThrowSyntaxError("'{' expected");
922 }
923
924 ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
925 auto *heritage = AllocNode<ir::TSInterfaceHeritage>(extendsClause);
926 heritage->SetRange(extendsClause->Range());
927 extends.push_back(heritage);
928 return extends;
929 }
930
931 // NOLINTNEXTLINE(google-default-arguments)
ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)932 ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
933 {
934 Lexer()->NextToken(); // eat '['
935
936 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
937 ThrowSyntaxError("Identifier expected.");
938 }
939
940 if (!Lexer()->GetToken().Ident().Is("key")) {
941 ThrowSyntaxError("'key' expected.");
942 }
943
944 auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
945 key->SetRange(Lexer()->GetToken().Loc());
946
947 Lexer()->NextToken(); // eat key
948
949 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
950 ThrowSyntaxError("':' expected.");
951 }
952
953 Lexer()->NextToken(); // eat ':'
954
955 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
956 ir::TypeNode *keyType = ParseTypeAnnotation(&options);
957 key->SetTsTypeAnnotation(keyType);
958
959 if (!keyType->IsNamedType()) {
960 ThrowSyntaxError("Type expected.");
961 }
962
963 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
964 ThrowSyntaxError("']' expected.");
965 }
966
967 Lexer()->NextToken(); // eat ']'
968
969 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
970 ThrowSyntaxError("':' expected.");
971 }
972
973 Lexer()->NextToken(); // eat ':'
974
975 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
976
977 if (!typeAnnotation->IsNamedType()) {
978 ThrowSyntaxError("Identifier expected.");
979 }
980
981 auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
982 indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
983 return indexSignature;
984 }
985
ParseInterfacePropertyKey()986 std::tuple<ir::Expression *, bool> ASParser::ParseInterfacePropertyKey()
987 {
988 ir::Expression *key = nullptr;
989
990 switch (Lexer()->GetToken().Type()) {
991 case lexer::TokenType::LITERAL_IDENT: {
992 const util::StringView &ident = Lexer()->GetToken().Ident();
993 key = AllocNode<ir::Identifier>(ident, Allocator());
994 key->SetRange(Lexer()->GetToken().Loc());
995 break;
996 }
997 case lexer::TokenType::LITERAL_STRING: {
998 const util::StringView &string = Lexer()->GetToken().String();
999 key = AllocNode<ir::StringLiteral>(string);
1000 key->SetRange(Lexer()->GetToken().Loc());
1001 break;
1002 }
1003 case lexer::TokenType::LITERAL_NUMBER: {
1004 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1005 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1006 } else {
1007 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1008 }
1009
1010 key->SetRange(Lexer()->GetToken().Loc());
1011 break;
1012 }
1013 default: {
1014 ThrowSyntaxError("Unexpected token in property key");
1015 }
1016 }
1017
1018 Lexer()->NextToken();
1019 return {key, false};
1020 }
1021
ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)1022 ir::AstNode *ASParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1023 {
1024 auto [key, isComputed] = ParseInterfacePropertyKey();
1025
1026 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1027 ThrowSyntaxError("Optional properties are not supported.");
1028 }
1029
1030 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1031 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1032 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1033
1034 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1035 auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1036 typeParamDecl = ParseTypeParameterDeclaration(&options);
1037 }
1038
1039 FunctionParameterContext funcParamContext(&GetContext());
1040 auto params = ParseFunctionParams();
1041
1042 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1043 ThrowSyntaxError("Type expected.");
1044 }
1045
1046 Lexer()->NextToken(); // eat ':'
1047 TypeAnnotationParsingOptions options =
1048 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1049 ir::TypeNode *returnType = ParseTypeAnnotation(&options);
1050
1051 auto signature = ir::FunctionSignature(typeParamDecl, std::move(params), returnType);
1052 auto *methodSignature = AllocNode<ir::TSMethodSignature>(key, std::move(signature), isComputed, false);
1053 methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1054 return methodSignature;
1055 }
1056
1057 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1058 ThrowSyntaxError("Type expected.");
1059 }
1060
1061 Lexer()->NextToken(); // eat ':'
1062 TypeAnnotationParsingOptions options =
1063 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1064 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1065
1066 auto *propertySignature = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, false, isReadonly);
1067 propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1068 return propertySignature;
1069 }
1070
ParseTypeLiteralOrInterfaceMember()1071 ir::AstNode *ASParser::ParseTypeLiteralOrInterfaceMember()
1072 {
1073 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1074 ThrowSyntaxError("Decorators are not allowed here");
1075 }
1076
1077 char32_t nextCp = Lexer()->Lookahead();
1078 lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1079 bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1080 nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON;
1081 if (isReadonly) {
1082 Lexer()->NextToken(); // eat 'readonly"
1083 }
1084
1085 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1086 return ParseIndexSignature(startLoc, isReadonly);
1087 }
1088
1089 return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1090 }
1091
ParseClassImplementClause()1092 ArenaVector<ir::TSClassImplements *> ASParser::ParseClassImplementClause()
1093 {
1094 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
1095
1096 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1097 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1098 ThrowSyntaxError("Identifier expected");
1099 }
1100
1101 const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start();
1102 auto *implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1103 implementsName->SetRange(Lexer()->GetToken().Loc());
1104 auto *implementsClause = AllocNode<ir::NamedType>(implementsName);
1105 implementsClause->SetRange(Lexer()->GetToken().Loc());
1106 Lexer()->NextToken();
1107
1108 ir::NamedType *current = implementsClause->AsNamedType();
1109 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1110 Lexer()->NextToken();
1111
1112 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1113 ThrowSyntaxError("Identifier expected");
1114 }
1115
1116 implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1117 implementsName->SetRange(Lexer()->GetToken().Loc());
1118 auto *next = AllocNode<ir::NamedType>(implementsName);
1119 current->SetRange(Lexer()->GetToken().Loc());
1120 current->SetNext(next);
1121 current = next;
1122 Lexer()->NextToken();
1123 }
1124
1125 ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
1126 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1127 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1128 }
1129
1130 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
1131 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1132 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1133 implTypeParams = ParseTypeParameterInstantiation(&options);
1134 }
1135
1136 auto *impl = AllocNode<ir::TSClassImplements>(current, implTypeParams);
1137 impl->SetRange({implementStart, Lexer()->GetToken().End()});
1138 implements.push_back(impl);
1139
1140 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1141 Lexer()->NextToken();
1142 continue;
1143 }
1144 ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
1145 }
1146
1147 if (implements.empty()) {
1148 ThrowSyntaxError("Implements clause can not be empty");
1149 }
1150
1151 return implements;
1152 }
1153
ParseClassKeyAnnotation()1154 ir::TypeNode *ASParser::ParseClassKeyAnnotation()
1155 {
1156 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1157 Lexer()->NextToken(); // eat ':'
1158 TypeAnnotationParsingOptions options =
1159 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1160 return ParseTypeAnnotation(&options);
1161 }
1162
1163 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1164 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1165 ThrowSyntaxError("Type expected");
1166 }
1167
1168 return nullptr;
1169 }
1170
ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)1171 void ASParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1172 {
1173 if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1174 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1175 if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) {
1176 ThrowSyntaxError("'declare' modifier cannot appear on class elements of this kind");
1177 }
1178
1179 desc->classMethod = true;
1180 } else {
1181 if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1182 ThrowSyntaxError("Expected '('");
1183 }
1184 desc->classField = true;
1185
1186 if (desc->invalidComputedProperty) {
1187 ThrowSyntaxError(
1188 "Computed property name must refer to a symbol or "
1189 "literal expression whose value is "
1190 "number or string");
1191 }
1192 }
1193
1194 if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1195 desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1196 }
1197
1198 if (desc->isGenerator) {
1199 desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1200 }
1201 }
1202
ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, ir::ScriptFunction *func)1203 void ASParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1204 ir::Expression *propName, ir::ScriptFunction *func)
1205 {
1206 if (func->Params().size() != 1) {
1207 ThrowSyntaxError("Setter must have exactly one formal parameter");
1208 }
1209
1210 if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1211 ir::ModifierFlags access = GetAccessability(desc->modifiers);
1212 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1213 }
1214 }
1215
ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)1216 void ASParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1217 ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)
1218 {
1219 if ((desc->modifiers & ir::ModifierFlags::STATIC) != 0) {
1220 ir::ModifierFlags access = GetAccessability(desc->modifiers);
1221
1222 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1223 }
1224 }
1225
ParseClassStaticBlock()1226 ir::ClassElement *ASParser::ParseClassStaticBlock()
1227 {
1228 ThrowSyntaxError("Unexpected token");
1229 return nullptr;
1230 }
1231
ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)1232 void ASParser::ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)
1233 {
1234 ThrowSyntaxError("Optional properties are not supported");
1235 }
1236
ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)1237 void ASParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1238 {
1239 if (typeAnnotation == nullptr) {
1240 ThrowSyntaxError("':' expected");
1241 }
1242
1243 if (!typeAnnotation->IsNamedType()) {
1244 ThrowSyntaxError("Identifier expected");
1245 }
1246 }
1247
IsModifierKind(const lexer::Token &token)1248 bool ASParser::IsModifierKind(const lexer::Token &token)
1249 {
1250 switch (token.KeywordType()) {
1251 case lexer::TokenType::KEYW_PUBLIC:
1252 case lexer::TokenType::KEYW_PRIVATE:
1253 case lexer::TokenType::KEYW_PROTECTED:
1254 case lexer::TokenType::KEYW_STATIC:
1255 case lexer::TokenType::KEYW_ASYNC:
1256 case lexer::TokenType::KEYW_DECLARE:
1257 case lexer::TokenType::KEYW_READONLY:
1258 return true;
1259 default:
1260 break;
1261 }
1262
1263 return false;
1264 }
1265
ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc, [[maybe_unused]] char32_t *nextCp)1266 void ASParser::ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc,
1267 [[maybe_unused]] char32_t *nextCp)
1268 {
1269 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1270 ThrowSyntaxError("Invalid character");
1271 }
1272 }
1273
ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)1274 std::tuple<bool, bool, bool> ASParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1275 {
1276 Lexer()->NextToken(); // eat left square bracket
1277
1278 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1279 Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1280 if (!Lexer()->GetToken().Ident().Is("key")) {
1281 ThrowSyntaxError("'key' expected.");
1282 }
1283
1284 auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1285 id->SetRange(Lexer()->GetToken().Loc());
1286
1287 Lexer()->NextToken(); // eat param
1288
1289 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1290 ThrowSyntaxError("':' expected");
1291 }
1292
1293 Lexer()->NextToken(); // eat ':'
1294 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1295 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1296
1297 if (!typeAnnotation->IsNamedType()) {
1298 ThrowSyntaxError("Type expected");
1299 }
1300
1301 id->SetTsTypeAnnotation(typeAnnotation);
1302 *propName = id;
1303
1304 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1305 ThrowSyntaxError("']' expected");
1306 }
1307
1308 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1309
1310 return {false, false, true};
1311 }
1312
1313 *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1314
1315 bool invalidComputedProperty =
1316 !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
1317 !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
1318 (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
1319
1320 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1321 ThrowSyntaxError("Unexpected token, expected ']'");
1322 }
1323
1324 return {true, invalidComputedProperty, false};
1325 }
1326
ParseFunctionBody( [[maybe_unused]] const ArenaVector<ir::Expression *> ¶ms, [[maybe_unused]] ParserStatus newStatus, ParserStatus contextStatus)1327 std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> ASParser::ParseFunctionBody(
1328 [[maybe_unused]] const ArenaVector<ir::Expression *> ¶ms, [[maybe_unused]] ParserStatus newStatus,
1329 ParserStatus contextStatus)
1330 {
1331 bool isDeclare = InAmbientContext();
1332 bool isOverload = false;
1333 bool letDeclare = true;
1334 ir::BlockStatement *body = nullptr;
1335 lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1336
1337 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1338 if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
1339 ThrowSyntaxError("Unexpected token, expected '{'");
1340 } else {
1341 letDeclare = false;
1342 }
1343
1344 isOverload = true;
1345 } else if (isDeclare) {
1346 ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
1347 } else {
1348 body = ParseBlockStatement();
1349 endLoc = body->End();
1350 }
1351
1352 return {letDeclare, body, endLoc, isOverload};
1353 }
1354
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)1355 ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1356 {
1357 ir::Identifier *local = ParseNamedImport(Lexer()->GetToken());
1358 Lexer()->NextToken(); // eat local name
1359
1360 auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1361 specifier->SetRange(specifier->Local()->Range());
1362 specifiers->push_back(specifier);
1363
1364 return nullptr;
1365 }
1366
ParseArrowFunctionRestParameter(lexer::SourcePosition start)1367 ir::Expression *ASParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
1368 {
1369 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1370
1371 restElement->SetGrouped();
1372 restElement->SetStart(start);
1373
1374 ValidateArrowFunctionRestParameter(restElement);
1375
1376 Lexer()->NextToken();
1377
1378 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1379 ThrowSyntaxError(":' expected");
1380 }
1381
1382 Lexer()->NextToken(); // eat ':'
1383
1384 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1385 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1386
1387 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1388 ThrowSyntaxError("'=>' expected");
1389 }
1390
1391 return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
1392 }
1393
ParseArrowFunctionNoParameter(lexer::SourcePosition start)1394 ir::Expression *ASParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
1395 {
1396 Lexer()->NextToken();
1397
1398 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1399 ThrowSyntaxError(":' expected");
1400 }
1401
1402 Lexer()->NextToken(); // eat ':'
1403
1404 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1405 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1406
1407 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1408 ThrowSyntaxError("'=>' expected");
1409 }
1410
1411 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
1412 arrowExpr->SetStart(start);
1413 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
1414
1415 return arrowExpr;
1416 }
1417
1418 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList( [[maybe_unused]] ExpressionParseFlags flags)1419 ir::Expression *ASParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
1420 [[maybe_unused]] ExpressionParseFlags flags)
1421 {
1422 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1423 lexer::SourcePosition start = Lexer()->GetToken().Start();
1424 Lexer()->NextToken();
1425 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1426
1427 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1428 return ParseArrowFunctionRestParameter(start);
1429 }
1430
1431 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1432 return ParseArrowFunctionNoParameter(start);
1433 }
1434
1435 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
1436 ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
1437
1438 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1439 ThrowSyntaxError("')' expected");
1440 }
1441
1442 expr->SetGrouped();
1443 expr->SetRange({start, Lexer()->GetToken().End()});
1444 Lexer()->NextToken();
1445
1446 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1447 ThrowSyntaxError("':' expected.");
1448 }
1449
1450 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1451 auto savedPos = Lexer()->Save();
1452 Lexer()->NextToken(); // eat ':'
1453 options = TypeAnnotationParsingOptions::NO_OPTS;
1454 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1455
1456 if (returnTypeAnnotation == nullptr) {
1457 Lexer()->Rewind(savedPos);
1458 return expr;
1459 }
1460
1461 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1462 Lexer()->Rewind(savedPos);
1463 return expr;
1464 }
1465
1466 return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
1467 }
1468
1469 return expr;
1470 }
1471
ParsePrefixAssertionExpression()1472 ir::Expression *ASParser::ParsePrefixAssertionExpression()
1473 {
1474 lexer::SourcePosition startPos = Lexer()->GetToken().Start();
1475 Lexer()->NextToken(); // eat <
1476 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1477 ir::TypeNode *type = ParseTypeAnnotation(&options);
1478
1479 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1480 ThrowSyntaxError("'>' expected");
1481 }
1482
1483 Lexer()->NextToken(); // eat >
1484
1485 ir::Expression *expr = ParseExpression();
1486
1487 auto *node = AllocNode<ir::PrefixAssertionExpression>(expr, type);
1488 node->SetRange({startPos, Lexer()->GetToken().End()});
1489 return node;
1490 }
1491
ParseConstStatement(StatementParsingFlags flags)1492 ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags)
1493 {
1494 lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
1495 Lexer()->NextToken();
1496
1497 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1498 return ParseEnumDeclaration(true);
1499 }
1500
1501 if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
1502 ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
1503 }
1504
1505 auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
1506 variableDecl->SetStart(constVarStar);
1507 ConsumeSemicolon(variableDecl);
1508
1509 return variableDecl;
1510 }
1511
ParseVariableDeclaratorKey(VariableParsingFlags flags)1512 ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
1513 {
1514 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1515 ThrowSyntaxError("Identifier expected");
1516 }
1517
1518 ValidateDeclaratorId();
1519
1520 const util::StringView &identStr = Lexer()->GetToken().Ident();
1521 auto init = AllocNode<ir::Identifier>(identStr, Allocator());
1522 init->SetRange(Lexer()->GetToken().Loc());
1523 Lexer()->NextToken();
1524
1525 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1526 Lexer()->NextToken(); // eat ':'
1527 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1528 init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1529 } else if (((flags & VariableParsingFlags::IN_FOR) == 0) &&
1530 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1531 ThrowSyntaxError("Type expected");
1532 }
1533
1534 return init;
1535 }
1536
ParsePotentialConstEnum(VariableParsingFlags flags)1537 ir::Statement *ASParser::ParsePotentialConstEnum(VariableParsingFlags flags)
1538 {
1539 if ((flags & VariableParsingFlags::CONST) == 0) {
1540 ThrowSyntaxError("Variable declaration expected.");
1541 }
1542
1543 return ParseEnumDeclaration(true);
1544 }
1545
1546 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc, bool isExportEquals)1547 ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1548 bool isExportEquals)
1549 {
1550 Lexer()->NextToken(); // eat `default` keyword or `=`
1551
1552 ir::AstNode *declNode = nullptr;
1553 bool eatSemicolon = false;
1554
1555 switch (Lexer()->GetToken().Type()) {
1556 case lexer::TokenType::KEYW_FUNCTION: {
1557 declNode = ParseFunctionDeclaration(true);
1558 break;
1559 }
1560 case lexer::TokenType::KEYW_CLASS: {
1561 declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1562 break;
1563 }
1564 case lexer::TokenType::KEYW_INTERFACE: {
1565 declNode = ParseInterfaceDeclaration(false);
1566 break;
1567 }
1568 case lexer::TokenType::KEYW_NAMESPACE: {
1569 Lexer()->NextToken(); // eat 'namespace'
1570 declNode = ParseModuleOrNamespaceDeclaration(startLoc);
1571 break;
1572 }
1573 case lexer::TokenType::KEYW_ENUM: {
1574 declNode = ParseEnumDeclaration();
1575 break;
1576 }
1577 case lexer::TokenType::KEYW_ASYNC: {
1578 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1579 Lexer()->NextToken(); // eat `async`
1580 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1581 break;
1582 }
1583
1584 [[fallthrough]];
1585 }
1586 default: {
1587 declNode = ParseExpression();
1588 eatSemicolon = true;
1589 break;
1590 }
1591 }
1592
1593 lexer::SourcePosition endLoc = declNode->End();
1594 auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1595 exportDeclaration->SetRange({startLoc, endLoc});
1596
1597 if (eatSemicolon) {
1598 ConsumeSemicolon(exportDeclaration);
1599 }
1600
1601 return exportDeclaration;
1602 }
1603
1604 class ASParser::ParseNamedExportDeclarationHelper {
1605 friend ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc);
1606
1607 private:
GetParsedDeclaration(ASParser *parser, lexer::TokenType type)1608 static ir::Statement *GetParsedDeclaration(ASParser *parser, lexer::TokenType type)
1609 {
1610 ir::ModifierFlags flags = ir::ModifierFlags::NONE;
1611 if (parser->Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1612 parser->Lexer()->NextToken(); // eat 'abstract'
1613 flags = ir::ModifierFlags::ABSTRACT;
1614 }
1615
1616 switch (type) {
1617 case lexer::TokenType::KEYW_VAR: {
1618 return parser->ParseVariableDeclaration(VariableParsingFlags::VAR);
1619 }
1620 case lexer::TokenType::KEYW_CONST: {
1621 return parser->ParseVariableDeclaration(VariableParsingFlags::CONST);
1622 }
1623 case lexer::TokenType::KEYW_LET: {
1624 return parser->ParseVariableDeclaration(VariableParsingFlags::LET);
1625 }
1626 case lexer::TokenType::KEYW_FUNCTION: {
1627 return parser->ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1628 }
1629 case lexer::TokenType::KEYW_CLASS: {
1630 return parser->ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED, flags);
1631 }
1632 case lexer::TokenType::KEYW_ENUM: {
1633 return parser->ParseEnumDeclaration();
1634 }
1635 case lexer::TokenType::KEYW_INTERFACE: {
1636 return parser->ParseInterfaceDeclaration(false);
1637 }
1638 case lexer::TokenType::KEYW_TYPE: {
1639 return parser->ParseTypeAliasDeclaration();
1640 }
1641 case lexer::TokenType::KEYW_GLOBAL:
1642 case lexer::TokenType::KEYW_MODULE:
1643 case lexer::TokenType::KEYW_NAMESPACE: {
1644 return parser->ParseModuleDeclaration();
1645 }
1646 default: {
1647 parser->ExpectToken(lexer::TokenType::KEYW_ASYNC);
1648 return parser->ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1649 }
1650 }
1651 }
1652 };
1653
ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)1654 ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1655 {
1656 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1657 CheckDeclare();
1658 }
1659
1660 ir::Statement *decl =
1661 ParseNamedExportDeclarationHelper::GetParsedDeclaration(this, Lexer()->GetToken().KeywordType());
1662
1663 if (decl->IsVariableDeclaration()) {
1664 ConsumeSemicolon(decl);
1665 }
1666
1667 ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1668 auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1669 exportDeclaration->SetRange({startLoc, decl->End()});
1670
1671 return exportDeclaration;
1672 }
1673
ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)1674 ir::AstNode *ASParser::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1675 {
1676 ASSERT(specifiers->empty());
1677
1678 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1679 ParseImportDefaultSpecifier(specifiers);
1680 return nullptr;
1681 }
1682
1683 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1684 ParseNameSpaceImport(specifiers);
1685 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1686 ParseNamedImportSpecifiers(specifiers);
1687 }
1688
1689 return nullptr;
1690 }
1691
ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)1692 ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
1693 {
1694 char32_t nextChar = Lexer()->Lookahead();
1695 if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
1696 return ParseExpressionStatement();
1697 }
1698
1699 lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1700 Lexer()->NextToken(); // eat import
1701
1702 ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
1703
1704 ir::StringLiteral *source = nullptr;
1705
1706 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1707 ParseImportSpecifiers(&specifiers);
1708 source = ParseFromClause(true);
1709 } else {
1710 source = ParseFromClause(false);
1711 }
1712
1713 lexer::SourcePosition endLoc = source->End();
1714 auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
1715 importDeclaration->SetRange({startLoc, endLoc});
1716
1717 ConsumeSemicolon(importDeclaration);
1718
1719 return importDeclaration;
1720 }
1721
ThrowIllegalBreakError()1722 void ASParser::ThrowIllegalBreakError()
1723 {
1724 ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement");
1725 }
1726
ThrowIllegalContinueError()1727 void ASParser::ThrowIllegalContinueError()
1728 {
1729 ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
1730 }
1731
1732 } // namespace ark::es2panda::parser
1733