• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 #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 ark::es2panda::checker {
28 class Type;
29 enum class PropertyType;
30 // NOLINTBEGIN(readability-redundant-declaration)
31 bool IsTypeError(Type const *tp);
32 // NOLINTEND(readability-redundant-declaration)
33 }  // namespace ark::es2panda::checker
34 
35 namespace ark::es2panda::varbinder {
36 class Decl;
37 class Scope;
38 class VariableScope;
39 
40 // CC-OFFNXT(G.PRE.09) code gen
41 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
42 #define DECLARE_CLASSES(type, className) class className;  // CC-OFF(G.PRE.02) name part
VARIABLE_TYPES(DECLARE_CLASSES)43 VARIABLE_TYPES(DECLARE_CLASSES)
44 #undef DECLARE_CLASSES
45 
46 class Variable {
47 public:
48     virtual ~Variable() = default;
49     NO_COPY_SEMANTIC(Variable);
50     NO_MOVE_SEMANTIC(Variable);
51 
52     VariableType virtual Type() const = 0;
53 
54 /* CC-OFFNXT(G.PRE.06) solid logic */
55 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
56 #define DECLARE_CHECKS_CASTS(variableType, className)                                       \
57     bool Is##className() const                                                              \
58     {                                                                                       \
59         /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
60         return Type() == VariableType::variableType; /* CC-OFF(G.PRE.02) name part */       \
61     }                                                                                       \
62     /* CC-OFFNXT(G.PRE.02) name part */                                                     \
63     className *As##className()                                                              \
64     {                                                                                       \
65         ASSERT(Is##className());                                                            \
66         /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
67         return reinterpret_cast<className *>(this); /* CC-OFF(G.PRE.02) name part */        \
68     }                                                                                       \
69     const className *As##className() const                                                  \
70     {                                                                                       \
71         ASSERT(Is##className());                                                            \
72         /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
73         return reinterpret_cast<const className *>(this);                                   \
74     }
75     VARIABLE_TYPES(DECLARE_CHECKS_CASTS)
76 #undef DECLARE_CHECKS_CASTS
77 
78     [[nodiscard]] const Decl *Declaration() const noexcept
79     {
80         return decl_;
81     }
82 
83     [[nodiscard]] Decl *Declaration() noexcept
84     {
85         return decl_;
86     }
87 
88     [[nodiscard]] VariableFlags Flags() const noexcept
89     {
90         return flags_;
91     }
92 
93     [[nodiscard]] checker::Type *TsType() const
94     {
95         return tsType_;
96     }
97 
98     [[nodiscard]] Scope *GetScope() const noexcept
99     {
100         return scope_;
101     }
102 
103     void SetTsType(checker::Type *tsType) noexcept
104     {
105         tsType_ = tsType;
106     }
107 
108     void SetScope(varbinder::Scope *scope) noexcept
109     {
110         scope_ = scope;
111     }
112 
113     void AddFlag(VariableFlags flag) noexcept
114     {
115         flags_ |= flag;
116     }
117 
118     [[nodiscard]] bool HasFlag(VariableFlags flag) const noexcept
119     {
120         return (flags_ & flag) != 0;
121     }
122 
123     void RemoveFlag(VariableFlags flag) noexcept
124     {
125         flags_ &= ~flag;
126     }
127 
128     void Reset(Decl *decl, VariableFlags flags) noexcept
129     {
130         decl_ = decl;
131         flags_ = flags;
132     }
133 
134     [[nodiscard]] bool LexicalBound() const noexcept
135     {
136         return HasFlag(VariableFlags::LEXICAL_BOUND);
137     }
138 
139     [[nodiscard]] const util::StringView &Name() const;
140     virtual void SetLexical(Scope *scope) = 0;
141 
142 protected:
143     explicit Variable(Decl *decl, VariableFlags flags) : decl_(decl), flags_(flags) {}
144     explicit Variable(VariableFlags flags) : flags_(flags) {}
145 
146     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
147     Decl *decl_ {};
148     VariableFlags flags_ {};
149     // NOLINTEND(misc-non-private-member-variables-in-classes)
150 
151 private:
152     checker::Type *tsType_ {};
153     Scope *scope_ {};
154 };
155 
156 class LocalVariable : public Variable {
157 public:
158     explicit LocalVariable(Decl *decl, VariableFlags flags);
159     explicit LocalVariable(VariableFlags flags);
160 
Type()161     VariableType Type() const override
162     {
163         return VariableType::LOCAL;
164     }
165 
BindVReg(compiler::VReg vreg)166     void BindVReg(compiler::VReg vreg)
167     {
168         ASSERT(!LexicalBound());
169         vreg_ = vreg;
170     }
171 
BindLexEnvSlot(uint32_t slot)172     void BindLexEnvSlot(uint32_t slot)
173     {
174         ASSERT(!LexicalBound());
175         AddFlag(VariableFlags::LEXICAL_BOUND);
176         vreg_.SetIndex(slot);
177     }
178 
Vreg()179     compiler::VReg Vreg() const
180     {
181         return vreg_;
182     }
183 
Vreg()184     compiler::VReg &Vreg()
185     {
186         return vreg_;
187     }
188 
LexIdx()189     uint32_t LexIdx() const
190     {
191         ASSERT(LexicalBound());
192         return vreg_.GetIndex();
193     }
194 
195     void SetLexical([[maybe_unused]] Scope *scope) override;
196     LocalVariable *Copy(ArenaAllocator *allocator, Decl *decl) const;
197 
198 private:
199     compiler::VReg vreg_ {};
200 };
201 
202 class GlobalVariable : public Variable {
203 public:
GlobalVariable(Decl * decl,VariableFlags flags)204     explicit GlobalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
205 
Type()206     VariableType Type() const override
207     {
208         return VariableType::GLOBAL;
209     }
210 
211     void SetLexical([[maybe_unused]] Scope *scope) override;
212 };
213 
214 class ModuleVariable : public Variable {
215 public:
ModuleVariable(Decl * decl,VariableFlags flags)216     explicit ModuleVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {}
217 
Type()218     VariableType Type() const override
219     {
220         return VariableType::MODULE;
221     }
222 
ModuleReg()223     compiler::VReg &ModuleReg()
224     {
225         return moduleReg_;
226     }
227 
ModuleReg()228     compiler::VReg ModuleReg() const
229     {
230         return moduleReg_;
231     }
232 
ExoticName()233     const util::StringView &ExoticName() const
234     {
235         return exoticName_;
236     }
237 
ExoticName()238     util::StringView &ExoticName()
239     {
240         return exoticName_;
241     }
242 
243     void SetLexical([[maybe_unused]] Scope *scope) override;
244 
245 private:
246     compiler::VReg moduleReg_ {};
247     util::StringView exoticName_ {};
248 };
249 
250 class EnumVariable : public Variable {
251 public:
252     explicit EnumVariable(Decl *decl, bool backReference = false)
Variable(decl,VariableFlags::NONE)253         : Variable(decl, VariableFlags::NONE), backReference_(backReference)
254     {
255     }
256 
Type()257     VariableType Type() const override
258     {
259         return VariableType::ENUM;
260     }
261 
SetValue(EnumMemberResult value)262     void SetValue(EnumMemberResult value)
263     {
264         value_ = value;
265     }
266 
Value()267     const EnumMemberResult &Value() const
268     {
269         return value_;
270     }
271 
BackReference()272     bool BackReference() const
273     {
274         return backReference_;
275     }
276 
SetBackReference()277     void SetBackReference()
278     {
279         backReference_ = true;
280     }
281 
282     void ResetDecl(Decl *decl);
283 
284     void SetLexical([[maybe_unused]] Scope *scope) override;
285 
286 private:
287     EnumMemberResult value_ {};
288     bool backReference_ {};
289 };
290 }  // namespace ark::es2panda::varbinder
291 #endif
292