• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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