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,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 default:
545 return std::nullopt;
546 }
547 }
548
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)549 ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
550 bool ignoreCallExpression,
551 [[maybe_unused]] bool *isChainExpression)
552 {
553 ir::Expression *returnExpression = primaryExpr;
554
555 while (true) {
556 auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression);
557 if (expr.has_value()) {
558 returnExpression = expr.value();
559 continue;
560 }
561
562 break;
563 }
564
565 return returnExpression;
566 }
567
ParsePotentialAsExpression(ir::Expression * primaryExpr)568 ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExpr)
569 {
570 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS);
571 Lexer()->NextToken();
572
573 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
574 ir::TypeNode *type = ParseTypeAnnotation(&options);
575
576 auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpr, type, false);
577 asExpression->SetRange(primaryExpr->Range());
578 return asExpression;
579 }
580
581 // Extracted from 'ParseNewExpression()' to reduce function's size
CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression * > & arguments,ir::TypeNode * typeReference,ir::TypeNode * baseTypeReference)582 ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments,
583 ir::TypeNode *typeReference,
584 ir::TypeNode *baseTypeReference)
585 {
586 lexer::SourcePosition endLoc = typeReference->End();
587
588 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
589 if (baseTypeReference != nullptr) {
590 ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start());
591 }
592
593 Lexer()->NextToken();
594
595 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
596 ir::Expression *argument = ParseExpression();
597 arguments.push_back(argument);
598
599 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
600 Lexer()->NextToken();
601 continue;
602 }
603 }
604
605 endLoc = Lexer()->GetToken().End();
606 Lexer()->NextToken();
607 }
608
609 ir::ClassDefinition *classDefinition {};
610
611 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
612 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
613 auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER;
614 auto [ctor, properties, bodyRange] = ParseClassBody(modifiers);
615
616 auto newIdent = AllocNode<ir::Identifier>("#0", Allocator());
617 classDefinition = AllocNode<ir::ClassDefinition>(
618 "#0", newIdent, nullptr, nullptr, std::move(implements), ctor, // remove name
619 typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE,
620 Language(Language::Id::ETS));
621
622 classDefinition->SetRange(bodyRange);
623 }
624
625 return classDefinition;
626 }
627
ParseNewExpression()628 ir::Expression *ETSParser::ParseNewExpression()
629 {
630 lexer::SourcePosition start = Lexer()->GetToken().Start();
631
632 Lexer()->NextToken(); // eat new
633
634 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
635 ir::TypeNode *baseTypeReference = ParseBaseTypeReference(&options);
636 ir::TypeNode *typeReference = baseTypeReference;
637 if (typeReference == nullptr) {
638 options |= TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | TypeAnnotationParsingOptions::ALLOW_WILDCARD;
639 typeReference = ParseTypeReference(&options);
640 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
641 ThrowSyntaxError("Invalid { after base types.");
642 }
643
644 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
645 Lexer()->NextToken();
646 ir::Expression *dimension = ParseExpression();
647
648 auto endLoc = Lexer()->GetToken().End();
649 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
650
651 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
652 auto *arrInstance = AllocNode<ir::ETSNewArrayInstanceExpression>(typeReference, dimension);
653 arrInstance->SetRange({start, endLoc});
654 return arrInstance;
655 }
656
657 ArenaVector<ir::Expression *> dimensions(Allocator()->Adapter());
658 dimensions.push_back(dimension);
659
660 do {
661 Lexer()->NextToken();
662 dimensions.push_back(ParseExpression());
663
664 endLoc = Lexer()->GetToken().End();
665 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
666 } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
667
668 auto *multiArray = AllocNode<ir::ETSNewMultiDimArrayInstanceExpression>(typeReference, std::move(dimensions));
669 multiArray->SetRange({start, endLoc});
670 return multiArray;
671 }
672
673 ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
674 ir::ClassDefinition *classDefinition =
675 CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference);
676
677 auto *newExprNode =
678 AllocNode<ir::ETSNewClassInstanceExpression>(typeReference, std::move(arguments), classDefinition);
679 newExprNode->SetRange({start, Lexer()->GetToken().End()});
680
681 return newExprNode;
682 }
683
ParseAsyncExpression()684 ir::Expression *ETSParser::ParseAsyncExpression()
685 {
686 Lexer()->NextToken(); // eat 'async'
687 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
688 !IsArrowFunctionExpressionStart()) {
689 ThrowSyntaxError("Unexpected token. expected '('");
690 }
691
692 auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ARROW_FUNCTION | ParserStatus::ASYNC_FUNCTION;
693 auto *func = ParseFunction(newStatus);
694 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
695 arrowFuncNode->SetRange(func->Range());
696 return arrowFuncNode;
697 }
698
ParseAwaitExpression()699 ir::Expression *ETSParser::ParseAwaitExpression()
700 {
701 lexer::SourcePosition start = Lexer()->GetToken().Start();
702 Lexer()->NextToken();
703 ir::Expression *argument = ParseExpression();
704 auto *awaitExpression = AllocNode<ir::AwaitExpression>(argument);
705 awaitExpression->SetRange({start, Lexer()->GetToken().End()});
706 return awaitExpression;
707 }
708
ParseThisExpression()709 ir::ThisExpression *ETSParser::ParseThisExpression()
710 {
711 auto *thisExpression = TypedParser::ParseThisExpression();
712
713 if (Lexer()->GetToken().NewLine()) {
714 return thisExpression;
715 }
716
717 switch (Lexer()->GetToken().Type()) {
718 case lexer::TokenType::PUNCTUATOR_PERIOD:
719 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
720 case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
721 case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
722 case lexer::TokenType::PUNCTUATOR_COLON:
723 case lexer::TokenType::PUNCTUATOR_EQUAL:
724 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
725 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
726 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
727 case lexer::TokenType::PUNCTUATOR_COMMA:
728 case lexer::TokenType::PUNCTUATOR_QUESTION_MARK:
729 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
730 case lexer::TokenType::KEYW_INSTANCEOF:
731 case lexer::TokenType::KEYW_AS: {
732 break;
733 }
734 default: {
735 ThrowUnexpectedToken(Lexer()->GetToken().Type());
736 break;
737 }
738 }
739
740 return thisExpression;
741 }
742
ParsePotentialExpressionSequence(ir::Expression * expr,ExpressionParseFlags flags)743 ir::Expression *ETSParser::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
744 {
745 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
746 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0 && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
747 return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
748 }
749
750 return expr;
751 }
752
ParsePotentialNonNullExpression(ir::Expression ** expression,const lexer::SourcePosition startLoc)753 bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)
754 {
755 if (expression == nullptr || Lexer()->GetToken().NewLine()) {
756 return true;
757 }
758
759 const auto nonNullExpr = AllocNode<ir::TSNonNullExpression>(*expression);
760 nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()});
761
762 *expression = nonNullExpr;
763
764 Lexer()->NextToken();
765
766 return false;
767 }
768
ValidateInstanceOfExpression(ir::Expression * expr)769 void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr)
770 {
771 ValidateGroupedExpression(expr);
772 lexer::TokenType tokenType = Lexer()->GetToken().Type();
773 if (tokenType == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
774 auto options = TypeAnnotationParsingOptions::NO_OPTS;
775
776 // Run checks to validate type declarations
777 // Should provide helpful messages with incorrect declarations like the following:
778 // `instanceof A<String;`
779 ParseTypeParameterDeclaration(&options);
780
781 // Display error message even when type declaration is correct
782 // `instanceof A<String>;`
783 ThrowSyntaxError("Invalid right-hand side in 'instanceof' expression");
784 }
785 }
786
787 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)788 ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags)
789 {
790 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
791 (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
792 ir::YieldExpression *yieldExpr = ParseYieldExpression();
793
794 return ParsePotentialExpressionSequence(yieldExpr, flags);
795 }
796
797 ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
798 if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
799 ValidateInstanceOfExpression(unaryExpressionNode);
800 }
801
802 ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
803
804 if (Lexer()->GetToken().NewLine()) {
805 return assignmentExpression;
806 }
807
808 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
809 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
810 return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
811 }
812
813 return assignmentExpression;
814 }
815
816 } // namespace ark::es2panda::parser
817