• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "variableDeclaration.h"
17 
18 #include "checker/TSchecker.h"
19 #include "checker/ETSchecker.h"
20 #include "compiler/core/ETSGen.h"
21 #include "compiler/core/pandagen.h"
22 #include "utils/arena_containers.h"
23 
24 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view transformationName)25 void VariableDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName)
26 {
27     for (auto *&it : VectorIterationGuard(decorators_)) {
28         if (auto *transformedNode = cb(it); it != transformedNode) {
29             it->SetTransformedNode(transformationName, transformedNode);
30             it = transformedNode->AsDecorator();
31         }
32     }
33 
34     for (auto *&it : VectorIterationGuard(Annotations())) {
35         if (auto *transformedNode = cb(it); it != transformedNode) {
36             it->SetTransformedNode(transformationName, transformedNode);
37             it = transformedNode->AsAnnotationUsage();
38         }
39     }
40 
41     for (auto *&it : VectorIterationGuard(declarators_)) {
42         if (auto *transformedNode = cb(it); it != transformedNode) {
43             it->SetTransformedNode(transformationName, transformedNode);
44             it = transformedNode->AsVariableDeclarator();
45         }
46     }
47 }
48 
Iterate(const NodeTraverser & cb) const49 void VariableDeclaration::Iterate(const NodeTraverser &cb) const
50 {
51     for (auto *it : VectorIterationGuard(decorators_)) {
52         cb(it);
53     }
54 
55     for (auto *it : VectorIterationGuard(Annotations())) {
56         cb(it);
57     }
58 
59     for (auto *it : VectorIterationGuard(declarators_)) {
60         cb(it);
61     }
62 }
63 
Dump(ir::AstDumper * dumper) const64 void VariableDeclaration::Dump(ir::AstDumper *dumper) const
65 {
66     const char *kind = nullptr;
67 
68     switch (kind_) {
69         case VariableDeclarationKind::CONST: {
70             kind = "const";
71             break;
72         }
73         case VariableDeclarationKind::LET: {
74             kind = "let";
75             break;
76         }
77         case VariableDeclarationKind::VAR: {
78             kind = "var";
79             break;
80         }
81         default: {
82             ES2PANDA_UNREACHABLE();
83         }
84     }
85 
86     dumper->Add({{"type", "VariableDeclaration"},
87                  {"declarations", declarators_},
88                  {"kind", kind},
89                  {"decorators", AstDumper::Optional(decorators_)},
90                  {"annotations", AstDumper::Optional(Annotations())},
91                  {"declare", AstDumper::Optional(IsDeclare())}});
92 }
93 
Dump(ir::SrcDumper * dumper) const94 void VariableDeclaration::Dump(ir::SrcDumper *dumper) const
95 {
96     for (auto *anno : Annotations()) {
97         anno->Dump(dumper);
98     }
99 
100     if (IsDeclare()) {
101         dumper->Add("declare ");
102     }
103 
104     switch (kind_) {
105         case VariableDeclarationKind::CONST:
106             dumper->Add("const ");
107             break;
108         case VariableDeclarationKind::LET:
109             dumper->Add("let ");
110             break;
111         case VariableDeclarationKind::VAR:
112             dumper->Add("var ");
113             break;
114         default:
115             ES2PANDA_UNREACHABLE();
116     }
117 
118     for (auto declarator : declarators_) {
119         declarator->Dump(dumper);
120         if (declarator != declarators_.back()) {
121             dumper->Add(", ");
122         }
123     }
124 
125     if ((parent_ != nullptr) &&
126         (parent_->IsBlockStatement() || parent_->IsBlockExpression() || parent_->IsSwitchCaseStatement())) {
127         dumper->Add(";");
128     }
129 }
130 
VariableDeclaration(Tag const tag,VariableDeclaration const & other,ArenaAllocator * const allocator)131 VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, VariableDeclaration const &other,
132                                          ArenaAllocator *const allocator)
133     : JsDocAllowed<AnnotationAllowed<Statement>>(static_cast<JsDocAllowed<AnnotationAllowed<Statement>> const &>(other),
134                                                  allocator),
135       kind_(other.kind_),
136       decorators_(allocator->Adapter()),
137       declarators_(allocator->Adapter())
138 {
139     for (auto const &d : other.decorators_) {
140         decorators_.emplace_back(d->Clone(allocator, nullptr));
141         decorators_.back()->SetParent(this);
142     }
143 
144     for (auto const &d : other.declarators_) {
145         auto *dClone = d->Clone(allocator, nullptr);
146         ES2PANDA_ASSERT(dClone != nullptr);
147         declarators_.emplace_back(dClone->AsVariableDeclarator());
148         declarators_.back()->SetParent(this);
149     }
150 }
151 
Clone(ArenaAllocator * const allocator,AstNode * const parent)152 VariableDeclaration *VariableDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent)
153 {
154     auto *const clone = allocator->New<VariableDeclaration>(Tag {}, *this, allocator);
155     ES2PANDA_ASSERT(clone != nullptr);
156     if (parent != nullptr) {
157         clone->SetParent(parent);
158     }
159     clone->SetRange(range_);
160     return clone;
161 }
162 
Compile(compiler::PandaGen * pg) const163 void VariableDeclaration::Compile(compiler::PandaGen *pg) const
164 {
165     pg->GetAstCompiler()->Compile(this);
166 }
167 
Compile(compiler::ETSGen * etsg) const168 void VariableDeclaration::Compile(compiler::ETSGen *etsg) const
169 {
170     etsg->GetAstCompiler()->Compile(this);
171 }
172 
Check(checker::TSChecker * checker)173 checker::Type *VariableDeclaration::Check(checker::TSChecker *checker)
174 {
175     return checker->GetAnalyzer()->Check(this);
176 }
177 
Check(checker::ETSChecker * checker)178 checker::VerifiedType VariableDeclaration::Check([[maybe_unused]] checker::ETSChecker *checker)
179 {
180     return {this, checker->GetAnalyzer()->Check(this)};
181 }
182 
Construct(ArenaAllocator * allocator)183 VariableDeclaration *VariableDeclaration::Construct(ArenaAllocator *allocator)
184 {
185     ArenaVector<VariableDeclarator *> declarators(allocator->Adapter());
186     return allocator->New<VariableDeclaration>(VariableDeclarationKind::LET, allocator, std::move(declarators));
187 }
188 
CopyTo(AstNode * other) const189 void VariableDeclaration::CopyTo(AstNode *other) const
190 {
191     auto otherImpl = other->AsVariableDeclaration();
192 
193     otherImpl->kind_ = kind_;
194     otherImpl->decorators_ = decorators_;
195     otherImpl->declarators_ = declarators_;
196 
197     JsDocAllowed<AnnotationAllowed<Statement>>::CopyTo(other);
198 }
199 
200 }  // namespace ark::es2panda::ir
201