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_TS_ENUM_DECLARATION_H
17#define ES2PANDA_IR_TS_ENUM_DECLARATION_H
18
19#include "varbinder/scope.h"
20#include "ir/statement.h"
21
22namespace ark::es2panda::varbinder {
23class EnumVariable;
24}  // namespace ark::es2panda::varbinder
25
26namespace ark::es2panda::ir {
27class Identifier;
28class TSEnumMember;
29
30class TSEnumDeclaration : public TypedStatement {
31public:
32    // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
33    struct ConstructorFlags {
34        bool isConst;
35        bool isStatic = false;
36        bool isDeclare = false;
37    };
38    // NOLINTEND(cppcoreguidelines-pro-type-member-init)
39
40    explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector<AstNode *> &&members,
41                               ConstructorFlags &&flags)
42        : TypedStatement(AstNodeType::TS_ENUM_DECLARATION),
43          decorators_(allocator->Adapter()),
44          key_(key),
45          members_(std::move(members)),
46          isConst_(flags.isConst),
47          isDeclare_(flags.isDeclare)
48    {
49        if (flags.isStatic) {
50            AddModifier(ModifierFlags::STATIC);
51        }
52        if (flags.isDeclare) {
53            AddModifier(ModifierFlags::DECLARE);
54        }
55    }
56
57    [[nodiscard]] bool IsScopeBearer() const noexcept override
58    {
59        return true;
60    }
61
62    [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override
63    {
64        return scope_;
65    }
66
67    void SetScope(varbinder::LocalScope *scope)
68    {
69        ASSERT(scope_ == nullptr);
70        scope_ = scope;
71    }
72
73    void ClearScope() noexcept override
74    {
75        scope_ = nullptr;
76    }
77
78    const Identifier *Key() const
79    {
80        return key_;
81    }
82
83    Identifier *Key()
84    {
85        return key_;
86    }
87
88    const ArenaVector<AstNode *> &Members() const
89    {
90        return members_;
91    }
92
93    const util::StringView &InternalName() const
94    {
95        return internalName_;
96    }
97
98    void SetInternalName(util::StringView internalName)
99    {
100        internalName_ = internalName;
101    }
102
103    ir::ClassDefinition *BoxedClass() const
104    {
105        return boxedClass_;
106    }
107
108    void SetBoxedClass(ir::ClassDefinition *const wrapperClass)
109    {
110        boxedClass_ = wrapperClass;
111    }
112
113    bool IsConst() const
114    {
115        return isConst_;
116    }
117
118    bool IsDeclare() const
119    {
120        return isDeclare_;
121    }
122
123    const ArenaVector<Decorator *> &Decorators() const
124    {
125        return decorators_;
126    }
127
128    const ArenaVector<Decorator *> *DecoratorsPtr() const override
129    {
130        return &Decorators();
131    }
132
133    void AddDecorators([[maybe_unused]] ArenaVector<ir::Decorator *> &&decorators) override
134    {
135        decorators_ = std::move(decorators);
136    }
137
138    bool CanHaveDecorator([[maybe_unused]] bool inTs) const override
139    {
140        return !inTs;
141    }
142
143    static varbinder::EnumMemberResult EvaluateEnumMember(checker::TSChecker *checker, varbinder::EnumVariable *enumVar,
144                                                          const ir::AstNode *expr);
145    void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
146    void Iterate(const NodeTraverser &cb) const override;
147    void Dump(ir::AstDumper *dumper) const override;
148    void Dump(ir::SrcDumper *dumper) const override;
149    void Compile(compiler::PandaGen *pg) const override;
150    void Compile(compiler::ETSGen *etsg) const override;
151    checker::Type *Check(checker::TSChecker *checker) override;
152    checker::Type *Check(checker::ETSChecker *checker) override;
153
154    void Accept(ASTVisitorT *v) override
155    {
156        v->Accept(this);
157    }
158
159private:
160    varbinder::LocalScope *scope_ {nullptr};
161    ArenaVector<ir::Decorator *> decorators_;
162    Identifier *key_;
163    ArenaVector<AstNode *> members_;
164    util::StringView internalName_;
165    ir::ClassDefinition *boxedClass_ {nullptr};
166    bool isConst_;
167    bool isDeclare_;
168};
169}  // namespace ark::es2panda::ir
170
171#endif
172