• 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 "etsParameterExpression.h"
17 
18 #include "checker/ETSchecker.h"
19 #include "checker/TSchecker.h"
20 #include "compiler/core/ETSGen.h"
21 #include "compiler/core/pandagen.h"
22 
23 namespace ark::es2panda::ir {
24 
ETSParameterExpression(AnnotatedExpression * const identOrSpread,bool isOptional,ArenaAllocator * const allocator)25 ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, bool isOptional,
26                                                ArenaAllocator *const allocator)
27     : AnnotationAllowed<Expression>(AstNodeType::ETS_PARAMETER_EXPRESSION, allocator)
28 {
29     SetOptional(isOptional);
30 
31     if (identOrSpread == nullptr) {
32         return;
33     }
34     identOrSpread->SetParent(this);
35     SetRange(identOrSpread->Range());
36     if (identOrSpread->IsIdentifier()) {
37         ident_ = identOrSpread->AsIdentifier();
38     } else if (identOrSpread->IsRestElement()) {
39         spread_ = identOrSpread->AsRestElement();
40         ES2PANDA_ASSERT(spread_->Argument()->IsIdentifier());
41         ident_ = spread_->Argument()->AsIdentifier();
42         ident_->SetParent(spread_);
43     } else {
44         ES2PANDA_UNREACHABLE();
45     }
46 }
47 
ETSParameterExpression(AnnotatedExpression * const identOrSpread,ir::Expression * initializer,ArenaAllocator * const allocator)48 ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, ir::Expression *initializer,
49                                                ArenaAllocator *const allocator)
50     : ETSParameterExpression(identOrSpread, true, allocator)
51 {
52     SetInitializer(initializer);
53 }
54 
Name() const55 const util::StringView &ETSParameterExpression::Name() const noexcept
56 {
57     return ident_->Name();
58 }
59 
Ident() const60 const Identifier *ETSParameterExpression::Ident() const noexcept
61 {
62     return ident_;
63 }
64 
Ident()65 Identifier *ETSParameterExpression::Ident() noexcept
66 {
67     return ident_;
68 }
69 
RestParameter() const70 const SpreadElement *ETSParameterExpression::RestParameter() const noexcept
71 {
72     return spread_;
73 }
74 
RestParameter()75 SpreadElement *ETSParameterExpression::RestParameter() noexcept
76 {
77     return spread_;
78 }
79 
Initializer() const80 const Expression *ETSParameterExpression::Initializer() const noexcept
81 {
82     return initializer_;
83 }
84 
Initializer()85 Expression *ETSParameterExpression::Initializer() noexcept
86 {
87     return initializer_;
88 }
89 
Variable() const90 varbinder::Variable *ETSParameterExpression::Variable() const noexcept
91 {
92     return ident_->Variable();
93 }
94 
TypeAnnotation() const95 TypeNode const *ETSParameterExpression::TypeAnnotation() const noexcept
96 {
97     return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation();
98 }
99 
TypeAnnotation()100 TypeNode *ETSParameterExpression::TypeAnnotation() noexcept
101 {
102     return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation();
103 }
104 
SetTypeAnnotation(TypeNode * typeNode)105 void ETSParameterExpression::SetTypeAnnotation(TypeNode *typeNode) noexcept
106 {
107     !IsRestParameter() ? ident_->SetTsTypeAnnotation(typeNode) : spread_->SetTsTypeAnnotation(typeNode);
108 }
109 
SetVariable(varbinder::Variable * const variable)110 void ETSParameterExpression::SetVariable(varbinder::Variable *const variable) noexcept
111 {
112     ident_->SetVariable(variable);
113 }
114 
SetLexerSaved(util::StringView s)115 void ETSParameterExpression::SetLexerSaved(util::StringView s) noexcept
116 {
117     savedLexer_ = s;
118 }
119 
LexerSaved() const120 util::StringView ETSParameterExpression::LexerSaved() const noexcept
121 {
122     return savedLexer_;
123 }
124 
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)125 void ETSParameterExpression::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
126 {
127     if (IsRestParameter()) {
128         if (auto *transformedNode = cb(spread_); spread_ != transformedNode) {
129             spread_->SetTransformedNode(transformationName, transformedNode);
130             spread_ = transformedNode->AsRestElement();
131         }
132         ident_ = spread_->Argument()->AsIdentifier();
133     } else {
134         if (auto *transformedNode = cb(ident_); ident_ != transformedNode) {
135             ident_->SetTransformedNode(transformationName, transformedNode);
136             ident_ = transformedNode->AsIdentifier();
137         }
138     }
139 
140     if (initializer_ != nullptr) {
141         if (auto *transformedNode = cb(initializer_); initializer_ != transformedNode) {
142             initializer_->SetTransformedNode(transformationName, transformedNode);
143             initializer_ = transformedNode->AsExpression();
144         }
145     }
146 
147     for (auto *&it : Annotations()) {
148         if (auto *transformedNode = cb(it); it != transformedNode) {
149             it->SetTransformedNode(transformationName, transformedNode);
150             it = transformedNode->AsAnnotationUsage();
151         }
152     }
153 }
154 
Iterate(const NodeTraverser & cb) const155 void ETSParameterExpression::Iterate(const NodeTraverser &cb) const
156 {
157     if (IsRestParameter()) {
158         cb(spread_);
159     } else {
160         cb(ident_);
161     }
162 
163     if (initializer_ != nullptr) {
164         cb(initializer_);
165     }
166 
167     for (auto *it : Annotations()) {
168         cb(it);
169     }
170 }
171 
Dump(ir::AstDumper * const dumper) const172 void ETSParameterExpression::Dump(ir::AstDumper *const dumper) const
173 {
174     if (!IsRestParameter()) {
175         dumper->Add({{"type", "ETSParameterExpression"},
176                      {"name", ident_},
177                      {"initializer", AstDumper::Optional(initializer_)},
178                      {"annotations", AstDumper::Optional(Annotations())}});
179     } else {
180         dumper->Add({{"type", "ETSParameterExpression"},
181                      {"rest parameter", spread_},
182                      {"annotations", AstDumper::Optional(Annotations())}});
183     }
184 }
185 
Dump(ir::SrcDumper * const dumper) const186 void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const
187 {
188     for (auto *anno : Annotations()) {
189         anno->Dump(dumper);
190     }
191 
192     if (IsRestParameter()) {
193         spread_->Dump(dumper);
194     } else {
195         if (ident_ != nullptr) {
196             ES2PANDA_ASSERT(ident_->IsAnnotatedExpression());
197             ident_->Dump(dumper);
198             if (isOptional_ && initializer_ == nullptr) {
199                 dumper->Add("?");
200             }
201             auto typeAnnotation = ident_->AsAnnotatedExpression()->TypeAnnotation();
202             if (typeAnnotation != nullptr) {
203                 dumper->Add(": ");
204                 typeAnnotation->Dump(dumper);
205             }
206         }
207         if (initializer_ != nullptr) {
208             dumper->Add(" = ");
209             initializer_->Dump(dumper);
210         }
211     }
212 }
213 
Compile(compiler::PandaGen * const pg) const214 void ETSParameterExpression::Compile(compiler::PandaGen *const pg) const
215 {
216     pg->GetAstCompiler()->Compile(this);
217 }
218 
Compile(compiler::ETSGen * const etsg) const219 void ETSParameterExpression::Compile(compiler::ETSGen *const etsg) const
220 {
221     etsg->GetAstCompiler()->Compile(this);
222 }
223 
Check(checker::TSChecker * const checker)224 checker::Type *ETSParameterExpression::Check(checker::TSChecker *const checker)
225 {
226     return checker->GetAnalyzer()->Check(this);
227 }
228 
Check(checker::ETSChecker * const checker)229 checker::VerifiedType ETSParameterExpression::Check(checker::ETSChecker *const checker)
230 {
231     return {this, checker->GetAnalyzer()->Check(this)};
232 }
233 
Clone(ArenaAllocator * const allocator,AstNode * const parent)234 ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent)
235 {
236     AnnotatedExpression *identOrSpread = nullptr;
237     if (spread_ != nullptr) {
238         auto spreadClone = spread_->Clone(allocator, nullptr);
239         ES2PANDA_ASSERT(spreadClone != nullptr);
240         identOrSpread = spreadClone->AsAnnotatedExpression();
241     } else {
242         auto identClone = ident_->Clone(allocator, nullptr);
243         ES2PANDA_ASSERT(identClone != nullptr);
244         identOrSpread = identClone->AsAnnotatedExpression();
245     }
246     auto *const initializer =
247         initializer_ != nullptr ? initializer_->Clone(allocator, nullptr)->AsExpression() : nullptr;
248 
249     auto *const clone = initializer_ != nullptr
250                             ? allocator->New<ETSParameterExpression>(identOrSpread, initializer, allocator)
251                             : allocator->New<ETSParameterExpression>(identOrSpread, isOptional_, allocator);
252     identOrSpread->SetParent(clone);
253 
254     if (initializer != nullptr) {
255         initializer->SetParent(clone);
256     }
257 
258     ES2PANDA_ASSERT(clone != nullptr);
259     if (parent != nullptr) {
260         clone->SetParent(parent);
261     }
262 
263     clone->SetRequiredParams(extraValue_);
264 
265     if (!Annotations().empty()) {
266         ArenaVector<AnnotationUsage *> annotationUsages {allocator->Adapter()};
267         for (auto *annotationUsage : Annotations()) {
268             auto *const annotationClone = annotationUsage->Clone(allocator, clone);
269             ES2PANDA_ASSERT(annotationClone != nullptr);
270             annotationUsages.push_back(annotationClone->AsAnnotationUsage());
271         }
272         clone->SetAnnotations(std::move(annotationUsages));
273     }
274 
275     return clone;
276 }
277 
Construct(ArenaAllocator * allocator)278 ETSParameterExpression *ETSParameterExpression::Construct(ArenaAllocator *allocator)
279 {
280     return allocator->New<ETSParameterExpression>(nullptr, false, allocator);
281 }
282 
CopyTo(AstNode * other) const283 void ETSParameterExpression::CopyTo(AstNode *other) const
284 {
285     auto otherImpl = other->AsETSParameterExpression();
286 
287     otherImpl->ident_ = ident_;
288     otherImpl->initializer_ = initializer_;
289     otherImpl->spread_ = spread_;
290     otherImpl->savedLexer_ = savedLexer_;
291     otherImpl->extraValue_ = extraValue_;
292     otherImpl->isOptional_ = isOptional_;
293 
294     AnnotationAllowed<Expression>::CopyTo(other);
295 }
296 
297 }  // namespace ark::es2panda::ir
298