• 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() 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