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