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