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