1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ETSparser.h"
17
18 #include "lexer/lexer.h"
19 #include "ir/typeNode.h"
20 #include "ir/expressions/identifier.h"
21 #include "ir/expressions/blockExpression.h"
22 #include "ir/expressions/sequenceExpression.h"
23 #include "ir/statements/blockStatement.h"
24 #include "ir/statements/expressionStatement.h"
25 #include "ir/base/methodDefinition.h"
26 #include "ir/ts/tsInterfaceBody.h"
27 #include "parser/parserStatusContext.h"
28
29 namespace ark::es2panda::parser {
30 //================================================================================================//
31 // Methods to create AST node(s) from the specified string (part of valid ETS-code!)
32 //================================================================================================//
33
34 // NOLINTBEGIN(modernize-avoid-c-arrays)
35 inline constexpr char const FORMAT_SIGNATURE = '@';
36 inline constexpr char const TYPE_FORMAT_NODE = 'T';
37 inline constexpr char const GENERAL_FORMAT_NODE = 'N';
38 inline constexpr char const IDENTIFIER_FORMAT_NODE = 'I';
39
40 static constexpr char const INVALID_NUMBER_NODE[] = "Invalid node number in format expression.";
41 static constexpr char const INVALID_FORMAT_NODE[] = "Invalid node type in format expression.";
42 static constexpr char const INSERT_NODE_ABSENT[] = "There is no any node to insert at the placeholder position.";
43 static constexpr char const INVALID_INSERT_NODE[] =
44 "Inserting node type differs from that required by format specification.";
45 static constexpr char const INVALID_CLASS_FIELD[] = "Cannot parse class field definition property.";
46 static constexpr char const INVALID_CLASS_METHOD[] = "Cannot parse class method definition property.";
47 // NOLINTEND(modernize-avoid-c-arrays)
48
GetFormatPlaceholderType() const49 ParserImpl::NodeFormatType ETSParser::GetFormatPlaceholderType() const
50 {
51 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT);
52 Lexer()->NextToken();
53
54 bool isArray = false;
55 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
56 isArray = true;
57 Lexer()->NextToken();
58 }
59
60 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT);
61 char const *const identData = Lexer()->GetToken().Ident().Bytes();
62
63 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic, cert-err34-c)
64 auto identNumber = std::atoi(identData + 1U);
65 if (identNumber <= 0) {
66 ThrowSyntaxError(INVALID_NUMBER_NODE, Lexer()->GetToken().Start());
67 }
68
69 return {isArray, *identData,
70 static_cast<decltype(std::get<2>(std::declval<ParserImpl::NodeFormatType>()))>(identNumber - 1)};
71 }
72
ParseExpressionFormatPlaceholder()73 ir::Expression *ETSParser::ParseExpressionFormatPlaceholder()
74 {
75 if (insertingNodes_.empty()) {
76 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
77 }
78
79 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
80 if (std::get<0>(nodeFormat)) {
81 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
82 }
83
84 if (auto const placeholderType = std::get<1>(nodeFormat); placeholderType == TYPE_FORMAT_NODE) {
85 return ParseTypeFormatPlaceholder(std::make_optional(std::move(nodeFormat)));
86 } else if (placeholderType == IDENTIFIER_FORMAT_NODE) { // NOLINT(readability-else-after-return)
87 return ParseIdentifierFormatPlaceholder(std::make_optional(std::move(nodeFormat)));
88 } else if (placeholderType != EXPRESSION_FORMAT_NODE) { // NOLINT(readability-else-after-return)
89 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
90 }
91
92 auto const placeholderNumber = std::get<2>(nodeFormat);
93 auto *const insertingNode =
94 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
95 if (insertingNode == nullptr || !insertingNode->IsExpression()) {
96 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
97 }
98
99 auto *const insertExpression = insertingNode->AsExpression();
100 Lexer()->NextToken();
101 return insertExpression;
102 }
103
ParseTypeFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)104 ir::TypeNode *ETSParser::ParseTypeFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)
105 {
106 if (!nodeFormat.has_value()) {
107 if (insertingNodes_.empty()) {
108 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
109 }
110
111 nodeFormat = GetFormatPlaceholderType();
112 if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != TYPE_FORMAT_NODE) {
113 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
114 }
115 }
116
117 auto const placeholderNumber = std::get<2>(*nodeFormat);
118 auto *const insertingNode =
119 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
120 if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsTypeNode()) {
121 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
122 }
123
124 auto *const insertType = insertingNode->AsExpression()->AsTypeNode();
125 Lexer()->NextToken();
126 return insertType;
127 }
128
ParseIdentifierFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat) const129 ir::Identifier *ETSParser::ParseIdentifierFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat) const
130 {
131 if (!nodeFormat.has_value()) {
132 if (insertingNodes_.empty()) {
133 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
134 }
135
136 nodeFormat = GetFormatPlaceholderType();
137 if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != IDENTIFIER_FORMAT_NODE) {
138 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
139 }
140 }
141
142 auto const placeholderNumber = std::get<2>(*nodeFormat);
143 auto *const insertingNode =
144 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
145 if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsIdentifier()) {
146 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
147 }
148
149 auto *const insertIdentifier = insertingNode->AsExpression()->AsIdentifier();
150 Lexer()->NextToken();
151 return insertIdentifier;
152 }
153
ParseStatementFormatPlaceholder() const154 ir::Statement *ETSParser::ParseStatementFormatPlaceholder() const
155 {
156 if (insertingNodes_.empty()) {
157 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
158 }
159
160 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
161 if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) {
162 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
163 }
164
165 auto const placeholderNumber = std::get<2>(nodeFormat);
166 auto *const insertingNode =
167 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
168 if (insertingNode == nullptr || !insertingNode->IsStatement()) {
169 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
170 }
171
172 Lexer()->NextToken();
173 return insertingNode->AsStatement();
174 }
175
ParseTypeParametersFormatPlaceholder() const176 ir::AstNode *ETSParser::ParseTypeParametersFormatPlaceholder() const
177 {
178 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
179 if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) {
180 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
181 }
182
183 auto const placeholderNumber = std::get<2>(nodeFormat);
184 if (placeholderNumber >= insertingNodes_.size()) {
185 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
186 }
187
188 auto *const insertingNode = insertingNodes_[placeholderNumber];
189 if (insertingNode != nullptr && !insertingNode->IsTSTypeParameterDeclaration() &&
190 !insertingNode->IsTSTypeParameterInstantiation()) {
191 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
192 }
193
194 Lexer()->NextToken();
195 return insertingNode;
196 }
197
ParseAstNodesArrayFormatPlaceholder() const198 ArenaVector<ir::AstNode *> &ETSParser::ParseAstNodesArrayFormatPlaceholder() const
199 {
200 if (insertingNodes_.empty()) {
201 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
202 }
203
204 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
205 if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != GENERAL_FORMAT_NODE) {
206 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
207 }
208
209 auto const placeholderNumber = std::get<2>(nodeFormat);
210 auto *const insertingNode =
211 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
212 if (insertingNode == nullptr || !insertingNode->IsTSInterfaceBody()) {
213 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
214 }
215
216 Lexer()->NextToken();
217 return insertingNode->AsTSInterfaceBody()->Body();
218 }
219
ParseStatementsArrayFormatPlaceholder() const220 ArenaVector<ir::Statement *> &ETSParser::ParseStatementsArrayFormatPlaceholder() const
221 {
222 if (insertingNodes_.empty()) {
223 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
224 }
225
226 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
227 if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) {
228 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
229 }
230
231 auto const placeholderNumber = std::get<2>(nodeFormat);
232 auto *const insertingNode =
233 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
234 if (insertingNode == nullptr || !insertingNode->IsBlockExpression()) {
235 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
236 }
237
238 Lexer()->NextToken();
239 return insertingNode->AsBlockExpression()->Statements();
240 }
241
ParseExpressionsArrayFormatPlaceholder() const242 ArenaVector<ir::Expression *> &ETSParser::ParseExpressionsArrayFormatPlaceholder() const
243 {
244 if (insertingNodes_.empty()) {
245 ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
246 }
247
248 ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
249 if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) {
250 ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
251 }
252
253 auto const placeholderNumber = std::get<2>(nodeFormat);
254 auto *const insertingNode =
255 placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
256 if (insertingNode == nullptr || !insertingNode->IsSequenceExpression()) {
257 ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
258 }
259
260 Lexer()->NextToken();
261 return insertingNode->AsSequenceExpression()->Sequence();
262 }
263
CreateStatement(std::string_view const sourceCode)264 ir::Statement *ETSParser::CreateStatement(std::string_view const sourceCode)
265 {
266 util::UString source {sourceCode, Allocator()};
267 auto const isp = InnerSourceParser(this);
268 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
269
270 lexer::SourcePosition const startLoc = lexer->GetToken().Start();
271 lexer->NextToken();
272
273 auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL);
274 auto const statementNumber = statements.size();
275 if (statementNumber == 0U) {
276 return nullptr;
277 }
278
279 if (statementNumber == 1U) {
280 return statements[0U];
281 }
282
283 auto *const blockStmt = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements));
284 blockStmt->SetRange({startLoc, lexer->GetToken().End()});
285
286 for (auto *statement : blockStmt->Statements()) {
287 statement->SetParent(blockStmt);
288 }
289
290 return blockStmt;
291 }
292
CreateFormattedStatement(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)293 ir::Statement *ETSParser::CreateFormattedStatement(std::string_view const sourceCode,
294 std::vector<ir::AstNode *> &insertingNodes)
295 {
296 insertingNodes_.swap(insertingNodes);
297 auto const statement = CreateStatement(sourceCode);
298 insertingNodes_.swap(insertingNodes);
299 return statement;
300 }
301
CreateStatements(std::string_view const sourceCode)302 ArenaVector<ir::Statement *> ETSParser::CreateStatements(std::string_view const sourceCode)
303 {
304 util::UString source {sourceCode, Allocator()};
305 auto const isp = InnerSourceParser(this);
306 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
307
308 lexer->NextToken();
309 return ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL);
310 }
311
CreateFormattedStatements(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)312 ArenaVector<ir::Statement *> ETSParser::CreateFormattedStatements(std::string_view const sourceCode,
313 std::vector<ir::AstNode *> &insertingNodes)
314 {
315 insertingNodes_.swap(insertingNodes);
316 auto statements = CreateStatements(sourceCode);
317 insertingNodes_.swap(insertingNodes);
318 return statements;
319 }
320
321 // NOTE: this method returns only a single (the first) class filed definition.
322 // It seems that it is possible to have several of them be parsed at a time but nobody knows how...
CreateFormattedClassFieldDefinition(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes)323 ir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sourceCode,
324 std::vector<ir::AstNode *> &insertingNodes)
325 {
326 static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()};
327 insertingNodes_.swap(insertingNodes);
328
329 auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE);
330 if (!property->IsTSInterfaceBody() || property->AsTSInterfaceBody()->Body().empty()) {
331 ThrowSyntaxError(INVALID_CLASS_FIELD);
332 }
333
334 insertingNodes_.swap(insertingNodes);
335 return property->AsTSInterfaceBody()->Body().front();
336 }
337
CreateFormattedClassMethodDefinition(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes)338 ir::AstNode *ETSParser::CreateFormattedClassMethodDefinition(std::string_view sourceCode,
339 std::vector<ir::AstNode *> &insertingNodes)
340 {
341 static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()};
342 insertingNodes_.swap(insertingNodes);
343
344 auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE);
345 if (!property->IsMethodDefinition()) {
346 ThrowSyntaxError(INVALID_CLASS_METHOD);
347 }
348
349 insertingNodes_.swap(insertingNodes);
350 return property;
351 }
352
CreateFormattedClassElement(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes,const ArenaVector<ir::AstNode * > & properties,ir::ClassDefinitionModifiers modifiers)353 ir::AstNode *ETSParser::CreateFormattedClassElement(std::string_view sourceCode,
354 std::vector<ir::AstNode *> &insertingNodes,
355 const ArenaVector<ir::AstNode *> &properties,
356 ir::ClassDefinitionModifiers modifiers)
357 {
358 insertingNodes_.swap(insertingNodes);
359 auto *const classElement = CreateClassElement(sourceCode, properties, modifiers);
360 insertingNodes_.swap(insertingNodes);
361 return classElement;
362 }
363
364 // NOTE: the method has limited functionality - it returns 'ir::TSInterfaceBody' placeholder for the field
365 // declaration(s) (properties themselves are in ->Body() member) and does not perform any check of the node returned.
366 // Also the node isn't placed in the providing properties container.
CreateClassElement(std::string_view sourceCode,const ArenaVector<ir::AstNode * > & properties,ir::ClassDefinitionModifiers modifiers)367 ir::AstNode *ETSParser::CreateClassElement(std::string_view sourceCode, const ArenaVector<ir::AstNode *> &properties,
368 ir::ClassDefinitionModifiers modifiers)
369 {
370 util::UString source {sourceCode, Allocator()};
371 auto const isp = InnerSourceParser(this);
372 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
373
374 auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext());
375 SavedClassPrivateContext classContext(this);
376
377 lexer->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
378
379 return ParseClassElement(properties, modifiers, ir::ModifierFlags::NONE);
380 }
381
CreateFormattedClassDeclaration(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes,bool const allowStatic)382 ir::ClassDeclaration *ETSParser::CreateFormattedClassDeclaration(std::string_view sourceCode,
383 std::vector<ir::AstNode *> &insertingNodes,
384 bool const allowStatic)
385 {
386 insertingNodes_.swap(insertingNodes);
387 auto *const classDeclaration = CreateClassDeclaration(sourceCode, allowStatic);
388 insertingNodes_.swap(insertingNodes);
389 return classDeclaration;
390 }
391
CreateClassDeclaration(std::string_view sourceCode,bool allowStatic)392 ir::ClassDeclaration *ETSParser::CreateClassDeclaration(std::string_view sourceCode, bool allowStatic)
393 {
394 util::UString source {sourceCode, Allocator()};
395 auto const isp = InnerSourceParser(this);
396 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
397
398 auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext());
399
400 auto modifiers = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL;
401 ir::ModifierFlags flags = ir::ModifierFlags::NONE;
402
403 lexer->NextToken();
404
405 switch (auto tokenType = Lexer()->GetToken().Type(); tokenType) {
406 case lexer::TokenType::KEYW_STATIC: {
407 if (!allowStatic) {
408 ThrowUnexpectedToken(Lexer()->GetToken().Type());
409 }
410 [[fallthrough]];
411 }
412 case lexer::TokenType::KEYW_ABSTRACT:
413 case lexer::TokenType::KEYW_FINAL: {
414 flags = ParseClassModifiers();
415 if (allowStatic && (flags & ir::ModifierFlags::STATIC) == 0U) {
416 modifiers |= ir::ClassDefinitionModifiers::INNER;
417 }
418
419 if (auto const tokType = Lexer()->GetToken().Type(); tokType != lexer::TokenType::KEYW_CLASS) {
420 ThrowUnexpectedToken(tokType);
421 }
422 [[fallthrough]];
423 }
424 case lexer::TokenType::KEYW_CLASS: {
425 return ParseClassDeclaration(modifiers);
426 }
427 default: {
428 ThrowUnexpectedToken(tokenType);
429 }
430 }
431 }
432
CreateMethodDefinition(ir::ModifierFlags modifiers,std::string_view const sourceCode)433 ir::MethodDefinition *ETSParser::CreateMethodDefinition(ir::ModifierFlags modifiers, std::string_view const sourceCode)
434 {
435 util::UString source {sourceCode, Allocator()};
436 auto const isp = InnerSourceParser(this);
437 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
438
439 auto const startLoc = Lexer()->GetToken().Start();
440 Lexer()->NextToken();
441
442 if (IsClassMethodModifier(Lexer()->GetToken().Type())) {
443 modifiers |= ParseClassMethodModifiers(false);
444 }
445
446 ir::MethodDefinition *methodDefinition = nullptr;
447 auto *methodName = ExpectIdentifier();
448
449 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
450 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
451 methodDefinition = ParseClassMethodDefinition(methodName, modifiers);
452 methodDefinition->SetStart(startLoc);
453 }
454
455 return methodDefinition;
456 }
457
CreateConstructorDefinition(ir::ModifierFlags modifiers,std::string_view const sourceCode)458 ir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags modifiers,
459 std::string_view const sourceCode)
460 {
461 util::UString source {sourceCode, Allocator()};
462 auto const isp = InnerSourceParser(this);
463 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
464
465 auto const startLoc = Lexer()->GetToken().Start();
466 Lexer()->NextToken();
467
468 if (IsClassMethodModifier(Lexer()->GetToken().Type())) {
469 modifiers |= ParseClassMethodModifiers(false);
470 }
471
472 if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_CONSTRUCTOR) {
473 ThrowSyntaxError({"Unexpected token. 'Constructor' keyword is expected."});
474 }
475
476 if ((modifiers & ir::ModifierFlags::ASYNC) != 0) {
477 ThrowSyntaxError({"Constructor should not be async."});
478 }
479
480 auto *memberName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
481 modifiers |= ir::ModifierFlags::CONSTRUCTOR;
482 Lexer()->NextToken();
483
484 auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers);
485 methodDefinition->SetStart(startLoc);
486
487 return methodDefinition;
488 }
489
CreateExpression(std::string_view const sourceCode,ExpressionParseFlags const flags)490 ir::Expression *ETSParser::CreateExpression(std::string_view const sourceCode, ExpressionParseFlags const flags)
491 {
492 util::UString source {sourceCode, Allocator()};
493 auto const isp = InnerSourceParser(this);
494 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
495
496 lexer::SourcePosition const startLoc = lexer->GetToken().Start();
497 lexer->NextToken();
498
499 ir::Expression *returnExpression = ParseExpression(flags);
500 returnExpression->SetRange({startLoc, lexer->GetToken().End()});
501
502 return returnExpression;
503 }
504
CreateFormattedExpression(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)505 ir::Expression *ETSParser::CreateFormattedExpression(std::string_view const sourceCode,
506 std::vector<ir::AstNode *> &insertingNodes)
507 {
508 ir::Expression *returnExpression;
509 insertingNodes_.swap(insertingNodes);
510
511 if (auto statements = CreateStatements(sourceCode);
512 statements.size() == 1U && statements.back()->IsExpressionStatement()) {
513 returnExpression = statements.back()->AsExpressionStatement()->GetExpression();
514 } else {
515 returnExpression = AllocNode<ir::BlockExpression>(std::move(statements));
516 }
517
518 insertingNodes_.swap(insertingNodes);
519 return returnExpression;
520 }
521
CreateTopLevelStatement(std::string_view const sourceCode)522 ir::Statement *ETSParser::CreateTopLevelStatement(std::string_view const sourceCode)
523 {
524 util::UString source {sourceCode, Allocator()};
525 auto const isp = InnerSourceParser(this);
526 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
527
528 lexer->NextToken();
529
530 return ParseTopLevelStatement();
531 }
532
CreateFormattedTopLevelStatement(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)533 ir::Statement *ETSParser::CreateFormattedTopLevelStatement(std::string_view const sourceCode,
534 std::vector<ir::AstNode *> &insertingNodes)
535 {
536 insertingNodes_.swap(insertingNodes);
537 auto const statement = CreateTopLevelStatement(sourceCode);
538 insertingNodes_.swap(insertingNodes);
539 return statement;
540 }
541
CreateTypeAnnotation(TypeAnnotationParsingOptions * options,std::string_view const sourceCode)542 ir::TypeNode *ETSParser::CreateTypeAnnotation(TypeAnnotationParsingOptions *options, std::string_view const sourceCode)
543 {
544 util::UString source {sourceCode, Allocator()};
545 auto const isp = InnerSourceParser(this);
546 auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
547
548 lexer->NextToken();
549 return ParseTypeAnnotation(options);
550 }
551 } // namespace ark::es2panda::parser
552