• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021 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 #ifndef ES2PANDA_COMPILER_SCOPES_DECLARATION_H
17 #define ES2PANDA_COMPILER_SCOPES_DECLARATION_H
18 
19 #include <binder/variableFlags.h>
20 #include <macros.h>
21 #include <util/ustring.h>
22 
23 namespace panda::es2panda::ir {
24 class AstNode;
25 class ScriptFunction;
26 class TSInterfaceDeclaration;
27 class TSModuleDeclaration;
28 class ImportDeclaration;
29 }  // namespace panda::es2panda::ir
30 
31 namespace panda::es2panda::binder {
32 
33 class Scope;
34 class LocalScope;
35 
36 #define DECLARE_CLASSES(decl_kind, className) class className;
DECLARATION_KINDS(DECLARE_CLASSES)37 DECLARATION_KINDS(DECLARE_CLASSES)
38 #undef DECLARE_CLASSES
39 
40 class Decl {
41 public:
42     virtual ~Decl() = default;
43     NO_COPY_SEMANTIC(Decl);
44     NO_MOVE_SEMANTIC(Decl);
45 
46     virtual DeclType Type() const = 0;
47 
48     const util::StringView &Name() const
49     {
50         return name_;
51     }
52 
53     const ir::AstNode *Node() const
54     {
55         return node_;
56     }
57 
58 #define DECLARE_CHECKS_CASTS(declKind, className)         \
59     bool Is##className() const                            \
60     {                                                     \
61         return Type() == DeclType::declKind;              \
62     }                                                     \
63     className *As##className()                            \
64     {                                                     \
65         ASSERT(Is##className());                          \
66         return reinterpret_cast<className *>(this);       \
67     }                                                     \
68     const className *As##className() const                \
69     {                                                     \
70         ASSERT(Is##className());                          \
71         return reinterpret_cast<const className *>(this); \
72     }
73     DECLARATION_KINDS(DECLARE_CHECKS_CASTS)
74 #undef DECLARE_CHECKS_CASTS
75 
76     void BindNode(const ir::AstNode *node)
77     {
78         node_ = node;
79     }
80 
81     bool IsLetOrConstOrClassDecl() const
82     {
83         return IsLetDecl() || IsConstDecl() || IsClassDecl();
84     }
85 
86     DeclarationFlags Flags() const
87     {
88         return flags_;
89     }
90 
91     void AddFlag(DeclarationFlags flag)
92     {
93         flags_ |= flag;
94     }
95 
96     bool HasFlag(DeclarationFlags flag) const
97     {
98         return (flags_ & flag) != 0;
99     }
100 
101     bool IsImportDecl() const
102     {
103         return HasFlag(DeclarationFlags::IMPORT);
104     }
105 
106     bool IsImportOrExportDecl() const
107     {
108         return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT);
109     }
110 
111 protected:
112     explicit Decl(util::StringView name) : name_(name) {}
113 
114     util::StringView name_;
115     DeclarationFlags flags_ {};
116     const ir::AstNode *node_ {};
117 };
118 
119 template <typename T>
120 class MultiDecl : public Decl {
121 public:
MultiDecl(ArenaAllocator * allocator,util::StringView name)122     explicit MultiDecl(ArenaAllocator *allocator, util::StringView name)
123         : Decl(name), declarations_(allocator->Adapter())
124     {
125     }
126 
Decls()127     const ArenaVector<T *> &Decls() const
128     {
129         return declarations_;
130     }
131 
Add(T * decl)132     void Add(T *decl)
133     {
134         declarations_.push_back(decl);
135     }
136 
137 private:
138     ArenaVector<T *> declarations_;
139 };
140 
141 class EnumLiteralDecl : public Decl {
142 public:
EnumLiteralDecl(util::StringView name,bool isConst)143     explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {}
144 
Type()145     DeclType Type() const override
146     {
147         return DeclType::ENUM_LITERAL;
148     }
149 
IsConst()150     bool IsConst() const
151     {
152         return isConst_;
153     }
154 
BindScope(LocalScope * scope)155     void BindScope(LocalScope *scope)
156     {
157         scope_ = scope;
158     }
159 
Scope()160     LocalScope *Scope()
161     {
162         return scope_;
163     }
164 
165 private:
166     LocalScope *scope_ {};
167     bool isConst_ {};
168 };
169 
170 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> {
171 public:
InterfaceDecl(ArenaAllocator * allocator,util::StringView name)172     explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {}
173 
Type()174     DeclType Type() const override
175     {
176         return DeclType::INTERFACE;
177     }
178 };
179 
180 class FunctionDecl : public MultiDecl<ir::ScriptFunction> {
181 public:
FunctionDecl(ArenaAllocator * allocator,util::StringView name,const ir::AstNode * node)182     explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node)
183         : MultiDecl(allocator, name)
184     {
185         node_ = node;
186     }
187 
Type()188     DeclType Type() const override
189     {
190         return DeclType::FUNC;
191     }
192 };
193 
194 class TypeParameterDecl : public Decl {
195 public:
196     explicit TypeParameterDecl(util::StringView name, const ir::AstNode *node);
197 
Type()198     DeclType Type() const override
199     {
200         return DeclType::TYPE_PARAMETER;
201     }
202 };
203 
204 class PropertyDecl : public Decl {
205 public:
PropertyDecl(util::StringView name)206     explicit PropertyDecl(util::StringView name) : Decl(name) {}
207 
Type()208     DeclType Type() const override
209     {
210         return DeclType::PROPERTY;
211     }
212 };
213 
214 class MethodDecl : public Decl {
215 public:
MethodDecl(util::StringView name)216     explicit MethodDecl(util::StringView name) : Decl(name) {}
217 
Type()218     DeclType Type() const override
219     {
220         return DeclType::METHOD;
221     }
222 };
223 
224 class EnumDecl : public Decl {
225 public:
EnumDecl(util::StringView name)226     explicit EnumDecl(util::StringView name) : Decl(name) {}
227 
Type()228     DeclType Type() const override
229     {
230         return DeclType::ENUM;
231     }
232 };
233 
234 class TypeAliasDecl : public Decl {
235 public:
TypeAliasDecl(util::StringView name)236     explicit TypeAliasDecl(util::StringView name) : Decl(name) {}
237 
Type()238     DeclType Type() const override
239     {
240         return DeclType::TYPE_ALIAS;
241     }
242 };
243 
244 class NamespaceDecl : public MultiDecl<ir::TSModuleDeclaration> {
245 public:
NamespaceDecl(ArenaAllocator * allocator,util::StringView name)246     explicit NamespaceDecl(ArenaAllocator *allocator, util::StringView name)
247         : MultiDecl(allocator, name)
248     {
249     }
250 
Type()251     DeclType Type() const override
252     {
253         return DeclType::NAMESPACE;
254     }
255 };
256 
257 class VarDecl : public Decl {
258 public:
VarDecl(util::StringView name)259     explicit VarDecl(util::StringView name) : Decl(name) {}
260 
Type()261     DeclType Type() const override
262     {
263         return DeclType::VAR;
264     }
265 };
266 
267 class LetDecl : public Decl {
268 public:
LetDecl(util::StringView name)269     explicit LetDecl(util::StringView name) : Decl(name) {}
270 
Type()271     DeclType Type() const override
272     {
273         return DeclType::LET;
274     }
275 };
276 
277 class ConstDecl : public Decl {
278 public:
ConstDecl(util::StringView name)279     explicit ConstDecl(util::StringView name) : Decl(name) {}
280 
Type()281     DeclType Type() const override
282     {
283         return DeclType::CONST;
284     }
285 };
286 
287 class ClassDecl : public Decl {
288 public:
ClassDecl(util::StringView name)289     explicit ClassDecl(util::StringView name) : Decl(name) {}
290 
Type()291     DeclType Type() const override
292     {
293         return DeclType::CLASS;
294     }
295 };
296 
297 class ParameterDecl : public Decl {
298 public:
ParameterDecl(util::StringView name)299     explicit ParameterDecl(util::StringView name) : Decl(name) {}
300 
Type()301     DeclType Type() const override
302     {
303         return DeclType::PARAM;
304     }
305 };
306 
307 class ImportEqualsDecl : public Decl {
308 public:
ImportEqualsDecl(util::StringView name)309     explicit ImportEqualsDecl(util::StringView name) : Decl(name) {}
310 
Type()311     DeclType Type() const override
312     {
313         return DeclType::IMPORT_EQUALS;
314     }
315 };
316 
317 }  // namespace panda::es2panda::binder
318 
319 #endif
320