1 /**
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "TSparser.h"
17
18 #include "parserFlags.h"
19 #include "util/helpers.h"
20 #include "varbinder/privateBinding.h"
21 #include "varbinder/scope.h"
22 #include "varbinder/tsBinding.h"
23 #include "lexer/TSLexer.h"
24 #include "ir/base/spreadElement.h"
25 #include "ir/base/decorator.h"
26 #include "ir/base/classElement.h"
27 #include "ir/base/classDefinition.h"
28 #include "ir/base/methodDefinition.h"
29 #include "ir/base/scriptFunction.h"
30 #include "ir/module/importDefaultSpecifier.h"
31 #include "ir/module/exportDefaultDeclaration.h"
32 #include "ir/module/exportAllDeclaration.h"
33 #include "ir/module/exportNamedDeclaration.h"
34 #include "ir/module/importDeclaration.h"
35 #include "ir/expressions/memberExpression.h"
36 #include "ir/expressions/sequenceExpression.h"
37 #include "ir/expressions/templateLiteral.h"
38 #include "ir/expressions/taggedTemplateExpression.h"
39 #include "ir/expressions/callExpression.h"
40 #include "ir/expressions/functionExpression.h"
41 #include "ir/expressions/arrowFunctionExpression.h"
42 #include "ir/expressions/yieldExpression.h"
43 #include "ir/expressions/assignmentExpression.h"
44 #include "ir/expressions/identifier.h"
45 #include "ir/expressions/objectExpression.h"
46 #include "ir/expressions/arrayExpression.h"
47 #include "ir/expressions/literals/bigIntLiteral.h"
48 #include "ir/expressions/literals/booleanLiteral.h"
49 #include "ir/expressions/literals/nullLiteral.h"
50 #include "ir/expressions/literals/numberLiteral.h"
51 #include "ir/expressions/literals/stringLiteral.h"
52 #include "ir/statements/emptyStatement.h"
53 #include "ir/statements/blockStatement.h"
54 #include "ir/statements/ifStatement.h"
55 #include "ir/statements/doWhileStatement.h"
56 #include "ir/statements/whileStatement.h"
57 #include "ir/statements/tryStatement.h"
58 #include "ir/statements/breakStatement.h"
59 #include "ir/statements/continueStatement.h"
60 #include "ir/statements/throwStatement.h"
61 #include "ir/statements/switchStatement.h"
62 #include "ir/statements/returnStatement.h"
63 #include "ir/statements/debuggerStatement.h"
64 #include "ir/statements/classDeclaration.h"
65 #include "ir/statements/labelledStatement.h"
66 #include "ir/statements/variableDeclarator.h"
67 #include "ir/statements/functionDeclaration.h"
68 #include "ir/ts/tsLiteralType.h"
69 #include "ir/ts/tsMappedType.h"
70 #include "ir/ts/tsImportType.h"
71 #include "ir/ts/tsThisType.h"
72 #include "ir/ts/tsConditionalType.h"
73 #include "ir/ts/tsTypeOperator.h"
74 #include "ir/ts/tsInferType.h"
75 #include "ir/ts/tsTupleType.h"
76 #include "ir/ts/tsNamedTupleMember.h"
77 #include "ir/ts/tsQualifiedName.h"
78 #include "ir/ts/tsIndexedAccessType.h"
79 #include "ir/ts/tsTypeQuery.h"
80 #include "ir/ts/tsTypeReference.h"
81 #include "ir/ts/tsTypePredicate.h"
82 #include "ir/ts/tsTypeLiteral.h"
83 #include "ir/ts/tsArrayType.h"
84 #include "ir/ts/tsUnionType.h"
85 #include "ir/ts/tsIntersectionType.h"
86 #include "ir/ts/tsAnyKeyword.h"
87 #include "ir/ts/tsUndefinedKeyword.h"
88 #include "ir/ts/tsVoidKeyword.h"
89 #include "ir/ts/tsNumberKeyword.h"
90 #include "ir/ts/tsStringKeyword.h"
91 #include "ir/ts/tsBooleanKeyword.h"
92 #include "ir/ts/tsBigintKeyword.h"
93 #include "ir/ts/tsUnknownKeyword.h"
94 #include "ir/ts/tsNullKeyword.h"
95 #include "ir/ts/tsNeverKeyword.h"
96 #include "ir/ts/tsObjectKeyword.h"
97 #include "ir/ts/tsFunctionType.h"
98 #include "ir/ts/tsConstructorType.h"
99 #include "ir/ts/tsParenthesizedType.h"
100 #include "ir/ts/tsTypeAssertion.h"
101 #include "ir/ts/tsAsExpression.h"
102 #include "ir/ts/tsNonNullExpression.h"
103 #include "ir/ts/tsEnumDeclaration.h"
104 #include "ir/ts/tsInterfaceDeclaration.h"
105 #include "ir/ts/tsTypeAliasDeclaration.h"
106 #include "ir/ts/tsModuleDeclaration.h"
107 #include "ir/ts/tsTypeParameterInstantiation.h"
108 #include "ir/ts/tsInterfaceHeritage.h"
109 #include "ir/base/tsSignatureDeclaration.h"
110 #include "ir/base/tsIndexSignature.h"
111 #include "ir/base/tsMethodSignature.h"
112 #include "ir/base/tsPropertySignature.h"
113 #include "ir/ts/tsParameterProperty.h"
114 #include "ir/ts/tsClassImplements.h"
115 #include "ir/ts/tsImportEqualsDeclaration.h"
116 #include "ir/ts/tsExternalModuleReference.h"
117
118 namespace ark::es2panda::parser {
ParsePotentialAsExpression(ir::Expression * expr)119 ir::Expression *TSParser::ParsePotentialAsExpression(ir::Expression *expr)
120 {
121 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
122 return nullptr;
123 }
124
125 Lexer()->NextToken(); // eat 'as'
126 TypeAnnotationParsingOptions options =
127 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ALLOW_CONST;
128 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
129
130 bool isConst = false;
131 if (typeAnnotation->IsTSTypeReference() && typeAnnotation->AsTSTypeReference()->TypeName()->IsIdentifier()) {
132 const util::StringView &refName = typeAnnotation->AsTSTypeReference()->TypeName()->AsIdentifier()->Name();
133 if (refName.Is("const")) {
134 isConst = true;
135 }
136 }
137
138 lexer::SourcePosition startLoc = expr->Start();
139 auto *asExpr = AllocNode<ir::TSAsExpression>(expr, typeAnnotation, isConst);
140 asExpr->SetRange({startLoc, Lexer()->GetToken().End()});
141
142 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) {
143 return ParsePotentialAsExpression(asExpr);
144 }
145
146 return asExpr;
147 }
148
ParsePatternElementGetReturnNode(ExpressionParseFlags & flags,bool & isOptional)149 ir::AnnotatedExpression *TSParser::ParsePatternElementGetReturnNode(ExpressionParseFlags &flags, bool &isOptional)
150 {
151 switch (Lexer()->GetToken().Type()) {
152 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
153 ir::AnnotatedExpression *returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
154 isOptional = returnNode->AsArrayPattern()->IsOptional();
155 return returnNode;
156 }
157 case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
158 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
159 ThrowSyntaxError("Unexpected token");
160 }
161
162 return ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
163 }
164 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
165 ir::AnnotatedExpression *returnNode =
166 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
167 isOptional = returnNode->AsObjectPattern()->IsOptional();
168 return returnNode;
169 }
170 case lexer::TokenType::LITERAL_IDENT: {
171 ir::AnnotatedExpression *returnNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
172
173 if (returnNode->AsIdentifier()->Decorators().empty()) {
174 returnNode->SetRange(Lexer()->GetToken().Loc());
175 } else {
176 returnNode->SetRange(
177 {returnNode->AsIdentifier()->Decorators().front()->Start(), Lexer()->GetToken().End()});
178 }
179
180 Lexer()->NextToken();
181
182 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
183 isOptional = true;
184
185 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
186 ThrowSyntaxError("A rest parameter cannot be optional");
187 }
188
189 returnNode->AsIdentifier()->SetOptional(true);
190 Lexer()->NextToken();
191 }
192
193 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
194 Lexer()->NextToken(); // eat ':'
195 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
196 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
197 }
198 return returnNode;
199 }
200 default: {
201 ThrowSyntaxError("Unexpected token, expected an identifier.");
202 }
203 }
204 }
205 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault)206 ir::Expression *TSParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
207 {
208 bool isOptional = false;
209 ir::AnnotatedExpression *returnNode = ParsePatternElementGetReturnNode(flags, isOptional);
210
211 if ((returnNode->IsObjectPattern() || returnNode->IsArrayPattern()) && !InAmbientContext() &&
212 ((GetContext().Status() & ParserStatus::FUNCTION) != 0) && isOptional) {
213 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.");
214 }
215
216 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
217 return returnNode;
218 }
219
220 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
221 ThrowSyntaxError("A rest parameter cannot have an initializer.");
222 }
223
224 if (!allowDefault) {
225 ThrowSyntaxError("Invalid destructuring assignment target");
226 }
227
228 if (isOptional) {
229 ThrowSyntaxError("Parameter cannot have question mark and initializer");
230 }
231
232 Lexer()->NextToken();
233
234 if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) &&
235 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
236 ThrowSyntaxError("Yield is not allowed in generator parameters");
237 }
238
239 ir::Expression *rightNode = ParseExpression();
240
241 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
242 ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
243 assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
244
245 return assignmentExpression;
246 }
247
CreateParameterProperty(ir::Expression * parameter,ir::ModifierFlags modifiers)248 ir::TSParameterProperty *TSParser::CreateParameterProperty(ir::Expression *parameter, ir::ModifierFlags modifiers)
249 {
250 auto accessibilityOption = ir::AccessibilityOption::NO_OPTS;
251 bool readonly = false;
252 bool isStatic = false;
253 bool isExport = false;
254
255 if ((modifiers & ir::ModifierFlags::PRIVATE) != 0) {
256 accessibilityOption = ir::AccessibilityOption::PRIVATE;
257 } else if ((modifiers & ir::ModifierFlags::PUBLIC) != 0) {
258 accessibilityOption = ir::AccessibilityOption::PUBLIC;
259 } else if ((modifiers & ir::ModifierFlags::PROTECTED) != 0) {
260 accessibilityOption = ir::AccessibilityOption::PROTECTED;
261 }
262
263 if ((modifiers & ir::ModifierFlags::READONLY) != 0) {
264 readonly = true;
265 }
266
267 if ((modifiers & ir::ModifierFlags::STATIC) != 0) {
268 isStatic = true;
269 }
270
271 // NOTE(Csaba Repasi): Handle export property of TSParameterProperty
272
273 return AllocNode<ir::TSParameterProperty>(accessibilityOption, parameter, readonly, isStatic, isExport);
274 }
275
ParseFunctionParameter()276 ir::Expression *TSParser::ParseFunctionParameter()
277 {
278 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS) {
279 Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
280 Lexer()->GetToken().SetTokenStr(ERROR_LITERAL);
281 }
282
283 lexer::SourcePosition parameterStart = Lexer()->GetToken().Start();
284 ir::ModifierFlags modifiers = ParseModifiers();
285 // NOTE(Csaba Repasi): throw error if using strick mode reserved keyword here
286 if (((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) == 0) && modifiers != ir::ModifierFlags::NONE) {
287 ThrowSyntaxError("A parameter property is only allowed in a constructor implementation.", parameterStart);
288 }
289
290 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
291 CheckRestrictedBinding();
292 }
293
294 ir::Expression *functionParameter = ParsePatternElement(ExpressionParseFlags::NO_OPTS, true);
295
296 if (modifiers != ir::ModifierFlags::NONE && functionParameter->IsRestElement()) {
297 ThrowSyntaxError("A parameter property cannot be declared using a rest parameter.", parameterStart);
298 }
299
300 if (modifiers != ir::ModifierFlags::NONE &&
301 (functionParameter->IsArrayPattern() || functionParameter->IsObjectPattern() ||
302 (functionParameter->IsAssignmentPattern() &&
303 (functionParameter->AsAssignmentPattern()->Left()->IsArrayPattern() ||
304 functionParameter->AsAssignmentPattern()->Left()->IsObjectPattern())))) {
305 ThrowSyntaxError("A parameter property may not be declared using a binding pattern.", parameterStart);
306 }
307
308 if (modifiers != ir::ModifierFlags::NONE) {
309 functionParameter = CreateParameterProperty(functionParameter, modifiers);
310 functionParameter->SetRange({parameterStart, functionParameter->AsTSParameterProperty()->Parameter()->End()});
311 }
312
313 return functionParameter;
314 }
315
ParseModuleReference()316 ir::Expression *TSParser::ParseModuleReference()
317 {
318 ir::Expression *result = nullptr;
319
320 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_REQUIRE &&
321 Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN) {
322 lexer::SourcePosition start = Lexer()->GetToken().Start();
323 Lexer()->NextToken(); // eat 'require'
324 Lexer()->NextToken(); // eat '('
325
326 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
327 ThrowSyntaxError("String literal expected.");
328 }
329
330 result = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
331 result->SetRange(Lexer()->GetToken().Loc());
332 Lexer()->NextToken();
333
334 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
335 ThrowSyntaxError("')' expected.");
336 }
337
338 result = AllocNode<ir::TSExternalModuleReference>(result);
339 result->SetRange({start, Lexer()->GetToken().End()});
340 Lexer()->NextToken(); // eat ')'
341 } else {
342 result = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
343 result->SetRange(Lexer()->GetToken().Loc());
344 Lexer()->NextToken();
345
346 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
347 result = ParseQualifiedReference(result);
348 }
349 }
350
351 return result;
352 }
353
ParseConstExpression()354 ir::TSTypeReference *TSParser::ParseConstExpression()
355 {
356 auto *identRef = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
357 identRef->SetRange(Lexer()->GetToken().Loc());
358
359 auto *typeReference = AllocNode<ir::TSTypeReference>(identRef, nullptr);
360 typeReference->SetRange(Lexer()->GetToken().Loc());
361
362 Lexer()->NextToken();
363
364 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
365 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
366 Lexer()->GetToken().Type() != lexer::TokenType::EOS &&
367 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET &&
368 ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) == 0)) {
369 ThrowSyntaxError("Unexpected token.");
370 }
371
372 return typeReference;
373 }
374
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)375 bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
376 {
377 if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
378 return true;
379 }
380
381 *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
382 (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
383 Lexer()->NextToken();
384 return false;
385 }
386
387 // NOLINTNEXTLINE(google-default-arguments)
ParseObjectExpression(ExpressionParseFlags flags)388 ir::ObjectExpression *TSParser::ParseObjectExpression(ExpressionParseFlags flags)
389 {
390 ir::ObjectExpression *objExpression = ParserImpl::ParseObjectExpression(flags);
391 ParsePotentialOptionalFunctionParameter(objExpression);
392 return objExpression;
393 }
394
395 // NOLINTNEXTLINE(google-default-arguments)
ParseArrayExpression(ExpressionParseFlags flags)396 ir::ArrayExpression *TSParser::ParseArrayExpression(ExpressionParseFlags flags)
397 {
398 ir::ArrayExpression *arrayExpression = ParserImpl::ParseArrayExpression(flags);
399 ParsePotentialOptionalFunctionParameter(arrayExpression);
400 return arrayExpression;
401 }
402 class TSParser::ParsePotentialArrowExpressionHelper {
403 friend ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression,
404 const lexer::SourcePosition &startLoc);
405
406 private:
CreateCallExpression(TSParser * parser,lexer::Lexer * lexer,ir::Expression ** returnExpression,ir::TSTypeParameterDeclaration * typeParamDecl,const lexer::SourcePosition & startLoc)407 static ir::ArrowFunctionExpression *CreateCallExpression(TSParser *parser, lexer::Lexer *lexer,
408 ir::Expression **returnExpression,
409 ir::TSTypeParameterDeclaration *typeParamDecl,
410 const lexer::SourcePosition &startLoc)
411 {
412 ir::CallExpression *callExpression = parser->ParseCallExpression(*returnExpression, false);
413
414 ir::TypeNode *returnTypeAnnotation = nullptr;
415 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
416 lexer->NextToken(); // eat ':'
417 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
418 returnTypeAnnotation = parser->ParseTypeAnnotation(&options);
419 }
420
421 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
422 ir::ArrowFunctionExpression *arrowFuncExpr =
423 parser->ParseArrowFunctionExpression(callExpression, typeParamDecl, returnTypeAnnotation, true);
424 arrowFuncExpr->SetStart(startLoc);
425
426 return arrowFuncExpr;
427 }
428
429 if (returnTypeAnnotation != nullptr || typeParamDecl != nullptr) {
430 parser->ThrowSyntaxError("'=>' expected");
431 }
432
433 *returnExpression = callExpression;
434 return nullptr;
435 }
436 };
437
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)438 ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression,
439 const lexer::SourcePosition &startLoc)
440 {
441 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
442
443 switch (Lexer()->GetToken().Type()) {
444 case lexer::TokenType::KEYW_FUNCTION: {
445 *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
446 (*returnExpression)->SetStart(startLoc);
447 break;
448 }
449 case lexer::TokenType::LITERAL_IDENT: {
450 ir::Expression *identRef = ParsePrimaryExpression();
451 if (identRef == nullptr) {
452 return nullptr;
453 }
454 ASSERT(identRef->IsIdentifier());
455
456 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
457 ThrowSyntaxError("Unexpected token, expected '=>'");
458 }
459
460 ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
461 arrowFuncExpr->SetStart(startLoc);
462
463 return arrowFuncExpr;
464 }
465 case lexer::TokenType::PUNCTUATOR_ARROW: {
466 ir::ArrowFunctionExpression *arrowFuncExpr =
467 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
468 arrowFuncExpr->SetStart(startLoc);
469 return arrowFuncExpr;
470 }
471 case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
472 const auto savedPos = Lexer()->Save();
473
474 auto options = TypeAnnotationParsingOptions::NO_OPTS;
475 typeParamDecl = ParseTypeParameterDeclaration(&options);
476 if (typeParamDecl == nullptr) {
477 Lexer()->Rewind(savedPos);
478 return nullptr;
479 }
480
481 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
482 ThrowSyntaxError("'(' expected");
483 }
484
485 [[fallthrough]];
486 }
487 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
488 return ParsePotentialArrowExpressionHelper::CreateCallExpression(this, Lexer(), returnExpression,
489 typeParamDecl, startLoc);
490 }
491 default: {
492 break;
493 }
494 }
495
496 return nullptr;
497 }
498
ParseVariableDeclaratorKey(VariableParsingFlags flags)499 ir::AnnotatedExpression *TSParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
500 {
501 ir::AnnotatedExpression *init = ParserImpl::ParseVariableDeclaratorKey(flags);
502
503 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
504 Lexer()->NextToken(); // eat ':'
505 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
506 init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
507 }
508
509 return init;
510 }
511
ParseOptionalFunctionParameter(ir::AnnotatedExpression * returnNode,bool isRest)512 void TSParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool isRest)
513 {
514 bool isOptional = false;
515
516 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
517 if (isRest) {
518 ThrowSyntaxError("A rest parameter cannot be optional");
519 }
520
521 switch (returnNode->Type()) {
522 case ir::AstNodeType::IDENTIFIER: {
523 returnNode->AsIdentifier()->SetOptional(true);
524 break;
525 }
526 case ir::AstNodeType::OBJECT_PATTERN:
527 case ir::AstNodeType::ARRAY_PATTERN: {
528 if (!InAmbientContext() && ((GetContext().Status() & ParserStatus::FUNCTION) != 0)) {
529 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.");
530 }
531
532 if (returnNode->IsObjectPattern()) {
533 returnNode->AsObjectPattern()->SetOptional(true);
534 break;
535 }
536
537 returnNode->AsArrayPattern()->SetOptional(true);
538 break;
539 }
540 case ir::AstNodeType::REST_ELEMENT: {
541 returnNode->AsRestElement()->SetOptional(true);
542 break;
543 }
544 default: {
545 UNREACHABLE();
546 }
547 }
548
549 isOptional = true;
550 Lexer()->NextToken(); // eat '?'
551 }
552
553 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
554 Lexer()->NextToken(); // eat ':'
555 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
556 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
557 }
558
559 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
560 return;
561 }
562
563 if (isRest) {
564 ThrowSyntaxError("A rest parameter cannot have an initializer");
565 }
566
567 if (returnNode->IsIdentifier() && isOptional) {
568 ThrowSyntaxError("Parameter cannot have question mark and initializer");
569 }
570 }
571
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)572 bool TSParser::ValidateArrowFunctionRestParameter(ir::SpreadElement *restElement)
573 {
574 ParseOptionalFunctionParameter(restElement, true);
575
576 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
577 ThrowSyntaxError("')' expected");
578 }
579
580 return true;
581 }
582
ParseArrowFunctionRestParameter(lexer::SourcePosition start)583 ir::Expression *TSParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
584 {
585 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
586
587 restElement->SetGrouped();
588 restElement->SetStart(start);
589
590 ValidateArrowFunctionRestParameter(restElement);
591
592 Lexer()->NextToken();
593
594 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
595 ir::TypeNode *returnTypeAnnotation = nullptr;
596 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
597 Lexer()->NextToken(); // eat ':'
598 returnTypeAnnotation = ParseTypeAnnotation(&options);
599 }
600
601 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
602 ThrowSyntaxError("Unexpected token");
603 }
604
605 return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
606 }
607
ParseArrowFunctionNoParameter(lexer::SourcePosition start)608 ir::Expression *TSParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
609 {
610 Lexer()->NextToken();
611
612 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
613 ir::TypeNode *returnTypeAnnotation = nullptr;
614 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
615 Lexer()->NextToken(); // eat ':'
616 returnTypeAnnotation = ParseTypeAnnotation(&options);
617 }
618
619 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
620 ThrowSyntaxError("Unexpected token");
621 }
622
623 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
624 arrowExpr->SetStart(start);
625 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
626
627 return arrowExpr;
628 }
629
630 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)631 ir::Expression *TSParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
632 [[maybe_unused]] ExpressionParseFlags flags) // CC-OFF(G.FMT.06-CPP) project code style
633 {
634 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
635 lexer::SourcePosition start = Lexer()->GetToken().Start();
636 Lexer()->NextToken();
637 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
638
639 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
640 return ParseArrowFunctionRestParameter(start);
641 }
642
643 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
644 return ParseArrowFunctionNoParameter(start);
645 }
646
647 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
648 ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
649
650 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
651 ThrowSyntaxError("Unexpected token, expected ')'");
652 }
653
654 expr->SetGrouped();
655 expr->SetRange({start, Lexer()->GetToken().End()});
656 Lexer()->NextToken();
657
658 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
659 auto savedPos = Lexer()->Save();
660 Lexer()->NextToken(); // eat ':'
661 options = TypeAnnotationParsingOptions::NO_OPTS;
662 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
663
664 if (returnTypeAnnotation == nullptr) {
665 Lexer()->Rewind(savedPos);
666 return expr;
667 }
668
669 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
670 Lexer()->Rewind(savedPos);
671 return expr;
672 }
673
674 return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
675 }
676
677 return expr;
678 }
679
680 } // namespace ark::es2panda::parser
681