1 /*
2 * Copyright (c) 2021 - 2023 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/ets/typeRelationContext.h"
20 #include "checker/TSchecker.h"
21 #include "compiler/core/ETSGen.h"
22 #include "compiler/core/pandagen.h"
23 #include "ir/astDump.h"
24 #include "ir/srcDump.h"
25 #include "ir/typeNode.h"
26 #include "ir/expressions/identifier.h"
27 #include "ir/base/spreadElement.h"
28
29 namespace panda::es2panda::ir {
30
ETSParameterExpression(AnnotatedExpression * const identOrSpread,Expression * const initializer)31 ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, Expression *const initializer)
32 : Expression(AstNodeType::ETS_PARAMETER_EXPRESSION), initializer_(initializer)
33 {
34 ASSERT(identOrSpread != nullptr);
35
36 if (identOrSpread->IsIdentifier()) {
37 ident_ = identOrSpread->AsIdentifier();
38 } else if (identOrSpread->IsRestElement()) {
39 spread_ = identOrSpread->AsRestElement();
40 ASSERT(spread_->Argument()->IsIdentifier());
41 ident_ = spread_->Argument()->AsIdentifier();
42 ident_->SetParent(spread_);
43 initializer_ = nullptr; // Just in case!
44 } else {
45 UNREACHABLE();
46 }
47 }
48
Ident() const49 const Identifier *ETSParameterExpression::Ident() const noexcept
50 {
51 return ident_;
52 }
53
Ident()54 Identifier *ETSParameterExpression::Ident() noexcept
55 {
56 return ident_;
57 }
58
RestParameter() const59 const SpreadElement *ETSParameterExpression::RestParameter() const noexcept
60 {
61 return spread_;
62 }
63
RestParameter()64 SpreadElement *ETSParameterExpression::RestParameter() noexcept
65 {
66 return spread_;
67 }
68
Initializer() const69 const Expression *ETSParameterExpression::Initializer() const noexcept
70 {
71 return initializer_;
72 }
73
Initializer()74 Expression *ETSParameterExpression::Initializer() noexcept
75 {
76 return initializer_;
77 }
78
Variable() const79 varbinder::Variable *ETSParameterExpression::Variable() const noexcept
80 {
81 return ident_->Variable();
82 }
83
TypeAnnotation() const84 TypeNode const *ETSParameterExpression::TypeAnnotation() const noexcept
85 {
86 return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation();
87 }
88
TypeAnnotation()89 TypeNode *ETSParameterExpression::TypeAnnotation() noexcept
90 {
91 return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation();
92 }
93
SetVariable(varbinder::Variable * const variable)94 void ETSParameterExpression::SetVariable(varbinder::Variable *const variable) noexcept
95 {
96 ident_->SetVariable(variable);
97 }
98
SetLexerSaved(util::StringView s)99 void ETSParameterExpression::SetLexerSaved(util::StringView s) noexcept
100 {
101 savedLexer_ = s;
102 }
103
LexerSaved() const104 util::StringView ETSParameterExpression::LexerSaved() const noexcept
105 {
106 return savedLexer_;
107 }
108
TransformChildren(const NodeTransformer & cb)109 void ETSParameterExpression::TransformChildren(const NodeTransformer &cb)
110 {
111 if (IsRestParameter()) {
112 spread_ = cb(spread_)->AsRestElement();
113 ident_ = spread_->Argument()->AsIdentifier();
114 } else {
115 ident_ = cb(ident_)->AsIdentifier();
116 }
117
118 if (IsDefault()) {
119 initializer_ = cb(initializer_)->AsExpression();
120 }
121 }
122
Iterate(const NodeTraverser & cb) const123 void ETSParameterExpression::Iterate(const NodeTraverser &cb) const
124 {
125 if (IsRestParameter()) {
126 cb(spread_);
127 } else {
128 cb(ident_);
129 }
130
131 if (IsDefault()) {
132 cb(initializer_);
133 }
134 }
135
Dump(ir::AstDumper * const dumper) const136 void ETSParameterExpression::Dump(ir::AstDumper *const dumper) const
137 {
138 if (!IsRestParameter()) {
139 dumper->Add(
140 {{"type", "ETSParameterExpression"}, {"name", ident_}, {"initializer", AstDumper::Optional(initializer_)}});
141 } else {
142 dumper->Add({{"type", "ETSParameterExpression"}, {"rest parameter", spread_}});
143 }
144 }
145
Dump(ir::SrcDumper * const dumper) const146 void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const
147 {
148 if (IsRestParameter()) {
149 spread_->Dump(dumper);
150 } else {
151 if (ident_ != nullptr) {
152 ASSERT(ident_->IsAnnotatedExpression());
153 ident_->Dump(dumper);
154 auto typeAnnotation = ident_->AsAnnotatedExpression()->TypeAnnotation();
155 if (typeAnnotation != nullptr) {
156 dumper->Add(": ");
157 typeAnnotation->Dump(dumper);
158 }
159 }
160 if (initializer_ != nullptr) {
161 ASSERT(initializer_->IsNumberLiteral());
162 if (initializer_->AsNumberLiteral()->Str().Length() > 0) {
163 dumper->Add(" = ");
164 initializer_->Dump(dumper);
165 }
166 }
167 }
168 }
169
Compile(compiler::PandaGen * const pg) const170 void ETSParameterExpression::Compile(compiler::PandaGen *const pg) const
171 {
172 pg->GetAstCompiler()->Compile(this);
173 }
174
Compile(compiler::ETSGen * const etsg) const175 void ETSParameterExpression::Compile(compiler::ETSGen *const etsg) const
176 {
177 etsg->GetAstCompiler()->Compile(this);
178 }
179
Check(checker::TSChecker * const checker)180 checker::Type *ETSParameterExpression::Check(checker::TSChecker *const checker)
181 {
182 return checker->GetAnalyzer()->Check(this);
183 }
184
Check(checker::ETSChecker * const checker)185 checker::Type *ETSParameterExpression::Check(checker::ETSChecker *const checker)
186 {
187 return checker->GetAnalyzer()->Check(this);
188 }
189
190 // NOLINTNEXTLINE(google-default-arguments)
Clone(ArenaAllocator * const allocator,AstNode * const parent)191 ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent)
192 {
193 auto *const identOrSpread = spread_ != nullptr ? spread_->Clone(allocator)->AsAnnotatedExpression()
194 : ident_->Clone(allocator)->AsAnnotatedExpression();
195 auto *const initializer = initializer_ != nullptr ? initializer_->Clone(allocator)->AsExpression() : nullptr;
196
197 if (auto *const clone = allocator->New<ETSParameterExpression>(identOrSpread, initializer); clone != nullptr) {
198 identOrSpread->SetParent(clone);
199
200 if (initializer != nullptr) {
201 initializer->SetParent(clone);
202 }
203
204 if (parent != nullptr) {
205 clone->SetParent(parent);
206 }
207
208 clone->SetRequiredParams(extraValue_);
209 return clone;
210 }
211
212 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR);
213 }
214 } // namespace panda::es2panda::ir
215