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 #ifndef ES2PANDA_PARSER_INCLUDE_AST_METHOD_DEFINITION_H 17 #define ES2PANDA_PARSER_INCLUDE_AST_METHOD_DEFINITION_H 18 19 #include "ir/base/classElement.h" 20 21 namespace ark::es2panda::checker { 22 class ETSAnalyzer; 23 } // namespace ark::es2panda::checker 24 25 namespace ark::es2panda::ir { 26 27 class Expression; 28 class ScriptFunction; 29 30 enum class MethodDefinitionKind { NONE, CONSTRUCTOR, METHOD, EXTENSION_METHOD, GET, SET }; 31 32 class MethodDefinition : public ClassElement { 33 public: 34 MethodDefinition() = delete; 35 ~MethodDefinition() override = default; 36 37 NO_COPY_SEMANTIC(MethodDefinition); 38 NO_MOVE_SEMANTIC(MethodDefinition); 39 40 using OverloadsT = ArenaVector<MethodDefinition *>; 41 MethodDefinition(MethodDefinitionKind const kind, Expression *const key, Expression *const value, ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed)42 explicit MethodDefinition(MethodDefinitionKind const kind, Expression *const key, Expression *const value, 43 ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed) 44 : ClassElement(AstNodeType::METHOD_DEFINITION, key, value, modifiers, allocator, isComputed), 45 kind_(kind), 46 overloads_(allocator->Adapter()), 47 baseOverloadMethod_(nullptr), 48 asyncPairMethod_(nullptr) 49 { 50 ASSERT(key_ != nullptr); 51 ASSERT(value != nullptr); 52 } 53 54 // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields 55 friend class checker::ETSAnalyzer; 56 Kind() const57 MethodDefinitionKind Kind() const 58 { 59 return kind_; 60 } 61 62 [[nodiscard]] bool IsConstructor() const noexcept 63 { 64 return kind_ == MethodDefinitionKind::CONSTRUCTOR; 65 } 66 67 [[nodiscard]] bool IsExtensionMethod() const noexcept 68 { 69 return kind_ == MethodDefinitionKind::EXTENSION_METHOD; 70 } 71 72 [[nodiscard]] const OverloadsT &Overloads() const noexcept 73 { 74 return overloads_; 75 } 76 77 [[nodiscard]] const MethodDefinition *BaseOverloadMethod() const noexcept 78 { 79 return baseOverloadMethod_; 80 } 81 82 [[nodiscard]] MethodDefinition *BaseOverloadMethod() noexcept 83 { 84 return baseOverloadMethod_; 85 } 86 87 [[nodiscard]] const MethodDefinition *AsyncPairMethod() const noexcept 88 { 89 return asyncPairMethod_; 90 } 91 92 [[nodiscard]] MethodDefinition *AsyncPairMethod() noexcept 93 { 94 return asyncPairMethod_; 95 } 96 SetOverloads(OverloadsT &&overloads)97 void SetOverloads(OverloadsT &&overloads) 98 { 99 overloads_ = std::move(overloads); 100 } 101 ClearOverloads()102 void ClearOverloads() 103 { 104 overloads_.clear(); 105 } 106 AddOverload(MethodDefinition *const overload)107 void AddOverload(MethodDefinition *const overload) 108 { 109 overloads_.emplace_back(overload); 110 overload->SetBaseOverloadMethod(this); 111 } 112 SetBaseOverloadMethod(MethodDefinition *const baseOverloadMethod)113 void SetBaseOverloadMethod(MethodDefinition *const baseOverloadMethod) 114 { 115 baseOverloadMethod_ = baseOverloadMethod; 116 } 117 SetAsyncPairMethod(MethodDefinition *const method)118 void SetAsyncPairMethod(MethodDefinition *const method) 119 { 120 asyncPairMethod_ = method; 121 } 122 123 [[nodiscard]] bool HasOverload(MethodDefinition *overload) noexcept 124 { 125 return std::find(overloads_.begin(), overloads_.end(), overload) != overloads_.end(); 126 } 127 128 ScriptFunction *Function(); 129 const ScriptFunction *Function() const; 130 PrivateFieldKind ToPrivateFieldKind(bool isStatic) const override; 131 132 [[nodiscard]] MethodDefinition *Clone(ArenaAllocator *allocator, AstNode *parent) override; 133 134 void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; 135 void Iterate(const NodeTraverser &cb) const override; 136 137 void ResolveReferences(const NodeTraverser &cb) const; 138 139 void Dump(ir::AstDumper *dumper) const override; 140 void Dump(ir::SrcDumper *dumper) const override; 141 void Compile(compiler::PandaGen *pg) const override; 142 void Compile(compiler::ETSGen *etsg) const override; 143 checker::Type *Check(checker::TSChecker *checker) override; 144 checker::Type *Check(checker::ETSChecker *checker) override; 145 146 void Accept(ASTVisitorT *v) override 147 { 148 v->Accept(this); 149 } 150 151 private: 152 void DumpPrefix(ir::SrcDumper *dumper) const; 153 154 MethodDefinitionKind kind_; 155 // Overloads are stored like in an 1:N fashion. 156 // The very firstly processed method becomes the base(1) and the others tied into it as overloads(N). 157 OverloadsT overloads_; 158 // Base overload method points at the first overload of the overloads. 159 MethodDefinition *baseOverloadMethod_; 160 // Pair method points at the original async method in case of an implement method and vice versa an implement 161 // method's point at the async method 162 MethodDefinition *asyncPairMethod_; 163 }; 164 } // namespace ark::es2panda::ir 165 166 #endif 167