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 
22 namespace ark::es2panda::varbinder {
23 class EnumVariable;
24 }  // namespace ark::es2panda::varbinder
25 
26 namespace ark::es2panda::ir {
27 class Identifier;
28 class TSEnumMember;
29 
30 class TSEnumDeclaration : public TypedStatement {
31 public:
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 
TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector<AstNode *> &&members, ConstructorFlags &&flags)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 
SetScope(varbinder::LocalScope *scope)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 
Key() const78     const Identifier *Key() const
79     {
80         return key_;
81     }
82 
Key()83     Identifier *Key()
84     {
85         return key_;
86     }
87 
Members() const88     const ArenaVector<AstNode *> &Members() const
89     {
90         return members_;
91     }
92 
InternalName() const93     const util::StringView &InternalName() const
94     {
95         return internalName_;
96     }
97 
SetInternalName(util::StringView internalName)98     void SetInternalName(util::StringView internalName)
99     {
100         internalName_ = internalName;
101     }
102 
BoxedClass() const103     ir::ClassDefinition *BoxedClass() const
104     {
105         return boxedClass_;
106     }
107 
SetBoxedClass(ir::ClassDefinition *const wrapperClass)108     void SetBoxedClass(ir::ClassDefinition *const wrapperClass)
109     {
110         boxedClass_ = wrapperClass;
111     }
112 
IsConst() const113     bool IsConst() const
114     {
115         return isConst_;
116     }
117 
IsDeclare() const118     bool IsDeclare() const
119     {
120         return isDeclare_;
121     }
122 
Decorators() const123     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 
159 private:
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