1 /**
2 * Copyright (c) 2021-2025 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 #include "tsInterfaceDeclaration.h"
17
18 #include "util/es2pandaMacros.h"
19 #include "utils/arena_containers.h"
20 #include "varbinder/declaration.h"
21 #include "varbinder/variable.h"
22 #include "checker/TSchecker.h"
23 #include "checker/ETSchecker.h"
24 #include "compiler/core/ETSGen.h"
25 #include "compiler/core/pandagen.h"
26 #include "ir/astDump.h"
27 #include "ir/srcDump.h"
28 #include "ir/base/decorator.h"
29 #include "ir/expressions/identifier.h"
30 #include "ir/ts/tsInterfaceBody.h"
31 #include "ir/ts/tsInterfaceHeritage.h"
32 #include "ir/ts/tsTypeParameter.h"
33 #include "ir/ts/tsTypeParameterDeclaration.h"
34 #include "util/language.h"
35
36 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view transformationName)37 void TSInterfaceDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName)
38 {
39 for (auto *&it : VectorIterationGuard(decorators_)) {
40 if (auto *transformedNode = cb(it); it != transformedNode) {
41 it->SetTransformedNode(transformationName, transformedNode);
42 it = transformedNode->AsDecorator();
43 }
44 }
45
46 for (auto *&it : Annotations()) {
47 if (auto *transformedNode = cb(it); it != transformedNode) {
48 it->SetTransformedNode(transformationName, transformedNode);
49 it = transformedNode->AsAnnotationUsage();
50 }
51 }
52
53 if (auto *transformedNode = cb(id_); id_ != transformedNode) {
54 id_->SetTransformedNode(transformationName, transformedNode);
55 id_ = transformedNode->AsIdentifier();
56 }
57
58 if (typeParams_ != nullptr) {
59 if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) {
60 typeParams_->SetTransformedNode(transformationName, transformedNode);
61 typeParams_ = transformedNode->AsTSTypeParameterDeclaration();
62 }
63 }
64
65 for (auto *&it : VectorIterationGuard(extends_)) {
66 if (auto *transformedNode = cb(it); it != transformedNode) {
67 it->SetTransformedNode(transformationName, transformedNode);
68 it = transformedNode->AsTSInterfaceHeritage();
69 }
70 }
71
72 if (auto *transformedNode = cb(body_); body_ != transformedNode) {
73 body_->SetTransformedNode(transformationName, transformedNode);
74 body_ = transformedNode->AsTSInterfaceBody();
75 }
76 }
77
Iterate(const NodeTraverser & cb) const78 void TSInterfaceDeclaration::Iterate(const NodeTraverser &cb) const
79 {
80 for (auto *it : VectorIterationGuard(decorators_)) {
81 cb(it);
82 }
83
84 for (auto *it : Annotations()) {
85 cb(it);
86 }
87
88 cb(id_);
89
90 if (typeParams_ != nullptr) {
91 cb(typeParams_);
92 }
93
94 for (auto *it : VectorIterationGuard(extends_)) {
95 cb(it);
96 }
97
98 cb(body_);
99 }
100
Dump(ir::AstDumper * dumper) const101 void TSInterfaceDeclaration::Dump(ir::AstDumper *dumper) const
102 {
103 dumper->Add({{"type", "TSInterfaceDeclaration"},
104 {"decorators", AstDumper::Optional(decorators_)},
105 {"annotations", AstDumper::Optional(Annotations())},
106 {"body", body_},
107 {"id", id_},
108 {"extends", extends_},
109 {"typeParameters", AstDumper::Optional(typeParams_)}});
110 }
111
RegisterUnexportedForDeclGen(ir::SrcDumper * dumper) const112 bool TSInterfaceDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const
113 {
114 if (!dumper->IsDeclgen()) {
115 return false;
116 }
117
118 if (dumper->IsIndirectDepPhase()) {
119 return false;
120 }
121
122 if (id_->Parent()->IsDefaultExported() || id_->Parent()->IsExported()) {
123 return false;
124 }
125
126 auto name = id_->Name().Mutf8();
127 dumper->AddNode(name, this);
128 return true;
129 }
130
Dump(ir::SrcDumper * dumper) const131 void TSInterfaceDeclaration::Dump(ir::SrcDumper *dumper) const
132 {
133 ES2PANDA_ASSERT(id_);
134 if (!id_->Parent()->IsDefaultExported() && !id_->Parent()->IsExported() && dumper->IsDeclgen() &&
135 !dumper->IsIndirectDepPhase()) {
136 auto name = id_->Name().Mutf8();
137 dumper->AddNode(name, this);
138 return;
139 }
140 for (auto *anno : Annotations()) {
141 anno->Dump(dumper);
142 }
143 if (id_->Parent()->IsExported()) {
144 dumper->Add("export ");
145 } else if (id_->Parent()->IsDefaultExported()) {
146 dumper->Add("export default ");
147 }
148 if (IsDeclare() || dumper->IsDeclgen()) {
149 dumper->Add("declare ");
150 }
151 dumper->Add("interface ");
152 id_->Dump(dumper);
153
154 if (typeParams_ != nullptr) {
155 dumper->Add("<");
156 typeParams_->Dump(dumper);
157 dumper->Add(">");
158 }
159 if (!extends_.empty()) {
160 dumper->Add(" extends ");
161 for (auto ext : extends_) {
162 ext->Dump(dumper);
163 if (ext != extends_.back()) {
164 dumper->Add(", ");
165 }
166 }
167 }
168
169 dumper->Add(" {");
170 if (body_ != nullptr) {
171 dumper->IncrIndent();
172 dumper->Endl();
173 body_->Dump(dumper);
174 dumper->DecrIndent();
175 dumper->Endl();
176 }
177 dumper->Add("}");
178 dumper->Endl();
179 }
180
Compile(compiler::PandaGen * pg) const181 void TSInterfaceDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const
182 {
183 pg->GetAstCompiler()->Compile(this);
184 }
185
Compile(compiler::ETSGen * etsg) const186 void TSInterfaceDeclaration::Compile(compiler::ETSGen *etsg) const
187 {
188 etsg->GetAstCompiler()->Compile(this);
189 }
190
Check(checker::TSChecker * checker)191 checker::Type *TSInterfaceDeclaration::Check([[maybe_unused]] checker::TSChecker *checker)
192 {
193 return checker->GetAnalyzer()->Check(this);
194 }
195
Check(checker::ETSChecker * checker)196 checker::VerifiedType TSInterfaceDeclaration::Check(checker::ETSChecker *checker)
197 {
198 return {this, checker->GetAnalyzer()->Check(this)};
199 }
200
Construct(ArenaAllocator * allocator)201 TSInterfaceDeclaration *TSInterfaceDeclaration::Construct(ArenaAllocator *allocator)
202 {
203 ArenaVector<TSInterfaceHeritage *> extends(allocator->Adapter());
204 return allocator->New<TSInterfaceDeclaration>(
205 allocator, std::move(extends), ConstructorData {nullptr, nullptr, nullptr, false, false, Language::Id::COUNT});
206 }
207
CopyTo(AstNode * other) const208 void TSInterfaceDeclaration::CopyTo(AstNode *other) const
209 {
210 auto otherImpl = other->AsTSInterfaceDeclaration();
211
212 otherImpl->decorators_ = decorators_;
213 otherImpl->scope_ = scope_;
214 otherImpl->id_ = id_;
215 otherImpl->typeParams_ = typeParams_;
216 otherImpl->body_ = body_;
217 otherImpl->extends_ = extends_;
218 otherImpl->internalName_ = internalName_;
219 otherImpl->isStatic_ = isStatic_;
220 otherImpl->isExternal_ = isExternal_;
221 otherImpl->lang_ = lang_;
222 otherImpl->anonClass_ = anonClass_;
223
224 JsDocAllowed<AnnotationAllowed<TypedStatement>>::CopyTo(other);
225 }
226
227 } // namespace ark::es2panda::ir
228