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 "lexer/token/tokenType.h"
17 #include "parser/parserFlags.h"
18 #include "ir/astNode.h"
19 #include "ir/base/classDefinition.h"
20 #include "ir/base/decorator.h"
21 #include "ir/base/metaProperty.h"
22 #include "ir/base/methodDefinition.h"
23 #include "ir/base/property.h"
24 #include "ir/base/scriptFunction.h"
25 #include "ir/base/spreadElement.h"
26 #include "ir/base/templateElement.h"
27 #include "ir/expression.h"
28 #include "ir/expressions/arrayExpression.h"
29 #include "ir/expressions/arrowFunctionExpression.h"
30 #include "ir/expressions/assignmentExpression.h"
31 #include "ir/expressions/awaitExpression.h"
32 #include "ir/expressions/binaryExpression.h"
33 #include "ir/expressions/callExpression.h"
34 #include "ir/expressions/chainExpression.h"
35 #include "ir/expressions/classExpression.h"
36 #include "ir/expressions/conditionalExpression.h"
37 #include "ir/expressions/directEvalExpression.h"
38 #include "ir/expressions/functionExpression.h"
39 #include "ir/expressions/identifier.h"
40 #include "ir/expressions/importExpression.h"
41 #include "ir/expressions/literals/bigIntLiteral.h"
42 #include "ir/expressions/literals/booleanLiteral.h"
43 #include "ir/expressions/literals/nullLiteral.h"
44 #include "ir/expressions/literals/numberLiteral.h"
45 #include "ir/expressions/literals/regExpLiteral.h"
46 #include "ir/expressions/literals/charLiteral.h"
47 #include "ir/expressions/literals/stringLiteral.h"
48 #include "ir/expressions/literals/undefinedLiteral.h"
49 #include "ir/expressions/memberExpression.h"
50 #include "ir/expressions/newExpression.h"
51 #include "ir/expressions/objectExpression.h"
52 #include "ir/expressions/omittedExpression.h"
53 #include "ir/expressions/sequenceExpression.h"
54 #include "ir/expressions/superExpression.h"
55 #include "ir/expressions/taggedTemplateExpression.h"
56 #include "ir/expressions/templateLiteral.h"
57 #include "ir/expressions/thisExpression.h"
58 #include "ir/expressions/typeofExpression.h"
59 #include "ir/expressions/unaryExpression.h"
60 #include "ir/expressions/updateExpression.h"
61 #include "ir/expressions/yieldExpression.h"
62 #include "ir/statements/blockStatement.h"
63 #include "ir/statements/classDeclaration.h"
64 #include "ir/ts/tsAsExpression.h"
65 #include "ir/ts/tsNonNullExpression.h"
66 #include "ir/validationInfo.h"
67 #include "lexer/lexer.h"
68 #include "lexer/regexp/regexp.h"
69 #include "lexer/token/letters.h"
70 #include "lexer/token/sourceLocation.h"
71 #include "lexer/token/token.h"
72 #include "macros.h"
73
74 #include <memory>
75
76 #include "parser/parserStatusContext.h"
77 #include "parserImpl.h"
78
79 namespace ark::es2panda::parser {
ParseYieldExpression()80 ir::YieldExpression *ParserImpl::ParseYieldExpression()
81 {
82 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD);
83
84 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
85 lexer::SourcePosition endLoc = lexer_->GetToken().End();
86
87 if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) {
88 ThrowSyntaxError("Unexpected identifier");
89 }
90
91 lexer_->NextToken();
92
93 bool isDelegate = false;
94 ir::Expression *argument = nullptr;
95
96 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY && !lexer_->GetToken().NewLine()) {
97 isDelegate = true;
98 lexer_->NextToken();
99
100 argument = ParseExpression();
101 endLoc = argument->End();
102 } else if (!lexer_->GetToken().NewLine() && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
103 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS &&
104 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET &&
105 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
106 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
107 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
108 lexer_->GetToken().Type() != lexer::TokenType::EOS) {
109 argument = ParseExpression();
110 endLoc = argument->End();
111 }
112
113 auto *yieldNode = AllocNode<ir::YieldExpression>(argument, isDelegate);
114 yieldNode->SetRange({startLoc, endLoc});
115
116 return yieldNode;
117 }
118
ParsePotentialExpressionSequence(ir::Expression * expr,ExpressionParseFlags flags)119 ir::Expression *ParserImpl::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
120 {
121 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
122 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0) {
123 return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
124 }
125
126 return expr;
127 }
128
129 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)130 ir::Expression *ParserImpl::ParseExpression(ExpressionParseFlags flags)
131 {
132 if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
133 (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
134 ir::YieldExpression *yieldExpr = ParseYieldExpression();
135
136 return ParsePotentialExpressionSequence(yieldExpr, flags);
137 }
138
139 ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
140 ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
141
142 if (lexer_->GetToken().NewLine()) {
143 return assignmentExpression;
144 }
145
146 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
147 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U) {
148 return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
149 }
150
151 return assignmentExpression;
152 }
153
154 // NOLINTNEXTLINE(google-default-arguments)
ParseArrayExpression(ExpressionParseFlags flags)155 ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags)
156 {
157 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
158
159 ArenaVector<ir::Expression *> elements(Allocator()->Adapter());
160
161 lexer_->NextToken();
162
163 bool trailingComma = false;
164 bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
165
166 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
167 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
168 auto *omitted = AllocNode<ir::OmittedExpression>();
169 omitted->SetRange(lexer_->GetToken().Loc());
170 elements.push_back(omitted);
171 lexer_->NextToken();
172 continue;
173 }
174
175 ir::Expression *element {};
176 if (inPattern) {
177 element = ParsePatternElement();
178 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
179 element = ParseSpreadElement(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
180 } else {
181 element = ParseExpression(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
182 }
183
184 bool containsRest = element->IsRestElement();
185
186 elements.push_back(element);
187
188 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
189 if (containsRest) {
190 ThrowSyntaxError("Rest element must be last element", startLoc);
191 }
192
193 lexer_->NextToken(); // eat comma
194
195 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
196 trailingComma = true;
197 break;
198 }
199
200 continue;
201 }
202
203 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
204 ThrowSyntaxError("Unexpected token, expected ',' or ']'");
205 }
206 }
207
208 auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION;
209 auto *arrayExpressionNode =
210 AllocNode<ir::ArrayExpression>(nodeType, std::move(elements), Allocator(), trailingComma);
211 arrayExpressionNode->SetRange({startLoc, lexer_->GetToken().End()});
212 lexer_->NextToken();
213
214 if (inPattern) {
215 arrayExpressionNode->SetDeclaration();
216 }
217
218 ParseArrayExpressionErrorCheck(arrayExpressionNode, flags, inPattern);
219 return arrayExpressionNode;
220 }
221
ParseArrayExpressionErrorCheck(ir::ArrayExpression * arrayExpressionNode,const ExpressionParseFlags flags,const bool inPattern)222 void ParserImpl::ParseArrayExpressionErrorCheck(ir::ArrayExpression *arrayExpressionNode,
223 const ExpressionParseFlags flags, const bool inPattern)
224 {
225 if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) {
226 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
227 !arrayExpressionNode->ConvertibleToArrayPattern()) {
228 ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", arrayExpressionNode->Start());
229 } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
230 ir::ValidationInfo info = arrayExpressionNode->ValidateExpression();
231 if (info.Fail()) {
232 ThrowSyntaxError(info.msg.Utf8(), info.pos);
233 }
234 }
235 }
236 }
237
ValidateArrowParameter(ir::Expression * expr,bool * seenOptional)238 ParserStatus ParserImpl::ValidateArrowParameter(ir::Expression *expr, [[maybe_unused]] bool *seenOptional)
239 {
240 switch (expr->Type()) {
241 case ir::AstNodeType::SPREAD_ELEMENT: {
242 if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
243 ThrowSyntaxError("Invalid rest element.");
244 }
245
246 [[fallthrough]];
247 }
248 case ir::AstNodeType::REST_ELEMENT: {
249 ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
250 return ParserStatus::HAS_COMPLEX_PARAM;
251 }
252 case ir::AstNodeType::IDENTIFIER: {
253 ValidateArrowParameterBindings(expr);
254 return ParserStatus::NO_OPTS;
255 }
256 case ir::AstNodeType::OBJECT_EXPRESSION: {
257 if (ir::ObjectExpression *objectPattern = expr->AsObjectExpression();
258 !objectPattern->ConvertibleToObjectPattern()) {
259 ThrowSyntaxError("Invalid destructuring assignment target");
260 }
261
262 ValidateArrowParameterBindings(expr);
263 return ParserStatus::HAS_COMPLEX_PARAM;
264 }
265 case ir::AstNodeType::ARRAY_EXPRESSION: {
266 if (ir::ArrayExpression *arrayPattern = expr->AsArrayExpression();
267 !arrayPattern->ConvertibleToArrayPattern()) {
268 ThrowSyntaxError("Invalid destructuring assignment target");
269 }
270
271 ValidateArrowParameterBindings(expr);
272 return ParserStatus::HAS_COMPLEX_PARAM;
273 }
274 case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
275 ValidateArrowParameterAssignment(expr->AsAssignmentExpression());
276 ValidateArrowParameterBindings(expr);
277 return ParserStatus::HAS_COMPLEX_PARAM;
278 }
279 default: {
280 break;
281 }
282 }
283 ThrowSyntaxError("Insufficient formal parameter in arrow function.");
284 return ParserStatus::NO_OPTS;
285 }
286
ValidateArrowParameterAssignment(ir::AssignmentExpression * expr)287 void ParserImpl::ValidateArrowParameterAssignment(ir::AssignmentExpression *expr)
288 {
289 if (expr->Right()->IsYieldExpression()) {
290 ThrowSyntaxError("yield is not allowed in arrow function parameters");
291 } else if (expr->Right()->IsAwaitExpression()) {
292 ThrowSyntaxError("await is not allowed in arrow function parameters");
293 } else if (!expr->ConvertibleToAssignmentPattern()) {
294 ThrowSyntaxError("Invalid destructuring assignment target");
295 }
296 }
297
ParseArrowFunctionExpressionBody(ArrowFunctionContext * arrowFunctionContext,ArrowFunctionDescriptor * desc,ir::TSTypeParameterDeclaration * typeParamDecl,ir::TypeNode * returnTypeAnnotation)298 ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowFunctionContext *arrowFunctionContext,
299 ArrowFunctionDescriptor *desc,
300 ir::TSTypeParameterDeclaration *typeParamDecl,
301 ir::TypeNode *returnTypeAnnotation)
302 {
303 context_.Status() |= desc->newStatus;
304
305 lexer_->NextToken(); // eat '=>'
306 ir::ScriptFunction *funcNode {};
307
308 ir::AstNode *body = nullptr;
309 lexer::SourcePosition endLoc;
310 lexer::SourcePosition bodyStart = lexer_->GetToken().Start();
311
312 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
313 body = ParseExpression();
314 endLoc = body->AsExpression()->End();
315 arrowFunctionContext->AddFlag(ir::ScriptFunctionFlags::EXPRESSION);
316 } else {
317 lexer_->NextToken();
318 auto statements = ParseStatementList();
319 body = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements));
320 body->SetRange({bodyStart, lexer_->GetToken().End()});
321
322 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
323 ThrowSyntaxError("Expected a '}'");
324 }
325
326 lexer_->NextToken();
327 endLoc = body->End();
328 }
329
330 // clang-format off
331 funcNode = AllocNode<ir::ScriptFunction>(
332 Allocator(), ir::ScriptFunction::ScriptFunctionData {
333 body,
334 ir::FunctionSignature(typeParamDecl, std::move(desc->params), returnTypeAnnotation),
335 arrowFunctionContext->Flags(),
336 {},
337 false,
338 context_.GetLanguage()});
339 // clang-format on
340 funcNode->SetRange({desc->startLoc, endLoc});
341
342 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(funcNode);
343 arrowFuncNode->SetRange(funcNode->Range());
344
345 return arrowFuncNode;
346 }
347
ConvertToArrowParameter(ir::Expression * expr,bool isAsync)348 ArrowFunctionDescriptor ParserImpl::ConvertToArrowParameter(ir::Expression *expr, bool isAsync)
349 {
350 auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
351 ArenaVector<ir::Expression *> params(Allocator()->Adapter());
352
353 if (expr == nullptr) {
354 return ArrowFunctionDescriptor {std::move(params), lexer_->GetToken().Start(), arrowStatus};
355 }
356
357 bool seenOptional = false;
358
359 switch (expr->Type()) {
360 case ir::AstNodeType::REST_ELEMENT:
361 case ir::AstNodeType::IDENTIFIER:
362 case ir::AstNodeType::OBJECT_EXPRESSION:
363 case ir::AstNodeType::ASSIGNMENT_EXPRESSION:
364 case ir::AstNodeType::ARRAY_EXPRESSION: {
365 arrowStatus |= ValidateArrowParameter(expr, &seenOptional);
366
367 params.push_back(expr);
368 break;
369 }
370 case ir::AstNodeType::SEQUENCE_EXPRESSION: {
371 auto &sequence = expr->AsSequenceExpression()->Sequence();
372
373 for (auto *it : sequence) {
374 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
375 }
376
377 params.swap(sequence);
378 break;
379 }
380 case ir::AstNodeType::CALL_EXPRESSION: {
381 if (isAsync) {
382 auto *callExpression = expr->AsCallExpression();
383 auto &arguments = callExpression->Arguments();
384
385 if (callExpression->HasTrailingComma()) {
386 ASSERT(!arguments.empty());
387 ThrowSyntaxError("Rest parameter must be last formal parameter", arguments.back()->End());
388 }
389
390 for (auto *it : arguments) {
391 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
392 }
393
394 params.swap(arguments);
395 break;
396 }
397
398 [[fallthrough]];
399 }
400 default: {
401 ThrowSyntaxError("Unexpected token, arrow (=>)");
402 }
403 }
404
405 return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus};
406 }
407
ParseArrowFunctionExpression(ir::Expression * expr,ir::TSTypeParameterDeclaration * typeParamDecl,ir::TypeNode * returnTypeAnnotation,bool isAsync)408 ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpression(ir::Expression *expr,
409 ir::TSTypeParameterDeclaration *typeParamDecl,
410 ir::TypeNode *returnTypeAnnotation, bool isAsync)
411 {
412 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW);
413
414 if (lexer_->GetToken().NewLine()) {
415 ThrowSyntaxError(
416 "expected '=>' on the same line after an argument list, "
417 "got line terminator");
418 }
419
420 ArrowFunctionContext arrowFunctionContext(this, isAsync);
421 FunctionParameterContext functionParamContext(&context_);
422 ArrowFunctionDescriptor desc = ConvertToArrowParameter(expr, isAsync);
423
424 return ParseArrowFunctionExpressionBody(&arrowFunctionContext, &desc, typeParamDecl, returnTypeAnnotation);
425 }
426
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)427 void ParserImpl::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
428 {
429 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
430 ThrowSyntaxError("Rest parameter must be last formal parameter");
431 }
432 }
433
434 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)435 ir::Expression *ParserImpl::ParseCoverParenthesizedExpressionAndArrowParameterList(
436 [[maybe_unused]] ExpressionParseFlags flags)
437 {
438 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
439 lexer::SourcePosition start = lexer_->GetToken().Start();
440 lexer_->NextToken();
441
442 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
443 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
444
445 restElement->SetGrouped();
446 restElement->SetStart(start);
447
448 ValidateArrowFunctionRestParameter(restElement);
449
450 lexer_->NextToken();
451
452 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
453 ThrowSyntaxError("Unexpected token");
454 }
455
456 return ParseArrowFunctionExpression(restElement, nullptr, nullptr, false);
457 }
458
459 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
460 lexer_->NextToken();
461
462 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
463 ThrowSyntaxError("Unexpected token");
464 }
465
466 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, nullptr, false);
467 arrowExpr->SetStart(start);
468 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
469
470 return arrowExpr;
471 }
472
473 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
474 ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
475
476 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
477 ThrowSyntaxError("Unexpected token, expected ')'");
478 }
479
480 expr->SetGrouped();
481 expr->SetRange({start, lexer_->GetToken().End()});
482 lexer_->NextToken();
483
484 return expr;
485 }
486
CheckInvalidDestructuring(const ir::AstNode * object) const487 void ParserImpl::CheckInvalidDestructuring(const ir::AstNode *object) const
488 {
489 object->Iterate([this](ir::AstNode *childNode) -> void {
490 switch (childNode->Type()) {
491 case ir::AstNodeType::ASSIGNMENT_PATTERN: {
492 ThrowSyntaxError("Invalid property initializer");
493 break;
494 }
495 case ir::AstNodeType::REST_ELEMENT:
496 case ir::AstNodeType::PROPERTY:
497 case ir::AstNodeType::OBJECT_EXPRESSION: {
498 CheckInvalidDestructuring(childNode);
499 break;
500 }
501 default: {
502 break;
503 }
504 }
505 });
506 }
507
ValidateGroupedExpression(ir::Expression * lhsExpression)508 void ParserImpl::ValidateGroupedExpression(ir::Expression *lhsExpression)
509 {
510 lexer::TokenType tokenType = lexer_->GetToken().Type();
511 if (lhsExpression->IsGrouped() && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
512 if (lhsExpression->IsSequenceExpression()) {
513 for (auto *seq : lhsExpression->AsSequenceExpression()->Sequence()) {
514 ValidateParenthesizedExpression(seq);
515 }
516 } else {
517 ValidateParenthesizedExpression(lhsExpression);
518 }
519 }
520 }
521
ValidateParenthesizedExpression(ir::Expression * lhsExpression)522 void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression)
523 {
524 switch (lhsExpression->Type()) {
525 case ir::AstNodeType::IDENTIFIER: {
526 auto info = lhsExpression->AsIdentifier()->ValidateExpression();
527 if (info.Fail()) {
528 ThrowSyntaxError(info.msg.Utf8(), info.pos);
529 }
530 break;
531 }
532 case ir::AstNodeType::MEMBER_EXPRESSION: {
533 break;
534 }
535 case ir::AstNodeType::ARRAY_EXPRESSION: {
536 auto info = lhsExpression->AsArrayExpression()->ValidateExpression();
537 if (info.Fail()) {
538 ThrowSyntaxError(info.msg.Utf8(), info.pos);
539 }
540 break;
541 }
542 case ir::AstNodeType::OBJECT_EXPRESSION: {
543 auto info = lhsExpression->AsObjectExpression()->ValidateExpression();
544 if (info.Fail()) {
545 ThrowSyntaxError(info.msg.Utf8(), info.pos);
546 }
547 break;
548 }
549 case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
550 if (lhsExpression->AsAssignmentExpression()->ConvertibleToAssignmentPattern(false)) {
551 break;
552 }
553 [[fallthrough]];
554 }
555 case ir::AstNodeType::SPREAD_ELEMENT: {
556 ThrowSyntaxError("Invalid left-hand side in assignment expression");
557 }
558 default: {
559 break;
560 }
561 }
562 }
563
ParsePrefixAssertionExpression()564 ir::Expression *ParserImpl::ParsePrefixAssertionExpression()
565 {
566 ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(lexer_->GetToken().Type()), "'."});
567 return nullptr;
568 }
569
ParseAssignmentExpression(ir::Expression * lhsExpression,ExpressionParseFlags flags)570 ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpression, ExpressionParseFlags flags)
571 {
572 ValidateGroupedExpression(lhsExpression);
573
574 lexer::TokenType tokenType = lexer_->GetToken().Type();
575 switch (tokenType) {
576 case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: {
577 lexer_->NextToken();
578 ir::Expression *consequent = ParseExpression();
579
580 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
581 ThrowSyntaxError("Unexpected token, expected ':'");
582 }
583
584 lexer_->NextToken();
585 ir::Expression *alternate = ParseExpression();
586
587 auto *conditionalExpr = AllocNode<ir::ConditionalExpression>(lhsExpression, consequent, alternate);
588 conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()});
589 return conditionalExpr;
590 }
591 case lexer::TokenType::PUNCTUATOR_ARROW: {
592 if (lexer_->GetToken().NewLine()) {
593 ThrowSyntaxError("Uncaught SyntaxError: expected expression, got '=>'");
594 }
595
596 return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false);
597 }
598 case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: {
599 ValidateAssignmentTarget(flags, lhsExpression);
600
601 lexer_->NextToken();
602 ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
603
604 auto *binaryAssignmentExpression =
605 AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
606
607 binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
608 return binaryAssignmentExpression;
609 }
610 case lexer::TokenType::KEYW_AS: {
611 if (auto asExpression = ParsePotentialAsExpression(lhsExpression); asExpression != nullptr) {
612 return ParseAssignmentExpression(asExpression);
613 }
614 break;
615 }
616 default: {
617 auto expression = ParseAssignmentBinaryExpression(tokenType, lhsExpression, flags);
618 if (expression == nullptr) {
619 expression = ParseAssignmentEqualExpression(tokenType, lhsExpression, flags);
620 }
621
622 if (expression != nullptr) {
623 return expression;
624 }
625
626 break;
627 }
628 }
629
630 return lhsExpression;
631 }
632
ParseAssignmentBinaryExpression(const lexer::TokenType tokenType,ir::Expression * lhsExpression,const ExpressionParseFlags flags)633 ir::Expression *ParserImpl::ParseAssignmentBinaryExpression(const lexer::TokenType tokenType,
634 ir::Expression *lhsExpression,
635 const ExpressionParseFlags flags)
636 {
637 switch (tokenType) {
638 case lexer::TokenType::KEYW_IN: {
639 if ((flags & ExpressionParseFlags::STOP_AT_IN) != 0) {
640 break;
641 }
642
643 [[fallthrough]];
644 }
645 case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING:
646 case lexer::TokenType::PUNCTUATOR_LOGICAL_OR:
647 case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
648 case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
649 case lexer::TokenType::PUNCTUATOR_BITWISE_XOR:
650 case lexer::TokenType::PUNCTUATOR_BITWISE_AND:
651 case lexer::TokenType::PUNCTUATOR_EQUAL:
652 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
653 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
654 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
655 case lexer::TokenType::PUNCTUATOR_LESS_THAN:
656 case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
657 case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
658 case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
659 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
660 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
661 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
662 case lexer::TokenType::PUNCTUATOR_PLUS:
663 case lexer::TokenType::PUNCTUATOR_MINUS:
664 case lexer::TokenType::PUNCTUATOR_MULTIPLY:
665 case lexer::TokenType::PUNCTUATOR_DIVIDE:
666 case lexer::TokenType::PUNCTUATOR_MOD:
667 case lexer::TokenType::KEYW_INSTANCEOF:
668 case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
669 return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression));
670 }
671 default:
672 break;
673 }
674
675 return nullptr;
676 }
677
ParseAssignmentEqualExpression(const lexer::TokenType tokenType,ir::Expression * lhsExpression,const ExpressionParseFlags flags)678 ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenType tokenType,
679 ir::Expression *lhsExpression,
680 const ExpressionParseFlags flags)
681 {
682 switch (tokenType) {
683 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL:
684 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL:
685 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL:
686 case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL:
687 case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL:
688 case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL:
689 case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
690 case lexer::TokenType::PUNCTUATOR_MOD_EQUAL:
691 case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL:
692 case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL:
693 case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL:
694 case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL:
695 case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL:
696 case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL:
697 case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: {
698 ValidateLvalueAssignmentTarget(lhsExpression);
699
700 lexer_->NextToken();
701 ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
702
703 auto *binaryAssignmentExpression =
704 AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
705
706 binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
707 return binaryAssignmentExpression;
708 }
709 default:
710 break;
711 }
712
713 return nullptr;
714 }
715
ParseTemplateLiteral()716 ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral()
717 {
718 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
719
720 ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter());
721 ArenaVector<ir::Expression *> expressions(Allocator()->Adapter());
722
723 while (true) {
724 lexer_->ResetTokenEnd();
725 const auto startPos = lexer_->Save();
726
727 lexer_->ScanString<lexer::LEX_CHAR_BACK_TICK>();
728 util::StringView cooked = lexer_->GetToken().String();
729
730 lexer_->Rewind(startPos);
731 auto [raw, end, scanExpression] = lexer_->ScanTemplateString();
732
733 auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked);
734 element->SetRange({lexer::SourcePosition {startPos.Iterator().Index(), startPos.Line()},
735 lexer::SourcePosition {end, lexer_->Line()}});
736 quasis.push_back(element);
737
738 if (!scanExpression) {
739 lexer_->ScanTemplateStringEnd();
740 break;
741 }
742
743 ir::Expression *expression = nullptr;
744
745 {
746 lexer::TemplateLiteralParserContext ctx(lexer_);
747 lexer_->PushTemplateContext(&ctx);
748 lexer_->NextToken();
749 expression = ParseExpression();
750 }
751
752 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
753 ThrowSyntaxError("Unexpected token, expected '}'.");
754 }
755
756 expressions.push_back(expression);
757 }
758
759 auto *templateNode = AllocNode<ir::TemplateLiteral>(std::move(quasis), std::move(expressions));
760 templateNode->SetRange({startLoc, lexer_->GetToken().End()});
761
762 lexer_->NextToken();
763
764 return templateNode;
765 }
766
ParseNewExpression()767 ir::Expression *ParserImpl::ParseNewExpression()
768 {
769 lexer::SourcePosition start = lexer_->GetToken().Start();
770
771 lexer_->NextToken(); // eat new
772
773 // parse callee part of NewExpression
774 ir::Expression *callee = ParseMemberExpression(true);
775 if (callee->IsImportExpression() && !callee->IsGrouped()) {
776 ThrowSyntaxError("Cannot use new with import(...)");
777 }
778
779 ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
780
781 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
782 lexer::SourcePosition endLoc = callee->End();
783 auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments));
784 newExprNode->SetRange({start, endLoc});
785
786 return newExprNode;
787 }
788
789 lexer_->NextToken(); // eat left parenthesis
790
791 // parse argument part of NewExpression
792 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
793 ir::Expression *argument = nullptr;
794
795 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
796 argument = ParseSpreadElement();
797 } else {
798 argument = ParseExpression();
799 }
800
801 arguments.push_back(argument);
802
803 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
804 lexer_->NextToken(); // eat comma
805 }
806
807 if (lexer_->GetToken().Type() == lexer::TokenType::EOS) {
808 ThrowSyntaxError("Unexpected token in argument parsing");
809 }
810 }
811
812 auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments));
813 newExprNode->SetRange({start, lexer_->GetToken().End()});
814
815 lexer_->NextToken();
816
817 return newExprNode;
818 }
819
ParseLeftHandSideExpression(ExpressionParseFlags flags)820 ir::Expression *ParserImpl::ParseLeftHandSideExpression(ExpressionParseFlags flags)
821 {
822 return ParseMemberExpression(false, flags);
823 }
824
ParsePotentialNewTarget()825 ir::MetaProperty *ParserImpl::ParsePotentialNewTarget()
826 {
827 lexer::SourceRange loc = lexer_->GetToken().Loc();
828
829 if (lexer_->Lookahead() == lexer::LEX_CHAR_DOT) {
830 lexer_->NextToken();
831 lexer_->NextToken();
832
833 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_TARGET) {
834 if ((context_.Status() & ParserStatus::ALLOW_NEW_TARGET) == 0) {
835 ThrowSyntaxError("'new.Target' is not allowed here");
836 }
837
838 if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) {
839 ThrowSyntaxError("'new.Target' must not contain escaped characters");
840 }
841
842 auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::NEW_TARGET);
843 metaProperty->SetRange(loc);
844 lexer_->NextToken();
845 return metaProperty;
846 }
847 }
848
849 return nullptr;
850 }
851
ParsePrimaryExpressionIdent(ExpressionParseFlags flags)852 ir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
853 {
854 auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
855 identNode->SetReference();
856 identNode->SetRange(lexer_->GetToken().Loc());
857
858 lexer_->NextToken();
859 return identNode;
860 }
861
ParseBooleanLiteral()862 ir::BooleanLiteral *ParserImpl::ParseBooleanLiteral()
863 {
864 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE ||
865 lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE);
866
867 auto *booleanNode = AllocNode<ir::BooleanLiteral>(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE);
868 booleanNode->SetRange(lexer_->GetToken().Loc());
869
870 lexer_->NextToken();
871 return booleanNode;
872 }
873
ParseNullLiteral()874 ir::NullLiteral *ParserImpl::ParseNullLiteral()
875 {
876 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL);
877 auto *nullNode = AllocNode<ir::NullLiteral>();
878 nullNode->SetRange(lexer_->GetToken().Loc());
879
880 lexer_->NextToken();
881 return nullNode;
882 }
883
ParseNumberLiteral()884 ir::Literal *ParserImpl::ParseNumberLiteral()
885 {
886 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER);
887
888 ir::Literal *numberNode {};
889
890 if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0U) {
891 numberNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
892 } else {
893 numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber());
894 }
895
896 numberNode->SetRange(lexer_->GetToken().Loc());
897
898 lexer_->NextToken();
899 return numberNode;
900 }
901
ParseCharLiteral()902 ir::CharLiteral *ParserImpl::ParseCharLiteral()
903 {
904 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR);
905
906 auto *charNode = AllocNode<ir::CharLiteral>(lexer_->GetToken().Utf16());
907 charNode->SetRange(lexer_->GetToken().Loc());
908
909 lexer_->NextToken();
910 return charNode;
911 }
912
ParseStringLiteral()913 ir::StringLiteral *ParserImpl::ParseStringLiteral()
914 {
915 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING);
916
917 auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
918 stringNode->SetRange(lexer_->GetToken().Loc());
919
920 lexer_->NextToken();
921 return stringNode;
922 }
923
ParseUndefinedLiteral()924 ir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral()
925 {
926 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED);
927 auto *undefinedNode = AllocNode<ir::UndefinedLiteral>();
928 undefinedNode->SetRange(lexer_->GetToken().Loc());
929
930 lexer_->NextToken();
931 return undefinedNode;
932 }
933
ParseThisExpression()934 ir::ThisExpression *ParserImpl::ParseThisExpression()
935 {
936 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS);
937
938 auto *thisExprNode = AllocNode<ir::ThisExpression>();
939 thisExprNode->SetRange(lexer_->GetToken().Loc());
940
941 lexer_->NextToken();
942 return thisExprNode;
943 }
944
ParseRegularExpression()945 ir::RegExpLiteral *ParserImpl::ParseRegularExpression()
946 {
947 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE ||
948 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL);
949
950 lexer_->ResetTokenEnd();
951 auto regexp = lexer_->ScanRegExp();
952
953 lexer::RegExpParser reParser(regexp, Allocator());
954
955 try {
956 reParser.ParsePattern();
957 } catch (lexer::RegExpError &e) {
958 ThrowSyntaxError(e.message.c_str());
959 }
960
961 auto *regexpNode = AllocNode<ir::RegExpLiteral>(regexp.patternStr, regexp.flags, regexp.flagsStr);
962 regexpNode->SetRange(lexer_->GetToken().Loc());
963
964 lexer_->NextToken();
965 return regexpNode;
966 }
967
ParseSuperExpression()968 ir::SuperExpression *ParserImpl::ParseSuperExpression()
969 {
970 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER);
971
972 auto *superExprNode = AllocNode<ir::SuperExpression>();
973 superExprNode->SetRange(lexer_->GetToken().Loc());
974
975 lexer_->NextToken(); // eat super
976
977 if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD ||
978 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) &&
979 (context_.Status() & ParserStatus::ALLOW_SUPER) != 0U) {
980 return superExprNode;
981 }
982
983 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
984 (context_.Status() & ParserStatus::ALLOW_SUPER_CALL) != 0U) {
985 return superExprNode;
986 }
987
988 ThrowSyntaxError("Unexpected super keyword");
989 }
990
ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)991 ir::Expression *ParserImpl::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)
992 {
993 switch (lexer_->GetToken().Type()) {
994 case lexer::TokenType::LITERAL_IDENT: {
995 return ParsePrimaryExpressionIdent(flags);
996 }
997 case lexer::TokenType::LITERAL_TRUE:
998 case lexer::TokenType::LITERAL_FALSE: {
999 return ParseBooleanLiteral();
1000 }
1001 case lexer::TokenType::LITERAL_NULL: {
1002 return ParseNullLiteral();
1003 }
1004 case lexer::TokenType::KEYW_UNDEFINED: {
1005 return ParseUndefinedLiteral();
1006 }
1007 case lexer::TokenType::LITERAL_NUMBER: {
1008 return ParseNumberLiteral();
1009 }
1010 case lexer::TokenType::LITERAL_STRING: {
1011 return ParseStringLiteral();
1012 }
1013 default: {
1014 break;
1015 }
1016 }
1017
1018 ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(lexer_->GetToken().Type()), "'."});
1019 return nullptr;
1020 }
1021
ParseHashMaskOperator()1022 ir::Expression *ParserImpl::ParseHashMaskOperator()
1023 {
1024 ValidatePrivateIdentifier();
1025 auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1026 privateIdent->SetPrivate(true);
1027 privateIdent->SetReference();
1028 lexer_->NextToken();
1029
1030 if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_IN) {
1031 ThrowSyntaxError("Unexpected private identifier");
1032 }
1033
1034 return privateIdent;
1035 }
1036
ParseClassExpression()1037 ir::Expression *ParserImpl::ParseClassExpression()
1038 {
1039 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1040 ir::ClassDefinition *classDefinition = ParseClassDefinition(ir::ClassDefinitionModifiers::ID_REQUIRED);
1041
1042 auto *classExpr = AllocNode<ir::ClassExpression>(classDefinition);
1043 classExpr->SetRange({startLoc, classDefinition->End()});
1044
1045 return classExpr;
1046 }
1047
ParsePunctuators(ExpressionParseFlags flags)1048 ir::Expression *ParserImpl::ParsePunctuators(ExpressionParseFlags flags)
1049 {
1050 switch (lexer_->GetToken().Type()) {
1051 case lexer::TokenType::PUNCTUATOR_DIVIDE:
1052 case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: {
1053 return ParseRegularExpression();
1054 }
1055 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1056 return ParseArrayExpression(CarryPatternFlags(flags));
1057 }
1058 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1059 return ParseCoverParenthesizedExpressionAndArrowParameterList();
1060 }
1061 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1062 return ParseObjectExpression(CarryPatternFlags(flags));
1063 }
1064 case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1065 return ParseTemplateLiteral();
1066 }
1067 case lexer::TokenType::PUNCTUATOR_HASH_MARK: {
1068 return ParseHashMaskOperator();
1069 }
1070 case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1071 return ParsePrefixAssertionExpression();
1072 }
1073 default: {
1074 UNREACHABLE();
1075 }
1076 }
1077 return nullptr;
1078 }
1079
1080 // NOLINTNEXTLINE(google-default-arguments)
ParsePrimaryExpression(ExpressionParseFlags flags)1081 ir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags)
1082 {
1083 switch (lexer_->GetToken().Type()) {
1084 case lexer::TokenType::KEYW_IMPORT: {
1085 return ParseImportExpression();
1086 }
1087 case lexer::TokenType::PUNCTUATOR_DIVIDE:
1088 case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
1089 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
1090 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
1091 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE:
1092 case lexer::TokenType::PUNCTUATOR_BACK_TICK:
1093 case lexer::TokenType::PUNCTUATOR_HASH_MARK:
1094 case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1095 return ParsePunctuators(flags);
1096 }
1097 case lexer::TokenType::KEYW_FUNCTION: {
1098 return ParseFunctionExpression();
1099 }
1100 case lexer::TokenType::KEYW_CLASS: {
1101 return ParseClassExpression();
1102 }
1103 case lexer::TokenType::KEYW_THIS: {
1104 return ParseThisExpression();
1105 }
1106 case lexer::TokenType::KEYW_TYPEOF: {
1107 return ParseUnaryOrPrefixUpdateExpression();
1108 }
1109 case lexer::TokenType::KEYW_SUPER: {
1110 return ParseSuperExpression();
1111 }
1112 case lexer::TokenType::KEYW_NEW: {
1113 ir::MetaProperty *newTarget = ParsePotentialNewTarget();
1114
1115 if (newTarget != nullptr) {
1116 return newTarget;
1117 }
1118
1119 return ParseNewExpression();
1120 }
1121 default: {
1122 break;
1123 }
1124 }
1125
1126 return ParsePrimaryExpressionWithLiterals(flags);
1127 }
1128
GetOperatorPrecedenceArithmeticAndComparison(const lexer::TokenType operatorType)1129 static constexpr size_t GetOperatorPrecedenceArithmeticAndComparison(const lexer::TokenType operatorType)
1130 {
1131 switch (operatorType) {
1132 case lexer::TokenType::PUNCTUATOR_EQUAL:
1133 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
1134 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
1135 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
1136 constexpr auto PRECEDENCE = 8;
1137 return PRECEDENCE;
1138 }
1139 case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1140 case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
1141 case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
1142 case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
1143 case lexer::TokenType::KEYW_INSTANCEOF:
1144 case lexer::TokenType::KEYW_IN: {
1145 constexpr auto PRECEDENCE = 9;
1146 return PRECEDENCE;
1147 }
1148 case lexer::TokenType::PUNCTUATOR_PLUS:
1149 case lexer::TokenType::PUNCTUATOR_MINUS: {
1150 constexpr auto PRECEDENCE = 12;
1151 return PRECEDENCE;
1152 }
1153 case lexer::TokenType::PUNCTUATOR_MULTIPLY:
1154 case lexer::TokenType::PUNCTUATOR_DIVIDE:
1155 case lexer::TokenType::PUNCTUATOR_MOD: {
1156 constexpr auto PRECEDENCE = 13;
1157 return PRECEDENCE;
1158 }
1159 default: {
1160 UNREACHABLE();
1161 }
1162 }
1163 }
1164
GetOperatorPrecedence(const lexer::TokenType operatorType)1165 static constexpr size_t GetOperatorPrecedence(const lexer::TokenType operatorType)
1166 {
1167 ASSERT(operatorType == lexer::TokenType::KEYW_AS || lexer::Token::IsBinaryToken(operatorType));
1168
1169 switch (operatorType) {
1170 case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: {
1171 constexpr auto PRECEDENCE = 1;
1172 return PRECEDENCE;
1173 }
1174 case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: {
1175 constexpr auto PRECEDENCE = 2;
1176 return PRECEDENCE;
1177 }
1178 case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: {
1179 constexpr auto PRECEDENCE = 4;
1180 return PRECEDENCE;
1181 }
1182 case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
1183 constexpr auto PRECEDENCE = 5;
1184 return PRECEDENCE;
1185 }
1186 case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: {
1187 constexpr auto PRECEDENCE = 6;
1188 return PRECEDENCE;
1189 }
1190 case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
1191 constexpr auto PRECEDENCE = 7;
1192 return PRECEDENCE;
1193 }
1194 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1195 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
1196 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
1197 constexpr auto PRECEDENCE = 10;
1198 return PRECEDENCE;
1199 }
1200 case lexer::TokenType::KEYW_AS: {
1201 constexpr auto PRECEDENCE = 11;
1202 return PRECEDENCE;
1203 }
1204 case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
1205 constexpr auto PRECEDENCE = 14;
1206 return PRECEDENCE;
1207 }
1208 default: {
1209 return GetOperatorPrecedenceArithmeticAndComparison(operatorType);
1210 }
1211 }
1212 }
1213
ShouldBinaryExpressionBeAmended(const ir::BinaryExpression * const binaryExpression,const lexer::TokenType operatorType)1214 static inline bool ShouldBinaryExpressionBeAmended(const ir::BinaryExpression *const binaryExpression,
1215 const lexer::TokenType operatorType)
1216 {
1217 return GetOperatorPrecedence(binaryExpression->OperatorType()) <= GetOperatorPrecedence(operatorType) &&
1218 !binaryExpression->IsGrouped() &&
1219 (operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION ||
1220 binaryExpression->OperatorType() != lexer::TokenType::PUNCTUATOR_EXPONENTIATION);
1221 }
1222
ShouldAsExpressionBeAmended(const ir::TSAsExpression * const asExpression,const lexer::TokenType operatorType)1223 static inline bool ShouldAsExpressionBeAmended(const ir::TSAsExpression *const asExpression,
1224 const lexer::TokenType operatorType)
1225 {
1226 return GetOperatorPrecedence(lexer::TokenType::KEYW_AS) <= GetOperatorPrecedence(operatorType) &&
1227 !asExpression->IsGrouped() && operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION;
1228 }
1229
ShouldExpressionBeAmended(const ir::Expression * const expression,const lexer::TokenType operatorType)1230 static inline bool ShouldExpressionBeAmended(const ir::Expression *const expression,
1231 const lexer::TokenType operatorType)
1232 {
1233 bool shouldBeAmended = false;
1234
1235 if (expression->IsBinaryExpression()) {
1236 shouldBeAmended = ShouldBinaryExpressionBeAmended(expression->AsBinaryExpression(), operatorType);
1237 } else if (expression->IsTSAsExpression()) {
1238 shouldBeAmended = ShouldAsExpressionBeAmended(expression->AsTSAsExpression(), operatorType);
1239 }
1240
1241 return shouldBeAmended;
1242 }
1243
AreLogicalAndNullishMixedIncorrectly(const ir::Expression * const expression,const lexer::TokenType operatorType)1244 static inline bool AreLogicalAndNullishMixedIncorrectly(const ir::Expression *const expression,
1245 const lexer::TokenType operatorType)
1246 {
1247 return ((operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1248 operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1249 expression->IsBinaryExpression() &&
1250 expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING &&
1251 !expression->IsGrouped()) ||
1252 (operatorType == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && expression->IsBinaryExpression() &&
1253 (expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1254 expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1255 !expression->IsGrouped());
1256 }
1257
GetAmendedChildExpression(ir::Expression * const expression)1258 static inline ir::Expression *GetAmendedChildExpression(ir::Expression *const expression)
1259 {
1260 ir::Expression *amendedChild = nullptr;
1261
1262 if (expression->IsBinaryExpression()) {
1263 amendedChild = expression->AsBinaryExpression()->Left();
1264 } else if (expression->IsTSAsExpression()) {
1265 amendedChild = expression->AsTSAsExpression()->Expr();
1266 } else {
1267 UNREACHABLE();
1268 }
1269
1270 return amendedChild;
1271 }
1272
SetAmendedChildExpression(ir::Expression * const parent,ir::Expression * const amended)1273 static inline void SetAmendedChildExpression(ir::Expression *const parent, ir::Expression *const amended)
1274 {
1275 if (parent->IsBinaryExpression()) {
1276 parent->AsBinaryExpression()->SetLeft(amended);
1277 amended->SetParent(parent);
1278 } else if (parent->IsTSAsExpression()) {
1279 parent->AsTSAsExpression()->SetExpr(amended);
1280 amended->SetParent(parent);
1281 } else {
1282 UNREACHABLE();
1283 }
1284 }
1285
CreateAmendedBinaryExpression(ir::Expression * const left,ir::Expression * const right,const lexer::TokenType operatorType)1286 void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::Expression *const right,
1287 const lexer::TokenType operatorType)
1288 {
1289 auto *amended = GetAmendedChildExpression(right);
1290
1291 amended->SetParent(nullptr); // Next line overwrite parent
1292 auto *binaryExpr = AllocNode<ir::BinaryExpression>(left, amended, operatorType);
1293
1294 binaryExpr->SetRange({left->Start(), amended->End()});
1295 SetAmendedChildExpression(right, binaryExpr);
1296 }
1297
ParseExpressionOrTypeAnnotation(lexer::TokenType type,ExpressionParseFlags flags)1298 ir::Expression *ParserImpl::ParseExpressionOrTypeAnnotation([[maybe_unused]] lexer::TokenType type,
1299 [[maybe_unused]] ExpressionParseFlags flags)
1300 {
1301 return ParseExpression(ExpressionParseFlags::DISALLOW_YIELD);
1302 }
1303
ParseBinaryExpression(ir::Expression * left,ExpressionParseFlags flags)1304 ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, ExpressionParseFlags flags)
1305 {
1306 lexer::TokenType operatorType = lexer_->GetToken().Type();
1307 ASSERT(lexer::Token::IsBinaryToken(operatorType));
1308
1309 if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) {
1310 if ((left->IsUnaryExpression() || left->IsTypeofExpression()) && !left->IsGrouped()) {
1311 ThrowSyntaxError(
1312 "Illegal expression. Wrap left hand side or entire "
1313 "exponentiation in parentheses.");
1314 }
1315 }
1316
1317 lexer_->NextToken();
1318
1319 ExpressionParseFlags newFlags = ExpressionParseFlags::DISALLOW_YIELD;
1320 if ((operatorType == lexer::TokenType::KEYW_INSTANCEOF) || ((flags & ExpressionParseFlags::INSTANCEOF) != 0)) {
1321 newFlags |= ExpressionParseFlags::INSTANCEOF;
1322 }
1323
1324 ir::Expression *rightExpr = ParseExpressionOrTypeAnnotation(operatorType, ExpressionParseFlags::DISALLOW_YIELD);
1325 ir::ConditionalExpression *conditionalExpr = nullptr;
1326
1327 if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) {
1328 conditionalExpr = rightExpr->AsConditionalExpression();
1329 rightExpr = conditionalExpr->Test();
1330 }
1331
1332 if (ShouldExpressionBeAmended(rightExpr, operatorType)) {
1333 if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) {
1334 ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1335 }
1336
1337 bool shouldBeAmended = true;
1338
1339 ir::Expression *expression = rightExpr;
1340 ir::Expression *parentExpression = nullptr;
1341
1342 while (shouldBeAmended && GetAmendedChildExpression(expression)->IsBinaryExpression()) {
1343 parentExpression = expression;
1344 parentExpression->SetStart(left->Start());
1345
1346 expression = GetAmendedChildExpression(expression);
1347
1348 shouldBeAmended = ShouldExpressionBeAmended(expression, operatorType);
1349 }
1350
1351 CreateAmendedBinaryExpression(left, shouldBeAmended ? expression : parentExpression, operatorType);
1352 } else {
1353 if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) {
1354 ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1355 }
1356 const lexer::SourcePosition &endPos = rightExpr->End();
1357 rightExpr = AllocNode<ir::BinaryExpression>(left, rightExpr, operatorType);
1358 rightExpr->SetRange({left->Start(), endPos});
1359 }
1360
1361 if (conditionalExpr != nullptr) {
1362 conditionalExpr->SetStart(rightExpr->Start());
1363 conditionalExpr->SetTest(rightExpr);
1364 return conditionalExpr;
1365 }
1366
1367 return rightExpr;
1368 }
1369
ParseCallExpressionArguments(bool & trailingComma)1370 ArenaVector<ir::Expression *> ParserImpl::ParseCallExpressionArguments(bool &trailingComma)
1371 {
1372 ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
1373
1374 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
1375 lexer_->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE)) {
1376 arguments = std::move(ParseExpressionsArrayFormatPlaceholder());
1377 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1378 ThrowSyntaxError("Expected a ')'");
1379 }
1380 } else {
1381 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1382 trailingComma = false;
1383 ir::Expression *argument {};
1384 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1385 argument = ParseSpreadElement();
1386 } else {
1387 argument = ParseExpression();
1388 }
1389
1390 arguments.push_back(argument);
1391
1392 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1393 lexer_->NextToken();
1394 trailingComma = true;
1395 } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1396 ThrowSyntaxError("Expected a ')'");
1397 }
1398 }
1399 }
1400
1401 return arguments;
1402 }
1403
ParseCallExpression(ir::Expression * callee,bool isOptionalChain,bool handleEval)1404 ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool isOptionalChain, bool handleEval)
1405 {
1406 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1407 bool trailingComma {};
1408
1409 while (true) {
1410 lexer_->NextToken();
1411 ArenaVector<ir::Expression *> arguments = ParseCallExpressionArguments(trailingComma);
1412 ir::CallExpression *callExpr {};
1413
1414 if (!isOptionalChain && handleEval && callee->IsIdentifier() && callee->AsIdentifier()->Name().Is("eval")) {
1415 auto parserStatus = static_cast<uint32_t>(context_.Status() | ParserStatus::DIRECT_EVAL);
1416 callExpr = AllocNode<ir::DirectEvalExpression>(callee, std::move(arguments), nullptr, isOptionalChain,
1417 parserStatus);
1418 } else {
1419 callExpr =
1420 AllocNode<ir::CallExpression>(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma);
1421 }
1422
1423 callExpr->SetRange({callee->Start(), lexer_->GetToken().End()});
1424 isOptionalChain = false;
1425
1426 lexer_->NextToken();
1427
1428 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1429 ParseTrailingBlock(callExpr);
1430 return callExpr;
1431 }
1432
1433 callee = callExpr;
1434 }
1435
1436 UNREACHABLE();
1437 }
1438
ParseOptionalChain(ir::Expression * leftSideExpr)1439 ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr)
1440 {
1441 ir::Expression *returnExpression = nullptr;
1442
1443 bool isPrivate = false;
1444
1445 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1446 isPrivate = true;
1447 ValidatePrivateIdentifier();
1448 }
1449
1450 const auto tokenType = lexer_->GetToken().Type();
1451 if (tokenType == lexer::TokenType::LITERAL_IDENT) {
1452 auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1453 identNode->SetReference();
1454 identNode->SetPrivate(isPrivate);
1455 identNode->SetRange(lexer_->GetToken().Loc());
1456
1457 returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, identNode,
1458 ir::MemberExpressionKind::PROPERTY_ACCESS, false, true);
1459 returnExpression->SetRange({leftSideExpr->Start(), identNode->End()});
1460 lexer_->NextToken();
1461 }
1462
1463 if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1464 lexer_->NextToken(); // eat '['
1465 ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1466
1467 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1468 ThrowSyntaxError("Unexpected token");
1469 }
1470
1471 returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, propertyNode,
1472 ir::MemberExpressionKind::ELEMENT_ACCESS, true, true);
1473 returnExpression->SetRange({leftSideExpr->Start(), lexer_->GetToken().End()});
1474 lexer_->NextToken();
1475 }
1476
1477 if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1478 returnExpression = ParseCallExpression(leftSideExpr, true);
1479 }
1480
1481 // Static semantic
1482 if (tokenType == lexer::TokenType::PUNCTUATOR_BACK_TICK ||
1483 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1484 ThrowSyntaxError("Tagged Template Literals are not allowed in optionalChain");
1485 }
1486
1487 return returnExpression;
1488 }
1489
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)1490 ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expression **returnExpression,
1491 const lexer::SourcePosition &startLoc)
1492 {
1493 switch (lexer_->GetToken().Type()) {
1494 case lexer::TokenType::KEYW_FUNCTION: {
1495 *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
1496 (*returnExpression)->SetStart(startLoc);
1497 break;
1498 }
1499 case lexer::TokenType::LITERAL_IDENT: {
1500 ir::Expression *identRef = ParsePrimaryExpression();
1501 ASSERT(identRef->IsIdentifier());
1502
1503 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1504 ThrowSyntaxError("Unexpected token, expected '=>'");
1505 }
1506
1507 ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
1508 arrowFuncExpr->SetStart(startLoc);
1509
1510 return arrowFuncExpr;
1511 }
1512 case lexer::TokenType::PUNCTUATOR_ARROW: {
1513 ir::ArrowFunctionExpression *arrowFuncExpr =
1514 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
1515 arrowFuncExpr->SetStart(startLoc);
1516 return arrowFuncExpr;
1517 }
1518 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1519 ir::CallExpression *callExpression = ParseCallExpression(*returnExpression, false);
1520
1521 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1522 ir::ArrowFunctionExpression *arrowFuncExpr =
1523 ParseArrowFunctionExpression(callExpression, nullptr, nullptr, true);
1524 arrowFuncExpr->SetStart(startLoc);
1525
1526 return arrowFuncExpr;
1527 }
1528
1529 *returnExpression = callExpression;
1530 break;
1531 }
1532 default: {
1533 break;
1534 }
1535 }
1536
1537 return nullptr;
1538 }
1539
ParsePotentialGenericFunctionCall(ir::Expression * primaryExpr,ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1540 bool ParserImpl::ParsePotentialGenericFunctionCall([[maybe_unused]] ir::Expression *primaryExpr,
1541 [[maybe_unused]] ir::Expression **returnExpression,
1542 [[maybe_unused]] const lexer::SourcePosition &startLoc,
1543 [[maybe_unused]] bool ignoreCallExpression)
1544 {
1545 return true;
1546 }
1547
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)1548 bool ParserImpl::ParsePotentialNonNullExpression([[maybe_unused]] ir::Expression **returnExpression,
1549 [[maybe_unused]] lexer::SourcePosition startLoc)
1550 {
1551 return true;
1552 }
1553
ParsePotentialAsExpression(ir::Expression * primaryExpression)1554 ir::Expression *ParserImpl::ParsePotentialAsExpression([[maybe_unused]] ir::Expression *primaryExpression)
1555 {
1556 return nullptr;
1557 }
1558
ParseElementAccess(ir::Expression * primaryExpr,bool isOptional)1559 ir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr, bool isOptional)
1560 {
1561 lexer_->NextToken(); // eat '['
1562 ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1563
1564 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1565 ThrowSyntaxError("Unexpected token");
1566 }
1567
1568 auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, propertyNode,
1569 ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional);
1570 memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()});
1571 lexer_->NextToken();
1572 return memberExpr;
1573 }
1574
ParsePrivatePropertyAccess(ir::Expression * primaryExpr)1575 ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *primaryExpr)
1576 {
1577 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK);
1578
1579 lexer::SourcePosition memberStart = lexer_->GetToken().Start();
1580 ValidatePrivateIdentifier();
1581
1582 auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1583 privateIdent->SetRange({memberStart, lexer_->GetToken().End()});
1584 privateIdent->SetPrivate(true);
1585 privateIdent->SetReference();
1586 lexer_->NextToken();
1587
1588 auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, privateIdent,
1589 ir::MemberExpressionKind::PROPERTY_ACCESS, false, false);
1590 memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()});
1591 return memberExpr;
1592 }
1593
ParsePropertyAccess(ir::Expression * primaryExpr,bool isOptional)1594 ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExpr, bool isOptional)
1595 {
1596 ir::Identifier *ident = ExpectIdentifier(true);
1597
1598 auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS,
1599 false, isOptional);
1600 memberExpr->SetRange({primaryExpr->Start(), ident->End()});
1601
1602 return memberExpr;
1603 }
1604
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)1605 ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
1606 bool ignoreCallExpression, bool *isChainExpression)
1607 {
1608 ir::Expression *returnExpr = primaryExpr;
1609 while (true) {
1610 switch (lexer_->GetToken().Type()) {
1611 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1612 returnExpr = ParseElementAccess(returnExpr);
1613 continue;
1614 }
1615 case lexer::TokenType::LITERAL_IDENT: {
1616 if (auto *asExpression = ParsePotentialAsExpression(returnExpr); asExpression != nullptr) {
1617 return asExpression;
1618 }
1619 break;
1620 }
1621 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1622 case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1623 if (ParsePotentialGenericFunctionCall(primaryExpr, &returnExpr, startLoc, ignoreCallExpression)) {
1624 break;
1625 }
1626 continue;
1627 }
1628 case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1629 returnExpr = ParsePostPrimaryExpressionBackTick(returnExpr, startLoc);
1630 continue;
1631 }
1632 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1633 if (ignoreCallExpression) {
1634 break;
1635 }
1636 returnExpr = ParseCallExpression(returnExpr, false);
1637 continue;
1638 }
1639 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
1640 if (ParsePotentialNonNullExpression(&returnExpr, startLoc)) {
1641 break;
1642 }
1643 continue;
1644 }
1645 default: {
1646 auto tmp = ParsePostPrimaryExpressionDot(returnExpr, lexer_->GetToken().Type(), isChainExpression);
1647 if (tmp != nullptr) {
1648 returnExpr = tmp;
1649 continue;
1650 }
1651 }
1652 }
1653 break;
1654 }
1655 return returnExpr;
1656 }
1657
ParsePostPrimaryExpressionBackTick(ir::Expression * returnExpression,const lexer::SourcePosition startLoc)1658 ir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *returnExpression,
1659 const lexer::SourcePosition startLoc)
1660 {
1661 ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
1662 lexer::SourcePosition endLoc = propertyNode->End();
1663
1664 returnExpression = AllocNode<ir::TaggedTemplateExpression>(returnExpression, propertyNode, nullptr);
1665 returnExpression->SetRange({startLoc, endLoc});
1666
1667 return returnExpression;
1668 }
1669
ParsePostPrimaryExpressionDot(ir::Expression * returnExpression,const lexer::TokenType tokenType,bool * isChainExpression)1670 ir::Expression *ParserImpl::ParsePostPrimaryExpressionDot(ir::Expression *returnExpression,
1671 const lexer::TokenType tokenType, bool *isChainExpression)
1672 {
1673 switch (tokenType) {
1674 case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: {
1675 *isChainExpression = true;
1676 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat ?.
1677 return ParseOptionalChain(returnExpression);
1678 }
1679 case lexer::TokenType::PUNCTUATOR_PERIOD: {
1680 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat period
1681
1682 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1683 return ParsePrivatePropertyAccess(returnExpression);
1684 }
1685
1686 return ParsePropertyAccess(returnExpression);
1687 }
1688 default: {
1689 break;
1690 }
1691 }
1692
1693 return nullptr;
1694 }
1695
ValidateUpdateExpression(ir::Expression * returnExpression,bool isChainExpression)1696 void ParserImpl::ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression)
1697 {
1698 if ((!returnExpression->IsMemberExpression() && !returnExpression->IsIdentifier() &&
1699 !returnExpression->IsTSNonNullExpression()) ||
1700 isChainExpression) {
1701 ThrowSyntaxError("Invalid left-hand side operator.");
1702 }
1703
1704 if (returnExpression->IsIdentifier()) {
1705 const util::StringView &returnExpressionStr = returnExpression->AsIdentifier()->Name();
1706
1707 if (returnExpressionStr.Is("eval")) {
1708 ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid");
1709 }
1710
1711 if (returnExpressionStr.Is("arguments")) {
1712 ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid");
1713 }
1714 }
1715 }
1716
SetupChainExpr(ir::Expression * const top,lexer::SourcePosition startLoc)1717 ir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::SourcePosition startLoc)
1718 {
1719 auto expr = top;
1720 while (expr->IsTSNonNullExpression()) {
1721 expr = expr->AsTSNonNullExpression()->Expr();
1722 }
1723 auto chainParent = expr->Parent();
1724
1725 lexer::SourcePosition endLoc = expr->End();
1726 auto chain = AllocNode<ir::ChainExpression>(expr);
1727 chain->SetRange({startLoc, endLoc});
1728
1729 if (expr == top) {
1730 return chain;
1731 }
1732 chainParent->AsTSNonNullExpression()->SetExpr(chain);
1733 chain->SetParent(chainParent);
1734 return top;
1735 }
1736
ParseMemberExpression(bool ignoreCallExpression,ExpressionParseFlags flags)1737 ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, ExpressionParseFlags flags)
1738 {
1739 bool isAsync = lexer_->GetToken().IsAsyncModifier();
1740 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1741 ir::Expression *returnExpression = ParsePrimaryExpression(flags);
1742
1743 if (lexer_->GetToken().NewLine() && returnExpression->IsArrowFunctionExpression()) {
1744 return returnExpression;
1745 }
1746
1747 if (isAsync && !lexer_->GetToken().NewLine()) {
1748 context_.Status() |= ParserStatus::ASYNC_FUNCTION;
1749 ir::ArrowFunctionExpression *arrow = ParsePotentialArrowExpression(&returnExpression, startLoc);
1750
1751 if (arrow != nullptr) {
1752 return arrow;
1753 }
1754 }
1755
1756 bool isChainExpression;
1757 ir::Expression *prevExpression;
1758 do {
1759 isChainExpression = false;
1760 prevExpression = returnExpression;
1761 returnExpression =
1762 ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression);
1763 if (isChainExpression) {
1764 returnExpression = SetupChainExpr(returnExpression, startLoc);
1765 }
1766 } while (prevExpression != returnExpression);
1767
1768 if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) {
1769 lexer::SourcePosition start = returnExpression->Start();
1770
1771 ValidateUpdateExpression(returnExpression, isChainExpression);
1772
1773 returnExpression = AllocNode<ir::UpdateExpression>(returnExpression, lexer_->GetToken().Type(), false);
1774
1775 returnExpression->SetRange({start, lexer_->GetToken().End()});
1776 lexer_->NextToken();
1777 }
1778
1779 return returnExpression;
1780 }
1781
1782 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault)1783 ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
1784 {
1785 ir::Expression *returnNode = nullptr;
1786
1787 switch (lexer_->GetToken().Type()) {
1788 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1789 returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1790 break;
1791 }
1792 case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
1793 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
1794 ThrowSyntaxError("Unexpected token");
1795 }
1796 returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1797 break;
1798 }
1799 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1800 returnNode =
1801 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
1802 break;
1803 }
1804 case lexer::TokenType::LITERAL_IDENT: {
1805 returnNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1806 returnNode->AsIdentifier()->SetReference();
1807 returnNode->SetRange(lexer_->GetToken().Loc());
1808 lexer_->NextToken();
1809 break;
1810 }
1811 default: {
1812 ThrowSyntaxError("Unexpected token, expected an identifier.");
1813 }
1814 }
1815
1816 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1817 return returnNode;
1818 }
1819
1820 ParsePatternElementErrorCheck(flags, allowDefault);
1821
1822 ir::Expression *rightNode = ParseExpression();
1823
1824 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1825 ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1826 assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
1827
1828 return assignmentExpression;
1829 }
1830
ParsePatternElementErrorCheck(const ExpressionParseFlags flags,const bool allowDefault)1831 void ParserImpl::ParsePatternElementErrorCheck(const ExpressionParseFlags flags, const bool allowDefault)
1832 {
1833 if ((flags & ExpressionParseFlags::IN_REST) != 0) {
1834 ThrowSyntaxError("Unexpected token, expected ')'");
1835 }
1836
1837 if (!allowDefault) {
1838 ThrowSyntaxError("Invalid destructuring assignment target");
1839 }
1840
1841 lexer_->NextToken();
1842
1843 if (context_.IsGenerator() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
1844 ThrowSyntaxError("Yield is not allowed in generator parameters");
1845 }
1846
1847 if (context_.IsAsync() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_AWAIT) {
1848 ThrowSyntaxError("Illegal await-expression in formal parameters of async function");
1849 }
1850 }
1851
CheckPropertyKeyAsyncModifier(ParserStatus * methodStatus)1852 void ParserImpl::CheckPropertyKeyAsyncModifier(ParserStatus *methodStatus)
1853 {
1854 const auto asyncPos = lexer_->Save();
1855 lexer_->NextToken();
1856
1857 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1858 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
1859 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1860 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1861 if (lexer_->GetToken().NewLine()) {
1862 ThrowSyntaxError(
1863 "Async methods cannot have a line terminator between "
1864 "'async' and the property name");
1865 }
1866
1867 *methodStatus |= ParserStatus::ASYNC_FUNCTION;
1868 } else {
1869 lexer_->Rewind(asyncPos);
1870 }
1871 }
1872
IsAccessorDelimiter(char32_t cp)1873 static bool IsAccessorDelimiter(char32_t cp)
1874 {
1875 switch (cp) {
1876 case lexer::LEX_CHAR_LEFT_PAREN:
1877 case lexer::LEX_CHAR_COLON:
1878 case lexer::LEX_CHAR_COMMA:
1879 case lexer::LEX_CHAR_RIGHT_BRACE: {
1880 return true;
1881 }
1882 default: {
1883 return false;
1884 }
1885 }
1886 }
1887
IsShorthandDelimiter(char32_t cp)1888 static bool IsShorthandDelimiter(char32_t cp)
1889 {
1890 switch (cp) {
1891 case lexer::LEX_CHAR_EQUALS:
1892 case lexer::LEX_CHAR_COMMA:
1893 case lexer::LEX_CHAR_RIGHT_BRACE: {
1894 return true;
1895 }
1896 default: {
1897 return false;
1898 }
1899 }
1900 }
1901
ValidateAccessor(ExpressionParseFlags flags,lexer::TokenFlags currentTokenFlags)1902 void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags)
1903 {
1904 if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
1905 ThrowSyntaxError("Unexpected token");
1906 }
1907
1908 if ((currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) {
1909 ThrowSyntaxError("Keyword must not contain escaped characters");
1910 }
1911 }
1912
ParseShorthandProperty(const lexer::LexerPosition * startPos)1913 ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos)
1914 {
1915 char32_t nextCp = lexer_->Lookahead();
1916 lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
1917
1918 /* Rewind the lexer to the beginning of the ident to reparse as common
1919 * identifier */
1920 lexer_->Rewind(*startPos);
1921 lexer_->NextToken();
1922 lexer::SourcePosition start = lexer_->GetToken().Start();
1923
1924 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1925 ThrowSyntaxError("Expected an identifier");
1926 }
1927
1928 const util::StringView &ident = lexer_->GetToken().Ident();
1929
1930 auto *key = AllocNode<ir::Identifier>(ident, Allocator());
1931 key->SetRange(lexer_->GetToken().Loc());
1932
1933 ir::Expression *value = AllocNode<ir::Identifier>(ident, Allocator());
1934 value->AsIdentifier()->SetReference();
1935 value->SetRange(lexer_->GetToken().Loc());
1936
1937 lexer::SourcePosition end;
1938
1939 if (nextCp == lexer::LEX_CHAR_EQUALS) {
1940 CheckRestrictedBinding(keywordType);
1941
1942 lexer_->NextToken(); // substitution
1943 lexer_->NextToken(); // eat substitution
1944
1945 ir::Expression *rightNode = ParseExpression();
1946
1947 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1948 ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1949 assignmentExpression->SetRange({value->Start(), rightNode->End()});
1950 end = rightNode->End();
1951 value = assignmentExpression;
1952 } else {
1953 end = lexer_->GetToken().End();
1954 lexer_->NextToken();
1955 }
1956
1957 auto *returnProperty = AllocNode<ir::Property>(key, value);
1958 returnProperty->SetRange({start, end});
1959
1960 return returnProperty;
1961 }
1962
ParsePropertyModifiers(ExpressionParseFlags flags,ir::PropertyKind * propertyKind,ParserStatus * methodStatus)1963 bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::PropertyKind *propertyKind,
1964 ParserStatus *methodStatus)
1965 {
1966 if (lexer_->GetToken().IsAsyncModifier()) {
1967 CheckPropertyKeyAsyncModifier(methodStatus);
1968 }
1969
1970 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1971 if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
1972 ThrowSyntaxError("Unexpected token");
1973 }
1974
1975 lexer_->NextToken();
1976 *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
1977 }
1978
1979 lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags();
1980 char32_t nextCp = lexer_->Lookahead();
1981 lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
1982 // Parse getter property
1983 if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) {
1984 ValidateAccessor(flags, currentTokenFlags);
1985
1986 *propertyKind = ir::PropertyKind::GET;
1987 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1988
1989 return false;
1990 }
1991
1992 // Parse setter property
1993 if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) {
1994 ValidateAccessor(flags, currentTokenFlags);
1995
1996 *propertyKind = ir::PropertyKind::SET;
1997 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1998
1999 return false;
2000 }
2001
2002 // Parse shorthand property or assignment pattern
2003 return (IsShorthandDelimiter(nextCp) && (*methodStatus & ParserStatus::ASYNC_FUNCTION) == 0);
2004 }
2005
ParseGeneratorPropertyModifier(ExpressionParseFlags flags,ParserStatus * methodStatus)2006 void ParserImpl::ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus)
2007 {
2008 if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
2009 ThrowSyntaxError("Unexpected token");
2010 }
2011
2012 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2013 *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
2014 }
2015
ParsePropertyKey(ExpressionParseFlags flags)2016 ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags)
2017 {
2018 ir::Expression *key = nullptr;
2019
2020 switch (lexer_->GetToken().Type()) {
2021 case lexer::TokenType::LITERAL_IDENT: {
2022 const util::StringView &ident = lexer_->GetToken().Ident();
2023 key = AllocNode<ir::Identifier>(ident, Allocator());
2024 key->SetRange(lexer_->GetToken().Loc());
2025 break;
2026 }
2027 case lexer::TokenType::LITERAL_STRING: {
2028 const util::StringView &string = lexer_->GetToken().String();
2029 key = AllocNode<ir::StringLiteral>(string);
2030 key->SetRange(lexer_->GetToken().Loc());
2031 break;
2032 }
2033 case lexer::TokenType::LITERAL_NUMBER: {
2034 if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
2035 key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
2036 } else {
2037 key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber());
2038 }
2039
2040 key->SetRange(lexer_->GetToken().Loc());
2041 break;
2042 }
2043 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
2044 lexer_->NextToken(); // eat left square bracket
2045
2046 key = ParseExpression(flags | ExpressionParseFlags::ACCEPT_COMMA);
2047
2048 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2049 ThrowSyntaxError("Unexpected token, expected ']'");
2050 }
2051 break;
2052 }
2053 default: {
2054 ThrowSyntaxError("Unexpected token in property key");
2055 }
2056 }
2057
2058 lexer_->NextToken();
2059 return key;
2060 }
2061
ParsePropertyValue(const ir::PropertyKind * propertyKind,const ParserStatus * methodStatus,ExpressionParseFlags flags)2062 ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyKind, const ParserStatus *methodStatus,
2063 ExpressionParseFlags flags)
2064 {
2065 bool isMethod = (*methodStatus & ParserStatus::FUNCTION) != 0;
2066 bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
2067
2068 if (!isMethod && !ir::Property::IsAccessorKind(*propertyKind)) {
2069 // If the actual property is not getter/setter nor method, the following
2070 // token must be ':'
2071 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2072 ThrowSyntaxError("Unexpected token, expected ':'");
2073 }
2074
2075 lexer_->NextToken(); // eat colon
2076
2077 if (!inPattern) {
2078 return ParseExpression(flags);
2079 }
2080
2081 return ParsePatternElement();
2082 }
2083
2084 if (inPattern) {
2085 ThrowSyntaxError("Object pattern can't contain methods");
2086 }
2087
2088 ParserStatus newStatus = *methodStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2089
2090 if (*propertyKind != ir::PropertyKind::SET) {
2091 newStatus |= ParserStatus::NEED_RETURN_TYPE;
2092 }
2093
2094 ir::ScriptFunction *methodDefinitonNode = ParseFunction(newStatus);
2095 methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD);
2096
2097 size_t paramsSize = methodDefinitonNode->Params().size();
2098
2099 auto *value = AllocNode<ir::FunctionExpression>(methodDefinitonNode);
2100 value->SetRange(methodDefinitonNode->Range());
2101
2102 if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) {
2103 ThrowSyntaxError("Setter must have exactly one formal parameter");
2104 }
2105
2106 if (*propertyKind == ir::PropertyKind::GET && paramsSize != 0) {
2107 ThrowSyntaxError("Getter must not have formal parameters");
2108 }
2109
2110 return value;
2111 }
2112
2113 // NOLINTNEXTLINE(google-default-arguments)
ParsePropertyDefinition(ExpressionParseFlags flags)2114 ir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)
2115 {
2116 ir::PropertyKind propertyKind = ir::PropertyKind::INIT;
2117 ParserStatus methodStatus = ParserStatus::NO_OPTS;
2118
2119 const auto startPos = lexer_->Save();
2120 lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2121 lexer::SourcePosition start = lexer_->GetToken().Start();
2122
2123 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2124 return ParseSpreadElement(flags);
2125 }
2126
2127 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
2128 if (ParsePropertyModifiers(flags, &propertyKind, &methodStatus)) {
2129 return ParseShorthandProperty(&startPos);
2130 }
2131 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2132 ParseGeneratorPropertyModifier(flags, &methodStatus);
2133 }
2134
2135 bool isComputed = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET;
2136 ir::Expression *key = ParsePropertyKey(flags);
2137
2138 // Parse method property
2139 if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
2140 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) &&
2141 !ir::Property::IsAccessorKind(propertyKind)) {
2142 methodStatus |= ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2143 propertyKind = ir::PropertyKind::INIT;
2144 } else if ((methodStatus & (ParserStatus::GENERATOR_FUNCTION | ParserStatus::ASYNC_FUNCTION)) != 0) {
2145 ThrowSyntaxError("Unexpected identifier");
2146 }
2147
2148 ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags);
2149 lexer::SourcePosition end = value->End();
2150
2151 ASSERT(key);
2152 ASSERT(value);
2153
2154 auto *returnProperty =
2155 AllocNode<ir::Property>(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed);
2156 returnProperty->SetRange({start, end});
2157
2158 return returnProperty;
2159 }
2160
ParsePropertyEnd()2161 bool ParserImpl::ParsePropertyEnd()
2162 {
2163 // Property definiton must end with ',' or '}' otherwise we throw SyntaxError
2164 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
2165 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2166 ThrowSyntaxError("Unexpected token, expected ',' or '}'");
2167 }
2168
2169 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
2170 lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) {
2171 lexer_->NextToken();
2172 return true;
2173 }
2174
2175 return false;
2176 }
2177
2178 // NOLINTNEXTLINE(google-default-arguments)
ParseObjectExpression(ExpressionParseFlags flags)2179 ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags flags)
2180 {
2181 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
2182 lexer::SourcePosition start = lexer_->GetToken().Start();
2183 ArenaVector<ir::Expression *> properties(Allocator()->Adapter());
2184 bool trailingComma = false;
2185 bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
2186
2187 if (lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) {
2188 lexer_->NextToken();
2189 }
2190
2191 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2192 ir::Expression *property = ParsePropertyDefinition(flags | ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
2193 properties.push_back(property);
2194 trailingComma = ParsePropertyEnd();
2195 }
2196
2197 auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION;
2198 auto *objectExpression =
2199 AllocNode<ir::ObjectExpression>(nodeType, Allocator(), std::move(properties), trailingComma);
2200 objectExpression->SetRange({start, lexer_->GetToken().End()});
2201 lexer_->NextToken();
2202
2203 if (inPattern) {
2204 objectExpression->SetDeclaration();
2205 }
2206
2207 if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) {
2208 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
2209 !objectExpression->ConvertibleToObjectPattern()) {
2210 ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", objectExpression->Start());
2211 } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2212 ir::ValidationInfo info = objectExpression->ValidateExpression();
2213 if (info.Fail()) {
2214 ThrowSyntaxError(info.msg.Utf8(), info.pos);
2215 }
2216 }
2217 }
2218
2219 return objectExpression;
2220 }
2221
ParseSequenceExpression(ir::Expression * startExpr,bool acceptRest)2222 ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *startExpr, bool acceptRest)
2223 {
2224 lexer::SourcePosition start = startExpr->Start();
2225
2226 ArenaVector<ir::Expression *> sequence(Allocator()->Adapter());
2227 sequence.push_back(startExpr);
2228
2229 while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2230 lexer_->NextToken();
2231
2232 if (acceptRest && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2233 ir::SpreadElement *expr = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
2234 sequence.push_back(expr);
2235 break;
2236 }
2237
2238 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && lexer_->CheckArrow()) {
2239 break;
2240 }
2241
2242 sequence.push_back(ParseExpression());
2243 }
2244
2245 lexer::SourcePosition end = sequence.back()->End();
2246 auto *sequenceNode = AllocNode<ir::SequenceExpression>(std::move(sequence));
2247 sequenceNode->SetRange({start, end});
2248
2249 return sequenceNode;
2250 }
2251
2252 // NOLINTNEXTLINE(google-default-arguments)
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)2253 ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
2254 {
2255 if (!lexer_->GetToken().IsUnary()) {
2256 return ParseLeftHandSideExpression(flags);
2257 }
2258
2259 lexer::TokenType operatorType = lexer_->GetToken().Type();
2260 lexer::SourcePosition start = lexer_->GetToken().Start();
2261 lexer_->NextToken();
2262
2263 ir::Expression *argument =
2264 lexer_->GetToken().IsUnary() ? ParseUnaryOrPrefixUpdateExpression() : ParseLeftHandSideExpression();
2265
2266 if (lexer::Token::IsUpdateToken(operatorType)) {
2267 if (!argument->IsIdentifier() && !argument->IsMemberExpression() && !argument->IsTSNonNullExpression()) {
2268 ThrowSyntaxError("Invalid left-hand side in prefix operation");
2269 }
2270
2271 if (argument->IsIdentifier()) {
2272 const util::StringView &argumentStr = argument->AsIdentifier()->Name();
2273
2274 if (argumentStr.Is("eval")) {
2275 ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid");
2276 } else if (argumentStr.Is("arguments")) {
2277 ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid");
2278 }
2279 }
2280 }
2281
2282 if (operatorType == lexer::TokenType::KEYW_DELETE) {
2283 if (argument->IsIdentifier()) {
2284 ThrowSyntaxError("Deleting local variable in strict mode");
2285 }
2286
2287 if (argument->IsMemberExpression() && argument->AsMemberExpression()->Property()->IsIdentifier() &&
2288 argument->AsMemberExpression()->Property()->AsIdentifier()->IsPrivateIdent()) {
2289 ThrowSyntaxError("Private fields can not be deleted");
2290 }
2291 }
2292
2293 lexer::SourcePosition end = argument->End();
2294
2295 ir::Expression *returnExpr = nullptr;
2296
2297 if (lexer::Token::IsUpdateToken(operatorType)) {
2298 returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true);
2299 } else if (operatorType == lexer::TokenType::KEYW_AWAIT) {
2300 returnExpr = AllocNode<ir::AwaitExpression>(argument);
2301 } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) {
2302 returnExpr = AllocNode<ir::TypeofExpression>(argument);
2303 } else {
2304 returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType);
2305 }
2306
2307 returnExpr->SetRange({start, end});
2308
2309 return returnExpr;
2310 }
2311
ParseImportExpression()2312 ir::Expression *ParserImpl::ParseImportExpression()
2313 {
2314 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2315 lexer::SourcePosition endLoc = lexer_->GetToken().End();
2316 lexer_->NextToken(); // eat import
2317
2318 // parse import.Meta
2319 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
2320 if (!context_.IsModule()) {
2321 ThrowSyntaxError("'import.Meta' may appear only with 'sourceType: module'");
2322 } else if (GetOptions().isDirectEval) {
2323 ThrowSyntaxError("'import.Meta' is not allowed in direct eval in module code.");
2324 }
2325
2326 lexer_->NextToken(); // eat dot
2327
2328 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT ||
2329 lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_META) {
2330 ThrowSyntaxError("The only valid meta property for import is import.Meta");
2331 }
2332
2333 auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::IMPORT_META);
2334 metaProperty->SetRange({startLoc, endLoc});
2335
2336 lexer_->NextToken();
2337 return metaProperty;
2338 }
2339
2340 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
2341 ThrowSyntaxError("Unexpected token");
2342 }
2343
2344 lexer_->NextToken(); // eat left parentheses
2345
2346 ir::Expression *source = ParseExpression();
2347
2348 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
2349 ThrowSyntaxError("Unexpected token");
2350 }
2351
2352 auto *importExpression = AllocNode<ir::ImportExpression>(source);
2353 importExpression->SetRange({startLoc, lexer_->GetToken().End()});
2354
2355 lexer_->NextToken(); // eat right paren
2356 return importExpression;
2357 }
2358
IsNamedFunctionExpression()2359 bool ParserImpl::IsNamedFunctionExpression()
2360 {
2361 return lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS;
2362 }
2363
ParseFunctionExpression(ParserStatus newStatus)2364 ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStatus)
2365 {
2366 lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2367 ir::Identifier *ident = nullptr;
2368
2369 if ((newStatus & ParserStatus::ARROW_FUNCTION) == 0) {
2370 ParserStatus savedStatus = context_.Status();
2371 context_.Status() |= static_cast<ParserStatus>(newStatus & ParserStatus::ASYNC_FUNCTION);
2372
2373 lexer_->NextToken();
2374
2375 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2376 newStatus |= ParserStatus::GENERATOR_FUNCTION;
2377 lexer_->NextToken();
2378 }
2379
2380 if (IsNamedFunctionExpression()) {
2381 CheckRestrictedBinding(lexer_->GetToken().KeywordType());
2382 ident = ExpectIdentifier(false, true);
2383 }
2384
2385 context_.Status() = savedStatus;
2386 }
2387
2388 ir::ScriptFunction *functionNode = ParseFunction(newStatus);
2389 functionNode->SetStart(startLoc);
2390
2391 auto *funcExpr = AllocNode<ir::FunctionExpression>(ident, functionNode);
2392 funcExpr->SetRange(functionNode->Range());
2393
2394 return funcExpr;
2395 }
2396 } // namespace ark::es2panda::parser
2397