• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 "methodDefinition.h"
17 
18 #include "checker/TSchecker.h"
19 #include "compiler/core/ETSGen.h"
20 #include "compiler/core/pandagen.h"
21 #include "ir/astDump.h"
22 #include "ir/srcDump.h"
23 
24 namespace ark::es2panda::ir {
25 
Function()26 ScriptFunction *MethodDefinition::Function()
27 {
28     return value_->IsFunctionExpression() ? value_->AsFunctionExpression()->Function() : nullptr;
29 }
30 
Function() const31 const ScriptFunction *MethodDefinition::Function() const
32 {
33     return value_->IsFunctionExpression() ? value_->AsFunctionExpression()->Function() : nullptr;
34 }
35 
ToPrivateFieldKind(bool const isStatic) const36 PrivateFieldKind MethodDefinition::ToPrivateFieldKind(bool const isStatic) const
37 {
38     switch (kind_) {
39         case MethodDefinitionKind::METHOD: {
40             return isStatic ? PrivateFieldKind::STATIC_METHOD : PrivateFieldKind::METHOD;
41         }
42         case MethodDefinitionKind::GET: {
43             return isStatic ? PrivateFieldKind::STATIC_GET : PrivateFieldKind::GET;
44         }
45         case MethodDefinitionKind::SET: {
46             return isStatic ? PrivateFieldKind::STATIC_SET : PrivateFieldKind::SET;
47         }
48         default: {
49             UNREACHABLE();
50         }
51     }
52 }
53 
ResolveReferences(const NodeTraverser & cb) const54 void MethodDefinition::ResolveReferences(const NodeTraverser &cb) const
55 {
56     cb(key_);
57     cb(value_);
58 
59     for (auto *it : overloads_) {
60         cb(it);
61     }
62 
63     for (auto *it : decorators_) {
64         cb(it);
65     }
66 }
67 
Iterate(const NodeTraverser & cb) const68 void MethodDefinition::Iterate(const NodeTraverser &cb) const
69 {
70     cb(key_);
71     cb(value_);
72 
73     for (auto *it : overloads_) {
74         if (it->Parent() == this) {
75             cb(it);
76         }
77     }
78 
79     for (auto *it : decorators_) {
80         cb(it);
81     }
82 }
83 
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)84 void MethodDefinition::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
85 {
86     if (auto *transformedNode = cb(key_); key_ != transformedNode) {
87         key_->SetTransformedNode(transformationName, transformedNode);
88         key_ = transformedNode->AsExpression();
89     }
90 
91     if (auto *transformedNode = cb(value_); value_ != transformedNode) {
92         value_->SetTransformedNode(transformationName, transformedNode);
93         value_ = transformedNode->AsExpression();
94     }
95 
96     for (auto *&it : overloads_) {
97         if (auto *transformedNode = cb(it); it != transformedNode) {
98             it->SetTransformedNode(transformationName, transformedNode);
99             it = transformedNode->AsMethodDefinition();
100         }
101     }
102 
103     for (auto *&it : decorators_) {
104         if (auto *transformedNode = cb(it); it != transformedNode) {
105             it->SetTransformedNode(transformationName, transformedNode);
106             it = transformedNode->AsDecorator();
107         }
108     }
109 }
110 
Dump(ir::AstDumper * dumper) const111 void MethodDefinition::Dump(ir::AstDumper *dumper) const
112 {
113     const char *kind = nullptr;
114 
115     switch (kind_) {
116         case MethodDefinitionKind::CONSTRUCTOR: {
117             kind = "constructor";
118             break;
119         }
120         case MethodDefinitionKind::METHOD: {
121             kind = "method";
122             break;
123         }
124         case MethodDefinitionKind::EXTENSION_METHOD: {
125             kind = "extensionmethod";
126             break;
127         }
128         case MethodDefinitionKind::GET: {
129             kind = "get";
130             break;
131         }
132         case MethodDefinitionKind::SET: {
133             kind = "set";
134             break;
135         }
136         default: {
137             UNREACHABLE();
138         }
139     }
140 
141     dumper->Add({{"type", "MethodDefinition"},
142                  {"key", key_},
143                  {"kind", kind},
144                  {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(flags_))},
145                  {"static", IsStatic()},
146                  {"optional", IsOptionalDeclaration()},
147                  {"computed", isComputed_},
148                  {"value", value_},
149                  {"overloads", overloads_},
150                  {"decorators", decorators_}});
151 }
152 
Dump(ir::SrcDumper * dumper) const153 void MethodDefinition::Dump(ir::SrcDumper *dumper) const
154 {
155     for (auto method : overloads_) {
156         method->Dump(dumper);
157         dumper->Endl();
158     }
159 
160     if (IsPrivate()) {
161         dumper->Add("private ");
162     } else if (IsProtected()) {
163         dumper->Add("protected ");
164     } else if (IsInternal()) {
165         dumper->Add("internal ");
166     } else {
167         dumper->Add("public ");
168     }
169 
170     if (IsStatic()) {
171         dumper->Add("static ");
172     }
173 
174     if (IsAbstract()) {
175         dumper->Add("abstract ");
176     }
177 
178     if (IsFinal()) {
179         dumper->Add("final ");
180     }
181 
182     if (IsNative()) {
183         dumper->Add("native ");
184     }
185 
186     if (IsAsync()) {
187         dumper->Add("async ");
188     }
189 
190     if (IsOverride()) {
191         dumper->Add("override ");
192     }
193 
194     if (key_ != nullptr) {
195         key_->Dump(dumper);
196     }
197 
198     if (value_ != nullptr) {
199         value_->Dump(dumper);
200     }
201 }
202 
Compile(compiler::PandaGen * pg) const203 void MethodDefinition::Compile(compiler::PandaGen *pg) const
204 {
205     pg->GetAstCompiler()->Compile(this);
206 }
207 
Compile(compiler::ETSGen * etsg) const208 void MethodDefinition::Compile(compiler::ETSGen *etsg) const
209 {
210     etsg->GetAstCompiler()->Compile(this);
211 }
212 
Check(checker::TSChecker * checker)213 checker::Type *MethodDefinition::Check(checker::TSChecker *checker)
214 {
215     return checker->GetAnalyzer()->Check(this);
216 }
217 
Check(checker::ETSChecker * checker)218 checker::Type *MethodDefinition::Check(checker::ETSChecker *checker)
219 {
220     return checker->GetAnalyzer()->Check(this);
221 }
222 
Clone(ArenaAllocator * const allocator,AstNode * const parent)223 MethodDefinition *MethodDefinition::Clone(ArenaAllocator *const allocator, AstNode *const parent)
224 {
225     auto *const key = key_ != nullptr ? key_->Clone(allocator, nullptr)->AsExpression() : nullptr;
226     auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr;
227 
228     if (auto *const clone = allocator->New<MethodDefinition>(kind_, key, value, flags_, allocator, isComputed_);
229         clone != nullptr) {
230         if (parent != nullptr) {
231             clone->SetParent(parent);
232         }
233 
234         if (key != nullptr) {
235             key->SetParent(clone);
236         }
237 
238         if (value != nullptr) {
239             value->SetParent(clone);
240         }
241 
242         for (auto *const decorator : decorators_) {
243             clone->AddDecorator(decorator->Clone(allocator, clone));
244         }
245 
246         for (auto *const overloads : overloads_) {
247             clone->AddOverload(overloads->Clone(allocator, clone));
248         }
249 
250         return clone;
251     }
252 
253     throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR);
254 }
255 }  // namespace ark::es2panda::ir
256