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