• 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_VARIABLE_H
17 #define ES2PANDA_COMPILER_SCOPES_VARIABLE_H
18 
19 #include <binder/enumMemberResult.h>
20 #include <binder/variableFlags.h>
21 #include <ir/irnode.h>
22 #include <macros.h>
23 #include <util/hotfix.h>
24 #include <util/ustring.h>
25 
26 #include <limits>
27 
28 namespace panda::es2panda::checker {
29 class Type;
30 }  // namespace panda::es2panda::checker
31 
32 namespace panda::es2panda::binder {
33 
34 class Decl;
35 class Scope;
36 class VariableScope;
37 class ExportBindings;
38 
39 #define DECLARE_CLASSES(type, className) class className;
VARIABLE_TYPES(DECLARE_CLASSES)40 VARIABLE_TYPES(DECLARE_CLASSES)
41 #undef DECLARE_CLASSES
42 
43 class Variable {
44 public:
45     virtual ~Variable() = default;
46     NO_COPY_SEMANTIC(Variable);
47     NO_MOVE_SEMANTIC(Variable);
48 
49     VariableType virtual Type() const = 0;
50 
51 #define DECLARE_CHECKS_CASTS(variableType, className)     \
52     bool Is##className() const                            \
53     {                                                     \
54         return Type() == VariableType::variableType;      \
55     }                                                     \
56     className *As##className()                            \
57     {                                                     \
58         ASSERT(Is##className());                          \
59         return reinterpret_cast<className *>(this);       \
60     }                                                     \
61     const className *As##className() const                \
62     {                                                     \
63         ASSERT(Is##className());                          \
64         return reinterpret_cast<const className *>(this); \
65     }
66     VARIABLE_TYPES(DECLARE_CHECKS_CASTS)
67 #undef DECLARE_CHECKS_CASTS
68 
69     Decl *Declaration() const
70     {
71         return decl_;
72     }
73 
74     VariableFlags Flags() const
75     {
76         return flags_;
77     }
78 
79     checker::Type *TsType() const
80     {
81         return tsType_;
82     }
83 
84     void SetTsType(checker::Type *tsType)
85     {
86         tsType_ = tsType;
87     }
88 
89     void AddFlag(VariableFlags flag)
90     {
91         flags_ |= flag;
92     }
93 
94     bool HasFlag(VariableFlags flag) const
95     {
96         return (flags_ & flag) != 0;
97     }
98 
99     void RemoveFlag(VariableFlags flag)
100     {
101         flags_ &= ~flag;
102     }
103 
104     void Reset(Decl *decl, VariableFlags flags)
105     {
106         decl_ = decl;
107         flags_ = flags;
108     }
109 
110     bool LexicalBound() const
111     {
112         return HasFlag(VariableFlags::LEXICAL_BOUND);
113     }
114 
115     const util::StringView &Name() const;
116     virtual void SetLexical(Scope *scope, util::Hotfix *hotfixHelper = nullptr) = 0;
117 
118 protected:
119     explicit Variable(Decl *decl, VariableFlags flags) : decl_(decl), flags_(flags) {}
120 
121     Decl *decl_;
122     VariableFlags flags_ {};
123     checker::Type *tsType_ {};
124 };
125 
126 class LocalVariable : public Variable {
127 public:
128     explicit LocalVariable(Decl *decl, VariableFlags flags);
129 
Type()130     VariableType Type() const override
131     {
132         return VariableType::LOCAL;
133     }
134 
BindVReg(compiler::VReg vreg)135     void BindVReg(compiler::VReg vreg)
136     {
137         ASSERT(!LexicalBound());
138         vreg_ = vreg;
139     }
140 
BindLexEnvSlot(uint32_t slot)141     void BindLexEnvSlot(uint32_t slot)
142     {
143         ASSERT(!LexicalBound());
144         AddFlag(VariableFlags::LEXICAL_BOUND);
145         vreg_ = slot;
146     }
147 
Vreg()148     compiler::VReg Vreg() const
149     {
150         return vreg_;
151     }
152 
LexIdx()153     uint32_t LexIdx() const
154     {
155         ASSERT(LexicalBound());
156         return vreg_;
157     }
158 
159     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
160     LocalVariable *Copy(ArenaAllocator *allocator, Decl *decl) const;
161 
162 private:
163     uint32_t vreg_ {};
164 };
165 
166 class GlobalVariable : public Variable {
167 public:
GlobalVariable(Decl * decl,VariableFlags flags)168     explicit GlobalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
169 
Type()170     VariableType Type() const override
171     {
172         return VariableType::GLOBAL;
173     }
174 
175     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
176 };
177 
178 class ModuleVariable : public Variable {
179 public:
ModuleVariable(Decl * decl,VariableFlags flags)180     explicit ModuleVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
181 
Type()182     VariableType Type() const override
183     {
184         return VariableType::MODULE;
185     }
186 
187     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
188 
AssignIndex(uint32_t index)189     void AssignIndex(uint32_t index)
190     {
191         index_ = index;
192     }
193 
Index()194     uint32_t Index() const
195     {
196         return index_;
197     }
198 
199 private:
200     uint32_t index_;
201 };
202 
203 class EnumVariable : public Variable {
204 public:
205     explicit EnumVariable(Decl *decl, bool backReference = false)
Variable(decl,VariableFlags::NONE)206         : Variable(decl, VariableFlags::NONE), backReference_(backReference)
207     {
208     }
209 
Type()210     VariableType Type() const override
211     {
212         return VariableType::ENUM;
213     }
214 
SetValue(EnumMemberResult value)215     void SetValue(EnumMemberResult value)
216     {
217         value_ = value;
218     }
219 
Value()220     const EnumMemberResult &Value() const
221     {
222         return value_;
223     }
224 
BackReference()225     bool BackReference() const
226     {
227         return backReference_;
228     }
229 
SetBackReference()230     void SetBackReference()
231     {
232         backReference_ = true;
233     }
234 
235     void ResetDecl(Decl *decl);
236 
237     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
238 
239 private:
240     EnumMemberResult value_ {false};
241     bool backReference_ {};
242 };
243 
244 class NamespaceVariable : public Variable {
245 public:
NamespaceVariable(Decl * decl,VariableFlags flags)246     explicit NamespaceVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
247 
Type()248     VariableType Type() const override
249     {
250         return VariableType::NAMESPACE;
251     }
252 
253     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
254 
GetExportBindings()255     ExportBindings *GetExportBindings()
256     {
257         return exportBindings_;
258     }
259 
SetExportBindings(ExportBindings * exportBindings)260     void SetExportBindings(ExportBindings *exportBindings)
261     {
262         exportBindings_ = exportBindings;
263     }
264 
265 private:
266     ExportBindings *exportBindings_ {nullptr};
267 };
268 
269 class ImportEqualsVariable : public Variable {
270 public:
ImportEqualsVariable(Decl * decl,VariableFlags flags)271     explicit ImportEqualsVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
272 
Type()273     VariableType Type() const override
274     {
275         return VariableType::IMPORT_EQUALS;
276     }
277 
278     void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override;
279 
GetScope()280     Scope *GetScope()
281     {
282         return scope_;
283     }
284 
SetScope(Scope * scope)285     void SetScope(Scope *scope)
286     {
287         scope_ = scope;
288     }
289 
290 private:
291     Scope *scope_ {nullptr};
292 };
293 
294 }  // namespace panda::es2panda::binder
295 #endif
296