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_IR_EXPRESSION_IDENTIFIER_H
17 #define ES2PANDA_IR_EXPRESSION_IDENTIFIER_H
18 
19 #include "checker/checkerContext.h"
20 #include "ir/expression.h"
21 #include "ir/validationInfo.h"
22 
23 namespace ark::es2panda::varbinder {
24 class Variable;
25 }  // namespace ark::es2panda::varbinder
26 
27 namespace ark::es2panda::ir {
28 
29 using ENUMBITOPS_OPERATORS;
30 
31 enum class IdentifierFlags : uint32_t {
32     NONE = 0U,
33     OPTIONAL = 1U << 0U,
34     REFERENCE = 1U << 1U,
35     TDZ = 1U << 2U,
36     PRIVATE = 1U << 3U,
37     GET = 1U << 4U,
38     SET = 1U << 5U,
39     IGNORE_BOX = 1U << 6U,
40 };
41 
42 }  // namespace ark::es2panda::ir
43 
44 template <>
45 struct enumbitops::IsAllowedType<ark::es2panda::ir::IdentifierFlags> : std::true_type {
46 };
47 
48 namespace ark::es2panda::ir {
49 
50 class Identifier : public AnnotatedExpression {
51 private:
52     struct Tag {};
53 
54 public:
55     Identifier() = delete;
56     ~Identifier() override = default;
57 
58     NO_COPY_SEMANTIC(Identifier);
59     NO_MOVE_SEMANTIC(Identifier);
60 
61 public:
Identifier(ArenaAllocator *const allocator)62     explicit Identifier(ArenaAllocator *const allocator) : Identifier("", allocator) {}
Identifier(util::StringView const name, ArenaAllocator *const allocator)63     explicit Identifier(util::StringView const name, ArenaAllocator *const allocator)
64         : AnnotatedExpression(AstNodeType::IDENTIFIER), name_(name), decorators_(allocator->Adapter())
65     {
66     }
67 
Identifier(util::StringView const name, TypeNode *const typeAnnotation, ArenaAllocator *const allocator)68     explicit Identifier(util::StringView const name, TypeNode *const typeAnnotation, ArenaAllocator *const allocator)
69         : AnnotatedExpression(AstNodeType::IDENTIFIER, typeAnnotation), name_(name), decorators_(allocator->Adapter())
70     {
71     }
72 
73     explicit Identifier(Tag tag, Identifier const &other, ArenaAllocator *allocator);
74 
75     [[nodiscard]] const util::StringView &Name() const noexcept
76     {
77         return name_;
78     }
79 
80     [[nodiscard]] util::StringView &Name() noexcept
81     {
82         return name_;
83     }
84 
85     void SetName(const util::StringView &newName) noexcept
86     {
87         name_ = newName;
88     }
89 
90     [[nodiscard]] const ArenaVector<Decorator *> &Decorators() const noexcept
91     {
92         return decorators_;
93     }
94 
95     const ArenaVector<Decorator *> *DecoratorsPtr() const override
96     {
97         return &Decorators();
98     }
99 
100     [[nodiscard]] bool IsOptional() const noexcept
101     {
102         return (flags_ & IdentifierFlags::OPTIONAL) != 0;
103     }
104 
105     void SetOptional(bool const optional) noexcept
106     {
107         if (optional) {
108             flags_ |= IdentifierFlags::OPTIONAL;
109         } else {
110             flags_ &= ~IdentifierFlags::OPTIONAL;
111         }
112     }
113 
114     [[nodiscard]] bool IsReference() const noexcept
115     {
116         return (flags_ & IdentifierFlags::REFERENCE) != 0;
117     }
118 
119     void SetReference(bool const isReference = true) noexcept
120     {
121         if (isReference) {
122             flags_ |= IdentifierFlags::REFERENCE;
123         } else {
124             flags_ &= ~IdentifierFlags::REFERENCE;
125         }
126     }
127 
128     [[nodiscard]] bool IsTdz() const noexcept
129     {
130         return (flags_ & IdentifierFlags::TDZ) != 0;
131     }
132 
133     void SetTdz() noexcept
134     {
135         flags_ |= IdentifierFlags::TDZ;
136     }
137 
138     void SetAccessor() noexcept
139     {
140         flags_ |= IdentifierFlags::GET;
141     }
142 
143     [[nodiscard]] bool IsAccessor() const noexcept
144     {
145         return (flags_ & IdentifierFlags::GET) != 0;
146     }
147 
148     void SetMutator() noexcept
149     {
150         flags_ |= IdentifierFlags::SET;
151     }
152 
153     [[nodiscard]] bool IsMutator() const noexcept
154     {
155         return (flags_ & IdentifierFlags::SET) != 0;
156     }
157 
158     [[nodiscard]] bool IsPrivateIdent() const noexcept
159     {
160         return (flags_ & IdentifierFlags::PRIVATE) != 0;
161     }
162 
163     void SetPrivate(bool const isPrivate) noexcept
164     {
165         if (isPrivate) {
166             flags_ |= IdentifierFlags::PRIVATE;
167         } else {
168             flags_ &= ~IdentifierFlags::PRIVATE;
169         }
170     }
171 
172     [[nodiscard]] bool IsIgnoreBox() const noexcept
173     {
174         return (flags_ & IdentifierFlags::IGNORE_BOX) != 0;
175     }
176 
177     void SetIgnoreBox() noexcept
178     {
179         flags_ |= IdentifierFlags::IGNORE_BOX;
180     }
181 
182     void AddDecorators([[maybe_unused]] ArenaVector<ir::Decorator *> &&decorators) override
183     {
184         decorators_ = std::move(decorators);
185     }
186 
187     [[nodiscard]] Identifier *Clone(ArenaAllocator *allocator, AstNode *parent) override;
188 
189     bool CanHaveDecorator([[maybe_unused]] bool inTs) const override
190     {
191         return true;
192     }
193 
194     [[nodiscard]] ValidationInfo ValidateExpression();
195 
196     void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
197     void Iterate(const NodeTraverser &cb) const override;
198     void Dump(ir::AstDumper *dumper) const override;
199     void Dump(ir::SrcDumper *dumper) const override;
200     void Compile(compiler::PandaGen *pg) const override;
201     void Compile(compiler::ETSGen *etsg) const override;
202     checker::Type *Check(checker::TSChecker *checker) override;
203     checker::Type *Check(checker::ETSChecker *checker) override;
204 
205     void Accept(ASTVisitorT *v) override
206     {
207         v->Accept(this);
208     }
209 
210 private:
211     util::StringView name_;
212     IdentifierFlags flags_ {IdentifierFlags::NONE};
213     ArenaVector<Decorator *> decorators_;
214 };
215 }  // namespace ark::es2panda::ir
216 
217 #endif
218