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::THROW_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 returnNode->AsIdentifier()->SetReference();
173
174 if (returnNode->AsIdentifier()->Decorators().empty()) {
175 returnNode->SetRange(Lexer()->GetToken().Loc());
176 } else {
177 returnNode->SetRange(
178 {returnNode->AsIdentifier()->Decorators().front()->Start(), Lexer()->GetToken().End()});
179 }
180
181 Lexer()->NextToken();
182
183 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
184 isOptional = true;
185
186 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
187 ThrowSyntaxError("A rest parameter cannot be optional");
188 }
189
190 returnNode->AsIdentifier()->SetOptional(true);
191 Lexer()->NextToken();
192 }
193
194 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
195 Lexer()->NextToken(); // eat ':'
196 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
197 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
198 }
199 return returnNode;
200 }
201 default: {
202 ThrowSyntaxError("Unexpected token, expected an identifier.");
203 }
204 }
205 }
206 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault)207 ir::Expression *TSParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
208 {
209 bool isOptional = false;
210 ir::AnnotatedExpression *returnNode = ParsePatternElementGetReturnNode(flags, isOptional);
211
212 if ((returnNode->IsObjectPattern() || returnNode->IsArrayPattern()) && !InAmbientContext() &&
213 ((GetContext().Status() & ParserStatus::FUNCTION) != 0) && isOptional) {
214 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.");
215 }
216
217 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
218 return returnNode;
219 }
220
221 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
222 ThrowSyntaxError("A rest parameter cannot have an initializer.");
223 }
224
225 if (!allowDefault) {
226 ThrowSyntaxError("Invalid destructuring assignment target");
227 }
228
229 if (isOptional) {
230 ThrowSyntaxError("Parameter cannot have question mark and initializer");
231 }
232
233 Lexer()->NextToken();
234
235 if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) &&
236 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
237 ThrowSyntaxError("Yield is not allowed in generator parameters");
238 }
239
240 ir::Expression *rightNode = ParseExpression();
241
242 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
243 ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
244 assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
245
246 return assignmentExpression;
247 }
248
CreateParameterProperty(ir::Expression * parameter,ir::ModifierFlags modifiers)249 ir::TSParameterProperty *TSParser::CreateParameterProperty(ir::Expression *parameter, ir::ModifierFlags modifiers)
250 {
251 auto accessibilityOption = ir::AccessibilityOption::NO_OPTS;
252 bool readonly = false;
253 bool isStatic = false;
254 bool isExport = false;
255
256 if ((modifiers & ir::ModifierFlags::PRIVATE) != 0) {
257 accessibilityOption = ir::AccessibilityOption::PRIVATE;
258 } else if ((modifiers & ir::ModifierFlags::PUBLIC) != 0) {
259 accessibilityOption = ir::AccessibilityOption::PUBLIC;
260 } else if ((modifiers & ir::ModifierFlags::PROTECTED) != 0) {
261 accessibilityOption = ir::AccessibilityOption::PROTECTED;
262 }
263
264 if ((modifiers & ir::ModifierFlags::READONLY) != 0) {
265 readonly = true;
266 }
267
268 if ((modifiers & ir::ModifierFlags::STATIC) != 0) {
269 isStatic = true;
270 }
271
272 // NOTE(Csaba Repasi): Handle export property of TSParameterProperty
273
274 return AllocNode<ir::TSParameterProperty>(accessibilityOption, parameter, readonly, isStatic, isExport);
275 }
276
ParseFunctionParameter()277 ir::Expression *TSParser::ParseFunctionParameter()
278 {
279 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS) {
280 Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
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->SetReference();
358 identRef->SetRange(Lexer()->GetToken().Loc());
359
360 auto *typeReference = AllocNode<ir::TSTypeReference>(identRef, nullptr);
361 typeReference->SetRange(Lexer()->GetToken().Loc());
362
363 Lexer()->NextToken();
364
365 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
366 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
367 Lexer()->GetToken().Type() != lexer::TokenType::EOS &&
368 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET &&
369 ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) == 0)) {
370 ThrowSyntaxError("Unexpected token.");
371 }
372
373 return typeReference;
374 }
375
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)376 bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
377 {
378 if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
379 return true;
380 }
381
382 *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
383 (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
384 Lexer()->NextToken();
385 return false;
386 }
387
388 // NOLINTNEXTLINE(google-default-arguments)
ParseObjectExpression(ExpressionParseFlags flags)389 ir::ObjectExpression *TSParser::ParseObjectExpression(ExpressionParseFlags flags)
390 {
391 ir::ObjectExpression *objExpression = ParserImpl::ParseObjectExpression(flags);
392 ParsePotentialOptionalFunctionParameter(objExpression);
393 return objExpression;
394 }
395
396 // NOLINTNEXTLINE(google-default-arguments)
ParseArrayExpression(ExpressionParseFlags flags)397 ir::ArrayExpression *TSParser::ParseArrayExpression(ExpressionParseFlags flags)
398 {
399 ir::ArrayExpression *arrayExpression = ParserImpl::ParseArrayExpression(flags);
400 ParsePotentialOptionalFunctionParameter(arrayExpression);
401 return arrayExpression;
402 }
403 class TSParser::ParsePotentialArrowExpressionHelper {
404 friend ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression,
405 const lexer::SourcePosition &startLoc);
406
407 private:
CreateCallExpression(TSParser * parser,lexer::Lexer * lexer,ir::Expression ** returnExpression,ir::TSTypeParameterDeclaration * typeParamDecl,const lexer::SourcePosition & startLoc)408 static ir::ArrowFunctionExpression *CreateCallExpression(TSParser *parser, lexer::Lexer *lexer,
409 ir::Expression **returnExpression,
410 ir::TSTypeParameterDeclaration *typeParamDecl,
411 const lexer::SourcePosition &startLoc)
412 {
413 ir::CallExpression *callExpression = parser->ParseCallExpression(*returnExpression, false);
414
415 ir::TypeNode *returnTypeAnnotation = nullptr;
416 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
417 lexer->NextToken(); // eat ':'
418 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
419 returnTypeAnnotation = parser->ParseTypeAnnotation(&options);
420 }
421
422 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
423 ir::ArrowFunctionExpression *arrowFuncExpr =
424 parser->ParseArrowFunctionExpression(callExpression, typeParamDecl, returnTypeAnnotation, true);
425 arrowFuncExpr->SetStart(startLoc);
426
427 return arrowFuncExpr;
428 }
429
430 if (returnTypeAnnotation != nullptr || typeParamDecl != nullptr) {
431 parser->ThrowSyntaxError("'=>' expected");
432 }
433
434 *returnExpression = callExpression;
435 return nullptr;
436 }
437 };
438
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)439 ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression,
440 const lexer::SourcePosition &startLoc)
441 {
442 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
443
444 switch (Lexer()->GetToken().Type()) {
445 case lexer::TokenType::KEYW_FUNCTION: {
446 *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
447 (*returnExpression)->SetStart(startLoc);
448 break;
449 }
450 case lexer::TokenType::LITERAL_IDENT: {
451 ir::Expression *identRef = ParsePrimaryExpression();
452 ASSERT(identRef->IsIdentifier());
453
454 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
455 ThrowSyntaxError("Unexpected token, expected '=>'");
456 }
457
458 ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
459 arrowFuncExpr->SetStart(startLoc);
460
461 return arrowFuncExpr;
462 }
463 case lexer::TokenType::PUNCTUATOR_ARROW: {
464 ir::ArrowFunctionExpression *arrowFuncExpr =
465 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
466 arrowFuncExpr->SetStart(startLoc);
467 return arrowFuncExpr;
468 }
469 case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
470 const auto savedPos = Lexer()->Save();
471
472 auto options = TypeAnnotationParsingOptions::NO_OPTS;
473 typeParamDecl = ParseTypeParameterDeclaration(&options);
474 if (typeParamDecl == nullptr) {
475 Lexer()->Rewind(savedPos);
476 return nullptr;
477 }
478
479 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
480 ThrowSyntaxError("'(' expected");
481 }
482
483 [[fallthrough]];
484 }
485 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
486 return ParsePotentialArrowExpressionHelper::CreateCallExpression(this, Lexer(), returnExpression,
487 typeParamDecl, startLoc);
488 }
489 default: {
490 break;
491 }
492 }
493
494 return nullptr;
495 }
496
ParseVariableDeclaratorKey(VariableParsingFlags flags)497 ir::AnnotatedExpression *TSParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
498 {
499 ir::AnnotatedExpression *init = ParserImpl::ParseVariableDeclaratorKey(flags);
500
501 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
502 Lexer()->NextToken(); // eat ':'
503 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
504 init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
505 }
506
507 return init;
508 }
509
ParseOptionalFunctionParameter(ir::AnnotatedExpression * returnNode,bool isRest)510 void TSParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool isRest)
511 {
512 bool isOptional = false;
513
514 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
515 if (isRest) {
516 ThrowSyntaxError("A rest parameter cannot be optional");
517 }
518
519 switch (returnNode->Type()) {
520 case ir::AstNodeType::IDENTIFIER: {
521 returnNode->AsIdentifier()->SetOptional(true);
522 break;
523 }
524 case ir::AstNodeType::OBJECT_PATTERN:
525 case ir::AstNodeType::ARRAY_PATTERN: {
526 if (!InAmbientContext() && ((GetContext().Status() & ParserStatus::FUNCTION) != 0)) {
527 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.");
528 }
529
530 if (returnNode->IsObjectPattern()) {
531 returnNode->AsObjectPattern()->SetOptional(true);
532 break;
533 }
534
535 returnNode->AsArrayPattern()->SetOptional(true);
536 break;
537 }
538 case ir::AstNodeType::REST_ELEMENT: {
539 returnNode->AsRestElement()->SetOptional(true);
540 break;
541 }
542 default: {
543 UNREACHABLE();
544 }
545 }
546
547 isOptional = true;
548 Lexer()->NextToken(); // eat '?'
549 }
550
551 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
552 Lexer()->NextToken(); // eat ':'
553 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
554 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
555 }
556
557 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
558 return;
559 }
560
561 if (isRest) {
562 ThrowSyntaxError("A rest parameter cannot have an initializer");
563 }
564
565 if (returnNode->IsIdentifier() && isOptional) {
566 ThrowSyntaxError("Parameter cannot have question mark and initializer");
567 }
568 }
569
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)570 void TSParser::ValidateArrowFunctionRestParameter(ir::SpreadElement *restElement)
571 {
572 ParseOptionalFunctionParameter(restElement, true);
573
574 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
575 ThrowSyntaxError("')' expected");
576 }
577 }
578
ParseArrowFunctionRestParameter(lexer::SourcePosition start)579 ir::Expression *TSParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
580 {
581 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
582
583 restElement->SetGrouped();
584 restElement->SetStart(start);
585
586 ValidateArrowFunctionRestParameter(restElement);
587
588 Lexer()->NextToken();
589
590 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
591 ir::TypeNode *returnTypeAnnotation = nullptr;
592 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
593 Lexer()->NextToken(); // eat ':'
594 returnTypeAnnotation = ParseTypeAnnotation(&options);
595 }
596
597 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
598 ThrowSyntaxError("Unexpected token");
599 }
600
601 return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
602 }
603
ParseArrowFunctionNoParameter(lexer::SourcePosition start)604 ir::Expression *TSParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
605 {
606 Lexer()->NextToken();
607
608 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
609 ir::TypeNode *returnTypeAnnotation = nullptr;
610 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
611 Lexer()->NextToken(); // eat ':'
612 returnTypeAnnotation = ParseTypeAnnotation(&options);
613 }
614
615 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
616 ThrowSyntaxError("Unexpected token");
617 }
618
619 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
620 arrowExpr->SetStart(start);
621 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
622
623 return arrowExpr;
624 }
625
626 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)627 ir::Expression *TSParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
628 [[maybe_unused]] ExpressionParseFlags flags)
629 {
630 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
631 lexer::SourcePosition start = Lexer()->GetToken().Start();
632 Lexer()->NextToken();
633 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
634
635 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
636 return ParseArrowFunctionRestParameter(start);
637 }
638
639 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
640 return ParseArrowFunctionNoParameter(start);
641 }
642
643 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
644 ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
645
646 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
647 ThrowSyntaxError("Unexpected token, expected ')'");
648 }
649
650 expr->SetGrouped();
651 expr->SetRange({start, Lexer()->GetToken().End()});
652 Lexer()->NextToken();
653
654 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
655 auto savedPos = Lexer()->Save();
656 Lexer()->NextToken(); // eat ':'
657 options = TypeAnnotationParsingOptions::NO_OPTS;
658 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
659
660 if (returnTypeAnnotation == nullptr) {
661 Lexer()->Rewind(savedPos);
662 return expr;
663 }
664
665 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
666 Lexer()->Rewind(savedPos);
667 return expr;
668 }
669
670 return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
671 }
672
673 return expr;
674 }
675
676 } // namespace ark::es2panda::parser