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