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