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
23namespace ark::es2panda::varbinder {
24class Variable;
25}  // namespace ark::es2panda::varbinder
26
27namespace ark::es2panda::ir {
28
29using ENUMBITOPS_OPERATORS;
30
31enum 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
44template <>
45struct enumbitops::IsAllowedType<ark::es2panda::ir::IdentifierFlags> : std::true_type {
46};
47
48namespace ark::es2panda::ir {
49
50class Identifier : public AnnotatedExpression {
51private:
52    struct Tag {};
53
54public:
55    Identifier() = delete;
56    ~Identifier() override = default;
57
58    NO_COPY_SEMANTIC(Identifier);
59    NO_MOVE_SEMANTIC(Identifier);
60
61public:
62    explicit Identifier(ArenaAllocator *const allocator) : Identifier("", allocator) {}
63    explicit Identifier(util::StringView const name, ArenaAllocator *const allocator)
64        : AnnotatedExpression(AstNodeType::IDENTIFIER), name_(name), decorators_(allocator->Adapter())
65    {
66    }
67
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
210private:
211    util::StringView name_;
212    IdentifierFlags flags_ {IdentifierFlags::NONE};
213    ArenaVector<Decorator *> decorators_;
214};
215}  // namespace ark::es2panda::ir
216
217#endif
218