• 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 #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