• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()49 ParserImpl::NodeFormatType ETSParser::GetFormatPlaceholderType()
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         LogSyntaxError(INVALID_NUMBER_NODE, Lexer()->GetToken().Start());
67         UNREACHABLE();
68     }
69 
70     return {isArray, *identData,
71             static_cast<decltype(std::get<2>(std::declval<ParserImpl::NodeFormatType>()))>(identNumber - 1)};
72 }
73 
ParseExpressionFormatPlaceholder()74 ir::Expression *ETSParser::ParseExpressionFormatPlaceholder()
75 {
76     if (insertingNodes_.empty()) {
77         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
78         UNREACHABLE();
79     }
80 
81     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
82     if (std::get<0>(nodeFormat)) {
83         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
84         UNREACHABLE();
85     }
86 
87     if (auto const placeholderType = std::get<1>(nodeFormat); placeholderType == TYPE_FORMAT_NODE) {
88         return ParseTypeFormatPlaceholder(std::make_optional(std::move(nodeFormat)));
89     } else if (placeholderType == IDENTIFIER_FORMAT_NODE) {  // NOLINT(readability-else-after-return)
90         return ParseIdentifierFormatPlaceholder(std::make_optional(std::move(nodeFormat)));
91     } else if (placeholderType != EXPRESSION_FORMAT_NODE) {  // NOLINT(readability-else-after-return)
92         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
93         UNREACHABLE();
94     }
95 
96     auto const placeholderNumber = std::get<2>(nodeFormat);
97     auto *const insertingNode =
98         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
99     if (insertingNode == nullptr || !insertingNode->IsExpression()) {
100         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
101         UNREACHABLE();
102     }
103 
104     auto *const insertExpression = insertingNode->AsExpression();
105     Lexer()->NextToken();
106     return insertExpression;
107 }
108 
ParseTypeFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)109 ir::TypeNode *ETSParser::ParseTypeFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)
110 {
111     if (!nodeFormat.has_value()) {
112         if (insertingNodes_.empty()) {
113             LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
114             UNREACHABLE();
115         }
116 
117         nodeFormat = GetFormatPlaceholderType();
118         if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != TYPE_FORMAT_NODE) {
119             LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
120             UNREACHABLE();
121         }
122     }
123 
124     auto const placeholderNumber = std::get<2>(*nodeFormat);
125     auto *const insertingNode =
126         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
127     if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsTypeNode()) {
128         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
129         UNREACHABLE();
130     }
131 
132     auto *const insertType = insertingNode->AsExpression()->AsTypeNode();
133     Lexer()->NextToken();
134     return insertType;
135 }
136 
ParseIdentifierFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)137 ir::Identifier *ETSParser::ParseIdentifierFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat)
138 {
139     if (!nodeFormat.has_value()) {
140         if (insertingNodes_.empty()) {
141             LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
142             UNREACHABLE();
143         }
144 
145         nodeFormat = GetFormatPlaceholderType();
146         if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != IDENTIFIER_FORMAT_NODE) {
147             LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
148             UNREACHABLE();
149         }
150     }
151 
152     auto const placeholderNumber = std::get<2>(*nodeFormat);
153     auto *const insertingNode =
154         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
155     if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsIdentifier()) {
156         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
157         UNREACHABLE();
158     }
159 
160     auto *const insertIdentifier = insertingNode->AsExpression()->AsIdentifier();
161     Lexer()->NextToken();
162     return insertIdentifier;
163 }
164 
ParseStatementFormatPlaceholder()165 ir::Statement *ETSParser::ParseStatementFormatPlaceholder()
166 {
167     if (insertingNodes_.empty()) {
168         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
169         UNREACHABLE();
170     }
171 
172     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
173     if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) {
174         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
175         UNREACHABLE();
176     }
177 
178     auto const placeholderNumber = std::get<2>(nodeFormat);
179     auto *const insertingNode =
180         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
181     if (insertingNode == nullptr || !insertingNode->IsStatement()) {
182         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
183         UNREACHABLE();
184     }
185 
186     Lexer()->NextToken();
187     return insertingNode->AsStatement();
188 }
189 
ParseTypeParametersFormatPlaceholder()190 ir::AstNode *ETSParser::ParseTypeParametersFormatPlaceholder()
191 {
192     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
193     if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) {
194         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
195         UNREACHABLE();
196     }
197 
198     auto const placeholderNumber = std::get<2>(nodeFormat);
199     if (placeholderNumber >= insertingNodes_.size()) {
200         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
201         UNREACHABLE();
202     }
203 
204     auto *const insertingNode = insertingNodes_[placeholderNumber];
205     if (insertingNode != nullptr && !insertingNode->IsTSTypeParameterDeclaration() &&
206         !insertingNode->IsTSTypeParameterInstantiation()) {
207         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
208         UNREACHABLE();
209     }
210 
211     Lexer()->NextToken();
212     return insertingNode;
213 }
214 
ParseAstNodesArrayFormatPlaceholder()215 ArenaVector<ir::AstNode *> &ETSParser::ParseAstNodesArrayFormatPlaceholder()
216 {
217     if (insertingNodes_.empty()) {
218         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
219         UNREACHABLE();
220     }
221 
222     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
223     if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != GENERAL_FORMAT_NODE) {
224         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
225         UNREACHABLE();
226     }
227 
228     auto const placeholderNumber = std::get<2>(nodeFormat);
229     auto *const insertingNode =
230         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
231     if (insertingNode == nullptr || !insertingNode->IsTSInterfaceBody()) {
232         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
233         UNREACHABLE();
234     }
235 
236     Lexer()->NextToken();
237     return insertingNode->AsTSInterfaceBody()->Body();
238 }
239 
ParseStatementsArrayFormatPlaceholder()240 ArenaVector<ir::Statement *> &ETSParser::ParseStatementsArrayFormatPlaceholder()
241 {
242     if (insertingNodes_.empty()) {
243         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
244         UNREACHABLE();
245     }
246 
247     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
248     if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) {
249         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
250         UNREACHABLE();
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->IsBlockExpression()) {
257         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
258         UNREACHABLE();
259     }
260 
261     Lexer()->NextToken();
262     return insertingNode->AsBlockExpression()->Statements();
263 }
264 
ParseExpressionsArrayFormatPlaceholder()265 ArenaVector<ir::Expression *> &ETSParser::ParseExpressionsArrayFormatPlaceholder()
266 {
267     if (insertingNodes_.empty()) {
268         LogSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start());
269         UNREACHABLE();
270     }
271 
272     ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType();
273     if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) {
274         LogSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start());
275         UNREACHABLE();
276     }
277 
278     auto const placeholderNumber = std::get<2>(nodeFormat);
279     auto *const insertingNode =
280         placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr;
281     if (insertingNode == nullptr || !insertingNode->IsSequenceExpression()) {
282         LogSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start());
283         UNREACHABLE();
284     }
285 
286     Lexer()->NextToken();
287     return insertingNode->AsSequenceExpression()->Sequence();
288 }
289 
CreateStatement(std::string_view const sourceCode)290 ir::Statement *ETSParser::CreateStatement(std::string_view const sourceCode)
291 {
292     util::UString source {sourceCode, Allocator()};
293     auto const isp = InnerSourceParser(this);
294     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
295 
296     lexer::SourcePosition const startLoc = lexer->GetToken().Start();
297     lexer->NextToken();
298 
299     auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL);
300     auto const statementNumber = statements.size();
301     if (statementNumber == 0U) {
302         return nullptr;
303     }
304 
305     if (statementNumber == 1U) {
306         return statements[0U];
307     }
308 
309     auto *const blockStmt = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements));
310     blockStmt->SetRange({startLoc, lexer->GetToken().End()});
311 
312     for (auto *statement : blockStmt->Statements()) {
313         statement->SetParent(blockStmt);
314     }
315 
316     return blockStmt;
317 }
318 
CreateFormattedStatement(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)319 ir::Statement *ETSParser::CreateFormattedStatement(std::string_view const sourceCode,
320                                                    std::vector<ir::AstNode *> &insertingNodes)
321 {
322     insertingNodes_.swap(insertingNodes);
323     auto const statement = CreateStatement(sourceCode);
324     insertingNodes_.swap(insertingNodes);
325     return statement;
326 }
327 
CreateStatements(std::string_view const sourceCode)328 ArenaVector<ir::Statement *> ETSParser::CreateStatements(std::string_view const sourceCode)
329 {
330     util::UString source {sourceCode, Allocator()};
331     auto const isp = InnerSourceParser(this);
332     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
333 
334     lexer->NextToken();
335     return ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL);
336 }
337 
CreateFormattedStatements(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)338 ArenaVector<ir::Statement *> ETSParser::CreateFormattedStatements(std::string_view const sourceCode,
339                                                                   std::vector<ir::AstNode *> &insertingNodes)
340 {
341     insertingNodes_.swap(insertingNodes);
342     auto statements = CreateStatements(sourceCode);
343     insertingNodes_.swap(insertingNodes);
344     return statements;
345 }
346 
347 //  NOTE: this method returns only a single (the first) class filed definition.
348 //  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)349 ir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sourceCode,
350                                                             std::vector<ir::AstNode *> &insertingNodes)
351 {
352     static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()};
353     insertingNodes_.swap(insertingNodes);
354 
355     auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE);
356     if (!property->IsTSInterfaceBody() || property->AsTSInterfaceBody()->Body().empty()) {
357         LogSyntaxError(INVALID_CLASS_FIELD);
358         UNREACHABLE();
359     }
360 
361     insertingNodes_.swap(insertingNodes);
362     return property->AsTSInterfaceBody()->Body().front();
363 }
364 
CreateFormattedClassMethodDefinition(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes)365 ir::AstNode *ETSParser::CreateFormattedClassMethodDefinition(std::string_view sourceCode,
366                                                              std::vector<ir::AstNode *> &insertingNodes)
367 {
368     static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()};
369     insertingNodes_.swap(insertingNodes);
370 
371     auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE);
372     if (!property->IsMethodDefinition()) {
373         LogSyntaxError(INVALID_CLASS_METHOD);
374         UNREACHABLE();
375     }
376 
377     insertingNodes_.swap(insertingNodes);
378     return property;
379 }
380 
CreateFormattedClassElement(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes,const ArenaVector<ir::AstNode * > & properties,ir::ClassDefinitionModifiers modifiers)381 ir::AstNode *ETSParser::CreateFormattedClassElement(std::string_view sourceCode,
382                                                     std::vector<ir::AstNode *> &insertingNodes,
383                                                     const ArenaVector<ir::AstNode *> &properties,
384                                                     ir::ClassDefinitionModifiers modifiers)
385 {
386     insertingNodes_.swap(insertingNodes);
387     auto *const classElement = CreateClassElement(sourceCode, properties, modifiers);
388     insertingNodes_.swap(insertingNodes);
389     return classElement;
390 }
391 
392 //  NOTE: the method has limited functionality - it returns 'ir::TSInterfaceBody' placeholder for the field
393 //  declaration(s) (properties themselves are in ->Body() member) and does not perform any check of the node returned.
394 //  Also the node isn't placed in the providing properties container.
CreateClassElement(std::string_view sourceCode,const ArenaVector<ir::AstNode * > & properties,ir::ClassDefinitionModifiers modifiers)395 ir::AstNode *ETSParser::CreateClassElement(std::string_view sourceCode, const ArenaVector<ir::AstNode *> &properties,
396                                            ir::ClassDefinitionModifiers modifiers)
397 {
398     util::UString source {sourceCode, Allocator()};
399     auto const isp = InnerSourceParser(this);
400     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
401 
402     auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext());
403     SavedClassPrivateContext classContext(this);
404 
405     lexer->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
406 
407     return ParseClassElement(properties, modifiers, ir::ModifierFlags::NONE);
408 }
409 
CreateFormattedClassDeclaration(std::string_view sourceCode,std::vector<ir::AstNode * > & insertingNodes,bool const allowStatic)410 ir::ClassDeclaration *ETSParser::CreateFormattedClassDeclaration(std::string_view sourceCode,
411                                                                  std::vector<ir::AstNode *> &insertingNodes,
412                                                                  bool const allowStatic)
413 {
414     insertingNodes_.swap(insertingNodes);
415     auto *const classDeclaration = CreateClassDeclaration(sourceCode, allowStatic);
416     insertingNodes_.swap(insertingNodes);
417     return classDeclaration;
418 }
419 
CreateClassDeclaration(std::string_view sourceCode,bool allowStatic)420 ir::ClassDeclaration *ETSParser::CreateClassDeclaration(std::string_view sourceCode, bool allowStatic)
421 {
422     util::UString source {sourceCode, Allocator()};
423     auto const isp = InnerSourceParser(this);
424     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
425 
426     auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext());
427 
428     auto modifiers = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL;
429     ir::ModifierFlags flags = ir::ModifierFlags::NONE;
430 
431     lexer->NextToken();
432 
433     switch (auto tokenType = Lexer()->GetToken().Type(); tokenType) {
434         case lexer::TokenType::KEYW_STATIC: {
435             if (!allowStatic) {
436                 ThrowUnexpectedToken(Lexer()->GetToken().Type());
437             }
438             [[fallthrough]];
439         }
440         case lexer::TokenType::KEYW_ABSTRACT:
441         case lexer::TokenType::KEYW_FINAL: {
442             flags = ParseClassModifiers();
443             if (allowStatic && (flags & ir::ModifierFlags::STATIC) == 0U) {
444                 modifiers |= ir::ClassDefinitionModifiers::INNER;
445             }
446 
447             if (auto const tokType = Lexer()->GetToken().Type(); tokType != lexer::TokenType::KEYW_CLASS) {
448                 ThrowUnexpectedToken(tokType);
449             }
450             [[fallthrough]];
451         }
452         case lexer::TokenType::KEYW_CLASS: {
453             return ParseClassDeclaration(modifiers);
454         }
455         default: {
456             ThrowUnexpectedToken(tokenType);
457         }
458     }
459 }
460 
CreateConstructorDefinition(ir::ModifierFlags modifiers,std::string_view const sourceCode)461 ir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags modifiers,
462                                                              std::string_view const sourceCode)
463 {
464     util::UString source {sourceCode, Allocator()};
465     auto const isp = InnerSourceParser(this);
466     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
467 
468     auto const startLoc = Lexer()->GetToken().Start();
469     Lexer()->NextToken();
470 
471     if (IsClassMethodModifier(Lexer()->GetToken().Type())) {
472         modifiers |= ParseClassMethodModifiers(false);
473     }
474 
475     if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_CONSTRUCTOR) {
476         LogExpectedToken(lexer::TokenType::KEYW_CONSTRUCTOR);
477     }
478 
479     if ((modifiers & ir::ModifierFlags::ASYNC) != 0) {
480         LogSyntaxError({"Constructor should not be async."});
481         UNREACHABLE();
482     }
483 
484     auto *memberName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
485     modifiers |= ir::ModifierFlags::CONSTRUCTOR;
486     Lexer()->NextToken();
487 
488     auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers);
489     methodDefinition->SetStart(startLoc);
490 
491     return methodDefinition;
492 }
493 
CreateExpression(std::string_view const sourceCode,ExpressionParseFlags const flags)494 ir::Expression *ETSParser::CreateExpression(std::string_view const sourceCode, ExpressionParseFlags const flags)
495 {
496     util::UString source {sourceCode, Allocator()};
497     auto const isp = InnerSourceParser(this);
498     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
499 
500     lexer::SourcePosition const startLoc = lexer->GetToken().Start();
501     lexer->NextToken();
502 
503     ir::Expression *returnExpression = ParseExpression(flags);
504     returnExpression->SetRange({startLoc, lexer->GetToken().End()});
505 
506     return returnExpression;
507 }
508 
CreateFormattedExpression(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)509 ir::Expression *ETSParser::CreateFormattedExpression(std::string_view const sourceCode,
510                                                      std::vector<ir::AstNode *> &insertingNodes)
511 {
512     ir::Expression *returnExpression;
513     insertingNodes_.swap(insertingNodes);
514 
515     if (auto statements = CreateStatements(sourceCode);
516         statements.size() == 1U && statements.back()->IsExpressionStatement()) {
517         returnExpression = statements.back()->AsExpressionStatement()->GetExpression();
518     } else {
519         returnExpression = AllocNode<ir::BlockExpression>(std::move(statements));
520     }
521 
522     insertingNodes_.swap(insertingNodes);
523     return returnExpression;
524 }
525 
CreateTopLevelStatement(std::string_view const sourceCode)526 ir::Statement *ETSParser::CreateTopLevelStatement(std::string_view const sourceCode)
527 {
528     util::UString source {sourceCode, Allocator()};
529     auto const isp = InnerSourceParser(this);
530     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
531 
532     lexer->NextToken();
533 
534     return ParseTopLevelStatement();
535 }
536 
CreateFormattedTopLevelStatement(std::string_view const sourceCode,std::vector<ir::AstNode * > & insertingNodes)537 ir::Statement *ETSParser::CreateFormattedTopLevelStatement(std::string_view const sourceCode,
538                                                            std::vector<ir::AstNode *> &insertingNodes)
539 {
540     insertingNodes_.swap(insertingNodes);
541     auto const statement = CreateTopLevelStatement(sourceCode);
542     insertingNodes_.swap(insertingNodes);
543     return statement;
544 }
545 
CreateTypeAnnotation(TypeAnnotationParsingOptions * options,std::string_view const sourceCode)546 ir::TypeNode *ETSParser::CreateTypeAnnotation(TypeAnnotationParsingOptions *options, std::string_view const sourceCode)
547 {
548     util::UString source {sourceCode, Allocator()};
549     auto const isp = InnerSourceParser(this);
550     auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()});
551 
552     lexer->NextToken();
553     return ParseTypeAnnotation(options);
554 }
555 }  // namespace ark::es2panda::parser
556