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 #include "ETSNolintParser.h"
18 #include <utility>
19
20 #include "macros.h"
21 #include "parser/parserFlags.h"
22 #include "parser/parserStatusContext.h"
23 #include "util/helpers.h"
24 #include "util/language.h"
25 #include "utils/arena_containers.h"
26 #include "varbinder/varbinder.h"
27 #include "varbinder/ETSBinder.h"
28 #include "lexer/lexer.h"
29 #include "lexer/ETSLexer.h"
30 #include "ir/astNode.h"
31
32 #include "ir/statements/namespaceDeclaration.h"
33
34 namespace ark::es2panda::parser {
35 class FunctionContext;
36
37 using namespace std::literals::string_literals;
38
ParseNamespaceDeclaration(ir::ModifierFlags flags)39 ir::NamespaceDeclaration *ETSParser::ParseNamespaceDeclaration(ir::ModifierFlags flags)
40 {
41 if ((GetContext().Status() & ParserStatus::IN_NAMESPACE) == 0) {
42 LogSyntaxError("Namespace not enabled in here.");
43 }
44
45 const lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
46 auto modifiers = ir::ClassDefinitionModifiers::NONE;
47 if (IsExternal()) {
48 modifiers |= ir::ClassDefinitionModifiers::FROM_EXTERNAL;
49 }
50
51 ir::NamespaceDefinition *namespaceDefinition = ParseNamespaceDefinition(modifiers, flags);
52
53 auto *namespaceDecl = AllocNode<ir::NamespaceDeclaration>(namespaceDefinition);
54
55 namespaceDecl->SetRange({startLoc, Lexer()->GetToken().End()});
56 return namespaceDecl;
57 }
58
ParseNamespaceDefinition(ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)59 ir::NamespaceDefinition *ETSParser::ParseNamespaceDefinition(ir::ClassDefinitionModifiers modifiers,
60 ir::ModifierFlags flags)
61 {
62 Lexer()->NextToken();
63 flags |= ir::ModifierFlags::DECLARE;
64 ir::Identifier *identNode = ParseClassIdent(modifiers);
65
66 ArenaVector<ir::AstNode *> properties(Allocator()->Adapter());
67 ir::MethodDefinition *ctor = nullptr;
68 lexer::SourceRange bodyRange;
69
70 std::tie(ctor, properties, bodyRange) = ParseNamespaceBody(modifiers, flags);
71
72 auto def =
73 AllocNode<ir::NamespaceDefinition>(identNode, std::move(properties), ctor, flags, GetContext().GetLanguage());
74 def->SetRange(bodyRange);
75 return def;
76 }
77
ParseNamespaceBody(ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)78 ETSParser::NamespaceBody ETSParser::ParseNamespaceBody(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags)
79 {
80 auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext());
81
82 lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
83 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
84
85 ir::MethodDefinition *ctor = nullptr;
86 ArenaVector<ir::AstNode *> properties(Allocator()->Adapter());
87
88 SavedClassPrivateContext classContext(this);
89
90 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
91 Lexer()->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE)) {
92 properties = std::move(ParseAstNodesArrayFormatPlaceholder());
93 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
94 LogSyntaxError("Expected a '}'");
95 UNREACHABLE();
96 }
97 } else {
98 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
99 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
100 Lexer()->NextToken();
101 continue;
102 }
103
104 ir::AstNode *property = ParseClassElement(properties, modifiers, flags);
105
106 if (CheckClassElement(property, ctor, properties)) {
107 continue;
108 }
109
110 properties.push_back(property);
111 }
112 }
113
114 lexer::SourcePosition endLoc = Lexer()->GetToken().End();
115 Lexer()->NextToken();
116
117 return {ctor, std::move(properties), lexer::SourceRange {startLoc, endLoc}};
118 }
119
120 } // namespace ark::es2panda::parser
121