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 "ETSparser.h"
17 #include "ETSNolintParser.h"
18 #include <utility>
19
20 #include "macros.h"
21 #include "parser/parserFlags.h"
22 #include "parser/parserStatusContext.h"
23 #include "util/helpers.h"
24 #include "util/language.h"
25 #include "utils/arena_containers.h"
26 #include "varbinder/varbinder.h"
27 #include "varbinder/ETSBinder.h"
28 #include "lexer/lexer.h"
29 #include "lexer/ETSLexer.h"
30 #include "checker/types/ets/etsEnumType.h"
31 #include "ir/astNode.h"
32 #include "ir/base/classDefinition.h"
33 #include "ir/base/decorator.h"
34 #include "ir/base/catchClause.h"
35 #include "ir/base/classProperty.h"
36 #include "ir/base/scriptFunction.h"
37 #include "ir/base/methodDefinition.h"
38 #include "ir/base/classStaticBlock.h"
39 #include "ir/base/spreadElement.h"
40 #include "ir/expressions/identifier.h"
41 #include "ir/expressions/functionExpression.h"
42 #include "ir/statements/functionDeclaration.h"
43 #include "ir/statements/expressionStatement.h"
44 #include "ir/statements/classDeclaration.h"
45 #include "ir/statements/variableDeclarator.h"
46 #include "ir/statements/variableDeclaration.h"
47 #include "ir/expressions/dummyNode.h"
48 #include "ir/expressions/callExpression.h"
49 #include "ir/expressions/thisExpression.h"
50 #include "ir/expressions/typeofExpression.h"
51 #include "ir/expressions/memberExpression.h"
52 #include "ir/expressions/updateExpression.h"
53 #include "ir/expressions/arrowFunctionExpression.h"
54 #include "ir/expressions/unaryExpression.h"
55 #include "ir/expressions/yieldExpression.h"
56 #include "ir/expressions/awaitExpression.h"
57 #include "ir/expressions/literals/nullLiteral.h"
58 #include "ir/expressions/literals/numberLiteral.h"
59 #include "ir/expressions/literals/stringLiteral.h"
60 #include "ir/expressions/literals/undefinedLiteral.h"
61 #include "ir/module/importDeclaration.h"
62 #include "ir/module/importDefaultSpecifier.h"
63 #include "ir/module/importSpecifier.h"
64 #include "ir/module/exportSpecifier.h"
65 #include "ir/module/exportNamedDeclaration.h"
66 #include "ir/statements/assertStatement.h"
67 #include "ir/statements/blockStatement.h"
68 #include "ir/statements/ifStatement.h"
69 #include "ir/statements/labelledStatement.h"
70 #include "ir/statements/switchStatement.h"
71 #include "ir/statements/throwStatement.h"
72 #include "ir/statements/tryStatement.h"
73 #include "ir/statements/whileStatement.h"
74 #include "ir/statements/forOfStatement.h"
75 #include "ir/statements/doWhileStatement.h"
76 #include "ir/statements/breakStatement.h"
77 #include "ir/statements/debuggerStatement.h"
78 #include "ir/ets/etsLaunchExpression.h"
79 #include "ir/ets/etsClassLiteral.h"
80 #include "ir/ets/etsPrimitiveType.h"
81 #include "ir/ets/etsPackageDeclaration.h"
82 #include "ir/ets/etsReExportDeclaration.h"
83 #include "ir/ets/etsWildcardType.h"
84 #include "ir/ets/etsNewArrayInstanceExpression.h"
85 #include "ir/ets/etsTuple.h"
86 #include "ir/ets/etsFunctionType.h"
87 #include "ir/ets/etsNewClassInstanceExpression.h"
88 #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h"
89 #include "ir/ets/etsScript.h"
90 #include "ir/ets/etsTypeReference.h"
91 #include "ir/ets/etsTypeReferencePart.h"
92 #include "ir/ets/etsNullishTypes.h"
93 #include "ir/ets/etsUnionType.h"
94 #include "ir/ets/etsImportSource.h"
95 #include "ir/ets/etsImportDeclaration.h"
96 #include "ir/ets/etsStructDeclaration.h"
97 #include "ir/ets/etsParameterExpression.h"
98 #include "ir/module/importNamespaceSpecifier.h"
99 #include "ir/ts/tsAsExpression.h"
100 #include "ir/ts/tsInterfaceDeclaration.h"
101 #include "ir/ts/tsEnumDeclaration.h"
102 #include "ir/ts/tsTypeParameterInstantiation.h"
103 #include "ir/ts/tsInterfaceBody.h"
104 #include "ir/ts/tsImportEqualsDeclaration.h"
105 #include "ir/ts/tsArrayType.h"
106 #include "ir/ts/tsQualifiedName.h"
107 #include "ir/ts/tsTypeReference.h"
108 #include "ir/ts/tsTypeParameter.h"
109 #include "ir/ts/tsInterfaceHeritage.h"
110 #include "ir/ts/tsFunctionType.h"
111 #include "ir/ts/tsClassImplements.h"
112 #include "ir/ts/tsEnumMember.h"
113 #include "ir/ts/tsTypeAliasDeclaration.h"
114 #include "ir/ts/tsTypeParameterDeclaration.h"
115 #include "ir/ts/tsNonNullExpression.h"
116 #include "ir/ts/tsThisType.h"
117 #include "generated/signatures.h"
118
119 namespace ark::es2panda::parser {
120 class FunctionContext;
121
122 using namespace std::literals::string_literals;
123
ParseLaunchExpression(ExpressionParseFlags flags)124 ir::Expression *ETSParser::ParseLaunchExpression(ExpressionParseFlags flags)
125 {
126 lexer::SourcePosition start = Lexer()->GetToken().Start();
127 Lexer()->NextToken(); // eat launch
128
129 ir::Expression *expr = ParseLeftHandSideExpression(flags);
130 if (!expr->IsCallExpression()) {
131 ThrowSyntaxError("Only call expressions are allowed after 'launch'", expr->Start());
132 }
133 auto call = expr->AsCallExpression();
134 auto *launchExpression = AllocNode<ir::ETSLaunchExpression>(call);
135 launchExpression->SetRange({start, call->End()});
136
137 return launchExpression;
138 }
139
140 // NOLINTBEGIN(modernize-avoid-c-arrays)
141 static constexpr char const NO_DEFAULT_FOR_REST[] = "Rest parameter cannot have the default value.";
142 // NOLINTEND(modernize-avoid-c-arrays)
143
ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent, ir::ETSUndefinedType *defaultUndef)144 ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent,
145 ir::ETSUndefinedType *defaultUndef)
146 {
147 ir::ETSParameterExpression *paramExpression;
148 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
149 if (paramIdent->IsRestElement()) {
150 ThrowSyntaxError(NO_DEFAULT_FOR_REST);
151 }
152
153 auto const lexerPos = Lexer()->Save().Iterator();
154 Lexer()->NextToken(); // eat '='
155
156 if ((GetContext().Status() & ParserStatus::ALLOW_DEFAULT_VALUE) != 0) {
157 ThrowSyntaxError("Default value is allowed only for optional parameters");
158 }
159
160 if (defaultUndef != nullptr) {
161 ThrowSyntaxError("Not enable default value with default undefined");
162 }
163 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS ||
164 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
165 ThrowSyntaxError("You didn't set the value.");
166 }
167
168 paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), ParseExpression());
169
170 std::string value = Lexer()->SourceView(lexerPos.Index(), Lexer()->Save().Iterator().Index()).Mutf8();
171 while (value.back() == ' ') {
172 value.pop_back();
173 }
174 if (value.back() == ')' || value.back() == ',') {
175 value.pop_back();
176 }
177 paramExpression->SetLexerSaved(util::UString(value, Allocator()).View());
178
179 paramExpression->SetRange({paramIdent->Start(), paramExpression->Initializer()->End()});
180 } else if (paramIdent->IsIdentifier()) {
181 auto *typeAnnotation = paramIdent->AsIdentifier()->TypeAnnotation();
182
183 const auto typeAnnotationValue = [this, typeAnnotation,
184 defaultUndef]() -> std::pair<ir::Expression *, std::string> {
185 if (typeAnnotation == nullptr) {
186 return std::make_pair(nullptr, "");
187 }
188 return std::make_pair(defaultUndef != nullptr ? AllocNode<ir::UndefinedLiteral>() : nullptr, "undefined");
189 }();
190
191 paramExpression =
192 AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), std::get<0>(typeAnnotationValue));
193 if (defaultUndef != nullptr) {
194 paramExpression->SetLexerSaved(util::UString(std::get<1>(typeAnnotationValue), Allocator()).View());
195 }
196 paramExpression->SetRange({paramIdent->Start(), paramIdent->End()});
197 } else {
198 paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsRestElement(), nullptr);
199 paramExpression->SetRange({paramIdent->Start(), paramIdent->End()});
200 }
201 return paramExpression;
202 }
203
ResolveArgumentUnaryExpr(ExpressionParseFlags flags)204 ir::Expression *ETSParser::ResolveArgumentUnaryExpr(ExpressionParseFlags flags)
205 {
206 switch (Lexer()->GetToken().Type()) {
207 case lexer::TokenType::PUNCTUATOR_PLUS:
208 case lexer::TokenType::PUNCTUATOR_MINUS:
209 case lexer::TokenType::PUNCTUATOR_TILDE:
210 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK:
211 case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR:
212 case lexer::TokenType::PUNCTUATOR_PLUS_PLUS:
213 case lexer::TokenType::PUNCTUATOR_MINUS_MINUS:
214 case lexer::TokenType::KEYW_TYPEOF: {
215 return ParseUnaryOrPrefixUpdateExpression();
216 }
217 default: {
218 return ParseLeftHandSideExpression(flags);
219 }
220 }
221 }
222
223 // NOLINTNEXTLINE(google-default-arguments)
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)224 ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
225 {
226 switch (Lexer()->GetToken().Type()) {
227 case lexer::TokenType::PUNCTUATOR_PLUS_PLUS:
228 case lexer::TokenType::PUNCTUATOR_MINUS_MINUS:
229 case lexer::TokenType::PUNCTUATOR_PLUS:
230 case lexer::TokenType::PUNCTUATOR_MINUS:
231 case lexer::TokenType::PUNCTUATOR_TILDE:
232 case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR:
233 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK:
234 case lexer::TokenType::KEYW_TYPEOF: {
235 break;
236 }
237 case lexer::TokenType::KEYW_LAUNCH: {
238 return ParseLaunchExpression(flags);
239 }
240 default: {
241 return ParseLeftHandSideExpression(flags);
242 }
243 }
244
245 lexer::TokenType operatorType = Lexer()->GetToken().Type();
246 auto start = Lexer()->GetToken().Start();
247 Lexer()->NextToken();
248
249 ir::Expression *argument = ResolveArgumentUnaryExpr(flags);
250
251 if (lexer::Token::IsUpdateToken(operatorType)) {
252 if (!argument->IsIdentifier() && !argument->IsMemberExpression()) {
253 ThrowSyntaxError("Invalid left-hand side in prefix operation");
254 }
255 }
256
257 lexer::SourcePosition end = argument->End();
258
259 ir::Expression *returnExpr = nullptr;
260 if (lexer::Token::IsUpdateToken(operatorType)) {
261 returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true);
262 } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) {
263 returnExpr = AllocNode<ir::TypeofExpression>(argument);
264 } else {
265 returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType);
266 }
267
268 returnExpr->SetRange({start, end});
269
270 return returnExpr;
271 }
272
273 // NOLINTNEXTLINE(google-default-arguments)
ParseDefaultPrimaryExpression(ExpressionParseFlags flags)274 ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags)
275 {
276 auto startLoc = Lexer()->GetToken().Start();
277 auto savedPos = Lexer()->Save();
278 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL |
279 TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE |
280 TypeAnnotationParsingOptions::DISALLOW_UNION;
281 ir::TypeNode *potentialType = ParseTypeAnnotation(&options);
282
283 if (potentialType != nullptr) {
284 if (potentialType->IsTSArrayType()) {
285 return potentialType;
286 }
287
288 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
289 Lexer()->NextToken(); // eat '.'
290 }
291
292 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) {
293 Lexer()->NextToken(); // eat 'class' and 'struct'
294 auto *classLiteral = AllocNode<ir::ETSClassLiteral>(potentialType);
295 classLiteral->SetRange({startLoc, Lexer()->GetToken().End()});
296 return classLiteral;
297 }
298 }
299
300 Lexer()->Rewind(savedPos);
301
302 Lexer()->NextToken();
303 bool pretendArrow = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW;
304 Lexer()->Rewind(savedPos);
305
306 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !pretendArrow) {
307 return ParsePrimaryExpressionIdent(flags);
308 }
309
310 ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(Lexer()->GetToken().Type()), "'."});
311 return nullptr;
312 }
313
ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)314 ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)
315 {
316 switch (Lexer()->GetToken().Type()) {
317 case lexer::TokenType::LITERAL_TRUE:
318 case lexer::TokenType::LITERAL_FALSE: {
319 return ParseBooleanLiteral();
320 }
321 case lexer::TokenType::LITERAL_NULL: {
322 return ParseNullLiteral();
323 }
324 case lexer::TokenType::KEYW_UNDEFINED: {
325 return ParseUndefinedLiteral();
326 }
327 case lexer::TokenType::LITERAL_NUMBER: {
328 return ParseCoercedNumberLiteral();
329 }
330 case lexer::TokenType::LITERAL_STRING: {
331 return ParseStringLiteral();
332 }
333 case lexer::TokenType::LITERAL_CHAR: {
334 return ParseCharLiteral();
335 }
336 default: {
337 return ParseDefaultPrimaryExpression(flags);
338 }
339 }
340 }
341
342 // NOLINTNEXTLINE(google-default-arguments)
ParsePrimaryExpression(ExpressionParseFlags flags)343 ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags)
344 {
345 switch (Lexer()->GetToken().Type()) {
346 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
347 return ParseCoverParenthesizedExpressionAndArrowParameterList(flags);
348 }
349 case lexer::TokenType::KEYW_THIS: {
350 return ParseThisExpression();
351 }
352 case lexer::TokenType::KEYW_SUPER: {
353 return ParseSuperExpression();
354 }
355 case lexer::TokenType::KEYW_NEW: {
356 return ParseNewExpression();
357 }
358 case lexer::TokenType::KEYW_ASYNC: {
359 return ParseAsyncExpression();
360 }
361 case lexer::TokenType::KEYW_AWAIT: {
362 return ParseAwaitExpression();
363 }
364 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
365 return ParseArrayExpression(CarryPatternFlags(flags));
366 }
367 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
368 return ParseObjectExpression(CarryPatternFlags(flags));
369 }
370 case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
371 return ParseTemplateLiteral();
372 }
373 case lexer::TokenType::KEYW_TYPE: {
374 ThrowSyntaxError("Type alias is allowed only as top-level declaration");
375 }
376 case lexer::TokenType::PUNCTUATOR_FORMAT: {
377 return ParseExpressionFormatPlaceholder();
378 }
379 case lexer::TokenType::KEYW_TYPEOF: {
380 return ParseUnaryOrPrefixUpdateExpression();
381 }
382 default: {
383 return ParsePrimaryExpressionWithLiterals(flags);
384 }
385 }
386 }
387
IsPunctuartorSpecialCharacter(lexer::TokenType tokenType)388 bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType)
389 {
390 switch (tokenType) {
391 case lexer::TokenType::PUNCTUATOR_COLON:
392 case lexer::TokenType::PUNCTUATOR_COMMA:
393 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
394 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
395 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
396 case lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET:
397 case lexer::TokenType::PUNCTUATOR_LESS_THAN:
398 case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
399 case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
400 return true;
401 default:
402 return false;
403 }
404 }
405
IsArrowFunctionExpressionStart()406 bool ETSParser::IsArrowFunctionExpressionStart()
407 {
408 const auto savedPos = Lexer()->Save();
409 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
410 Lexer()->NextToken();
411 auto tokenType = Lexer()->GetToken().Type();
412
413 size_t openBrackets = 1;
414 bool expectIdentifier = true;
415 while (tokenType != lexer::TokenType::EOS && openBrackets > 0) {
416 switch (tokenType) {
417 case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
418 --openBrackets;
419 break;
420 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
421 ++openBrackets;
422 break;
423 case lexer::TokenType::PUNCTUATOR_COMMA:
424 expectIdentifier = true;
425 break;
426 case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
427 Lexer()->Rewind(savedPos);
428 return false;
429 default:
430 if (!expectIdentifier) {
431 break;
432 }
433 if (tokenType != lexer::TokenType::LITERAL_IDENT &&
434 tokenType != lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
435 Lexer()->Rewind(savedPos);
436 return false;
437 }
438 expectIdentifier = false;
439 }
440 Lexer()->NextToken();
441 tokenType = Lexer()->GetToken().Type();
442 }
443
444 while (tokenType != lexer::TokenType::EOS && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
445 if (lexer::Token::IsPunctuatorToken(tokenType) && !IsPunctuartorSpecialCharacter(tokenType)) {
446 break;
447 }
448 Lexer()->NextToken();
449 tokenType = Lexer()->GetToken().Type();
450 }
451 Lexer()->Rewind(savedPos);
452 return tokenType == lexer::TokenType::PUNCTUATOR_ARROW;
453 }
454
ParseArrowFunctionExpression()455 ir::ArrowFunctionExpression *ETSParser::ParseArrowFunctionExpression()
456 {
457 auto newStatus = ParserStatus::ARROW_FUNCTION;
458 auto *func = ParseFunction(newStatus);
459 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
460 arrowFuncNode->SetRange(func->Range());
461 return arrowFuncNode;
462 }
463
464 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)465 ir::Expression *ETSParser::ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)
466 {
467 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
468 if (IsArrowFunctionExpressionStart()) {
469 return ParseArrowFunctionExpression();
470 }
471
472 lexer::SourcePosition start = Lexer()->GetToken().Start();
473 Lexer()->NextToken();
474
475 ExpressionParseFlags newFlags = ExpressionParseFlags::ACCEPT_COMMA;
476 if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
477 newFlags |= ExpressionParseFlags::INSTANCEOF;
478 };
479
480 ir::Expression *expr = ParseExpression(newFlags);
481
482 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
483 ThrowSyntaxError("Unexpected token, expected ')'");
484 }
485
486 expr->SetGrouped();
487 expr->SetRange({start, Lexer()->GetToken().End()});
488 Lexer()->NextToken();
489
490 return expr;
491 }
492
GetPostPrimaryExpression(ir::Expression *returnExpression, lexer::SourcePosition startLoc, bool ignoreCallExpression, [[maybe_unused]] bool *isChainExpression)493 std::optional<ir::Expression *> ETSParser::GetPostPrimaryExpression(ir::Expression *returnExpression,
494 lexer::SourcePosition startLoc,
495 bool ignoreCallExpression,
496 [[maybe_unused]] bool *isChainExpression)
497 {
498 switch (Lexer()->GetToken().Type()) {
499 case lexer::TokenType::PUNCTUATOR_QUESTION_DOT:
500 if (*isChainExpression) {
501 return std::nullopt; // terminate current chain
502 }
503 *isChainExpression = true;
504 Lexer()->NextToken(); // eat ?.
505
506 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
507 return ParseElementAccess(returnExpression, true);
508 }
509
510 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
511 return ParseCallExpression(returnExpression, true, false);
512 }
513
514 return ParsePropertyAccess(returnExpression, true);
515 case lexer::TokenType::PUNCTUATOR_PERIOD:
516 Lexer()->NextToken(); // eat period
517
518 return ParsePropertyAccess(returnExpression);
519 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
520 return ParseElementAccess(returnExpression);
521 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
522 case lexer::TokenType::PUNCTUATOR_LESS_THAN:
523 if (ParsePotentialGenericFunctionCall(returnExpression, &returnExpression, startLoc,
524 ignoreCallExpression)) {
525 return std::nullopt;
526 }
527
528 return returnExpression;
529 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
530 if (ignoreCallExpression) {
531 return std::nullopt;
532 }
533 return ParseCallExpression(returnExpression, false, false);
534 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
535 const bool shouldBreak = ParsePotentialNonNullExpression(&returnExpression, startLoc);
536 if (shouldBreak) {
537 return std::nullopt;
538 }
539
540 return returnExpression;
541 }
542 case lexer::TokenType::PUNCTUATOR_FORMAT:
543 ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_FORMAT);
544 case lexer::TokenType::PUNCTUATOR_ARROW:
545 ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_ARROW);
546 default:
547 return std::nullopt;
548 }
549 }
550
ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, bool ignoreCallExpression, [[maybe_unused]] bool *isChainExpression)551 ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
552 bool ignoreCallExpression,
553 [[maybe_unused]] bool *isChainExpression)
554 {
555 ir::Expression *returnExpression = primaryExpr;
556
557 while (true) {
558 auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression);
559 if (expr.has_value()) {
560 returnExpression = expr.value();
561 continue;
562 }
563
564 break;
565 }
566
567 return returnExpression;
568 }
569
ParsePotentialAsExpression(ir::Expression *primaryExpr)570 ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExpr)
571 {
572 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS);
573 Lexer()->NextToken();
574
575 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
576 ir::TypeNode *type = ParseTypeAnnotation(&options);
577
578 auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpr, type, false);
579 asExpression->SetRange(primaryExpr->Range());
580 return asExpression;
581 }
582
583 // Extracted from 'ParseNewExpression()' to reduce function's size
CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments, ir::TypeNode *typeReference, ir::TypeNode *baseTypeReference)584 ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments,
585 ir::TypeNode *typeReference,
586 ir::TypeNode *baseTypeReference)
587 {
588 lexer::SourcePosition endLoc = typeReference->End();
589
590 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
591 if (baseTypeReference != nullptr) {
592 ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start());
593 }
594
595 Lexer()->NextToken();
596
597 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
598 ir::Expression *argument = ParseExpression();
599 arguments.push_back(argument);
600
601 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
602 Lexer()->NextToken();
603 continue;
604 }
605 }
606
607 endLoc = Lexer()->GetToken().End();
608 Lexer()->NextToken();
609 }
610
611 ir::ClassDefinition *classDefinition {};
612
613 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
614 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
615 auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER;
616 auto [ctor, properties, bodyRange] = ParseClassBody(modifiers);
617
618 auto newIdent = AllocNode<ir::Identifier>("#0", Allocator());
619 classDefinition = AllocNode<ir::ClassDefinition>(
620 "#0", newIdent, nullptr, nullptr, std::move(implements), ctor, // remove name
621 typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE,
622 Language(Language::Id::ETS));
623
624 classDefinition->SetRange(bodyRange);
625 }
626
627 return classDefinition;
628 }
629
ParseNewExpression()630 ir::Expression *ETSParser::ParseNewExpression()
631 {
632 lexer::SourcePosition start = Lexer()->GetToken().Start();
633
634 Lexer()->NextToken(); // eat new
635
636 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
637 ir::TypeNode *baseTypeReference = ParseBaseTypeReference(&options);
638 ir::TypeNode *typeReference = baseTypeReference;
639 if (typeReference == nullptr) {
640 options |= TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | TypeAnnotationParsingOptions::ALLOW_WILDCARD |
641 TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY;
642 typeReference = ParseTypeReference(&options);
643 if (typeReference == nullptr) {
644 typeReference = ParseTypeAnnotation(&options);
645 }
646 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
647 ThrowSyntaxError("Invalid { after base types.");
648 }
649
650 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
651 Lexer()->NextToken();
652 ir::Expression *dimension = ParseExpression();
653
654 auto endLoc = Lexer()->GetToken().End();
655 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
656
657 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
658 auto *arrInstance = AllocNode<ir::ETSNewArrayInstanceExpression>(typeReference, dimension);
659 arrInstance->SetRange({start, endLoc});
660 return arrInstance;
661 }
662
663 ArenaVector<ir::Expression *> dimensions(Allocator()->Adapter());
664 dimensions.push_back(dimension);
665
666 do {
667 Lexer()->NextToken();
668 dimensions.push_back(ParseExpression());
669
670 endLoc = Lexer()->GetToken().End();
671 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
672 } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
673
674 auto *multiArray = AllocNode<ir::ETSNewMultiDimArrayInstanceExpression>(typeReference, std::move(dimensions));
675 multiArray->SetRange({start, endLoc});
676 return multiArray;
677 }
678
679 ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
680 ir::ClassDefinition *classDefinition =
681 CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference);
682
683 auto *newExprNode =
684 AllocNode<ir::ETSNewClassInstanceExpression>(typeReference, std::move(arguments), classDefinition);
685 newExprNode->SetRange({start, Lexer()->GetToken().End()});
686
687 return newExprNode;
688 }
689
ParseAsyncExpression()690 ir::Expression *ETSParser::ParseAsyncExpression()
691 {
692 Lexer()->NextToken(); // eat 'async'
693 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
694 !IsArrowFunctionExpressionStart()) {
695 ThrowSyntaxError("Unexpected token. expected '('");
696 }
697
698 auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ARROW_FUNCTION | ParserStatus::ASYNC_FUNCTION;
699 auto *func = ParseFunction(newStatus);
700 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
701 arrowFuncNode->SetRange(func->Range());
702 return arrowFuncNode;
703 }
704
ParseAwaitExpression()705 ir::Expression *ETSParser::ParseAwaitExpression()
706 {
707 lexer::SourcePosition start = Lexer()->GetToken().Start();
708 Lexer()->NextToken();
709 ir::Expression *argument = ParseExpression();
710 auto *awaitExpression = AllocNode<ir::AwaitExpression>(argument);
711 awaitExpression->SetRange({start, Lexer()->GetToken().End()});
712 return awaitExpression;
713 }
714
ParseThisExpression()715 ir::ThisExpression *ETSParser::ParseThisExpression()
716 {
717 auto *thisExpression = TypedParser::ParseThisExpression();
718
719 if (Lexer()->GetToken().NewLine()) {
720 return thisExpression;
721 }
722
723 switch (Lexer()->GetToken().Type()) {
724 case lexer::TokenType::PUNCTUATOR_PERIOD:
725 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
726 case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
727 case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
728 case lexer::TokenType::PUNCTUATOR_COLON:
729 case lexer::TokenType::PUNCTUATOR_EQUAL:
730 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
731 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
732 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
733 case lexer::TokenType::PUNCTUATOR_COMMA:
734 case lexer::TokenType::PUNCTUATOR_QUESTION_MARK:
735 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
736 case lexer::TokenType::KEYW_INSTANCEOF:
737 case lexer::TokenType::KEYW_AS: {
738 break;
739 }
740 default: {
741 ThrowUnexpectedToken(Lexer()->GetToken().Type());
742 break;
743 }
744 }
745
746 return thisExpression;
747 }
748
ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)749 ir::Expression *ETSParser::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
750 {
751 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
752 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0 && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
753 return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
754 }
755
756 return expr;
757 }
758
ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)759 bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)
760 {
761 if (expression == nullptr || Lexer()->GetToken().NewLine()) {
762 return true;
763 }
764
765 const auto nonNullExpr = AllocNode<ir::TSNonNullExpression>(*expression);
766 nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()});
767
768 *expression = nonNullExpr;
769
770 Lexer()->NextToken();
771
772 return false;
773 }
774
ValidateInstanceOfExpression(ir::Expression *expr)775 void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr)
776 {
777 ValidateGroupedExpression(expr);
778 lexer::TokenType tokenType = Lexer()->GetToken().Type();
779 if (tokenType == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
780 auto options = TypeAnnotationParsingOptions::NO_OPTS;
781
782 // Run checks to validate type declarations
783 // Should provide helpful messages with incorrect declarations like the following:
784 // `instanceof A<String;`
785 ParseTypeParameterDeclaration(&options);
786
787 // Display error message even when type declaration is correct
788 // `instanceof A<String>;`
789 ThrowSyntaxError("Invalid right-hand side in 'instanceof' expression");
790 }
791 }
792
793 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)794 ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags)
795 {
796 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
797 (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
798 ir::YieldExpression *yieldExpr = ParseYieldExpression();
799
800 return ParsePotentialExpressionSequence(yieldExpr, flags);
801 }
802
803 ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
804 if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
805 ValidateInstanceOfExpression(unaryExpressionNode);
806 }
807
808 ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
809
810 if (Lexer()->GetToken().NewLine()) {
811 return assignmentExpression;
812 }
813
814 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
815 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
816 return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
817 }
818
819 return assignmentExpression;
820 }
821
822 } // namespace ark::es2panda::parser
823