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