1 /** 2 * Copyright (c) 2021-2025 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 "scriptFunction.h" 20 #include "ir/base/classElement.h" 21 22 namespace ark::es2panda::checker { 23 class ETSAnalyzer; 24 } // namespace ark::es2panda::checker 25 26 namespace ark::es2panda::ir { 27 28 class Expression; 29 class ScriptFunction; 30 31 enum class MethodDefinitionKind { 32 NONE, 33 CONSTRUCTOR, 34 METHOD, 35 EXTENSION_METHOD, 36 GET, 37 SET, 38 EXTENSION_GET, 39 EXTENSION_SET, 40 }; 41 42 struct OverloadInfo { 43 uint32_t minArg = 0; 44 size_t maxArg = 0; 45 bool needHelperOverload = false; 46 bool isDeclare = false; 47 bool hasRestVar = false; 48 bool returnVoid = false; 49 }; 50 51 class MethodDefinition : public ClassElement { 52 public: 53 MethodDefinition() = delete; 54 ~MethodDefinition() override = default; 55 56 NO_COPY_SEMANTIC(MethodDefinition); 57 NO_MOVE_SEMANTIC(MethodDefinition); 58 59 using OverloadsT = ArenaVector<MethodDefinition *>; 60 // CC-OFFNXT(G.FUN.01-CPP) solid logic MethodDefinition(MethodDefinitionKind const kind,Expression * const key,Expression * const value,ModifierFlags const modifiers,ArenaAllocator * const allocator,bool const isComputed)61 explicit MethodDefinition(MethodDefinitionKind const kind, Expression *const key, Expression *const value, 62 ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed) 63 : ClassElement(AstNodeType::METHOD_DEFINITION, key, value, modifiers, allocator, isComputed), 64 kind_(kind), 65 overloads_(allocator->Adapter()), 66 baseOverloadMethod_(nullptr), 67 asyncPairMethod_(nullptr) 68 { 69 } 70 71 // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields 72 friend class checker::ETSAnalyzer; 73 Kind()74 MethodDefinitionKind Kind() const 75 { 76 return kind_; 77 } 78 IsConstructor()79 [[nodiscard]] bool IsConstructor() const noexcept 80 { 81 return kind_ == MethodDefinitionKind::CONSTRUCTOR; 82 } 83 IsMethod()84 [[nodiscard]] bool IsMethod() const noexcept 85 { 86 return kind_ == MethodDefinitionKind::METHOD; 87 } 88 IsExtensionMethod()89 [[nodiscard]] bool IsExtensionMethod() const noexcept 90 { 91 return (kind_ == MethodDefinitionKind::EXTENSION_METHOD) || (kind_ == MethodDefinitionKind::EXTENSION_GET) || 92 (kind_ == MethodDefinitionKind::EXTENSION_SET); 93 } 94 IsGetter()95 [[nodiscard]] bool IsGetter() const noexcept 96 { 97 return kind_ == MethodDefinitionKind::GET; 98 } 99 IsSetter()100 [[nodiscard]] bool IsSetter() const noexcept 101 { 102 return kind_ == MethodDefinitionKind::SET; 103 } 104 IsDefaultAccessModifier()105 [[nodiscard]] bool IsDefaultAccessModifier() const noexcept 106 { 107 return isDefault_; 108 } 109 SetDefaultAccessModifier(bool isDefault)110 void SetDefaultAccessModifier(bool isDefault) 111 { 112 isDefault_ = isDefault; 113 } 114 Overloads()115 [[nodiscard]] const OverloadsT &Overloads() const noexcept 116 { 117 return overloads_; 118 } 119 BaseOverloadMethod()120 [[nodiscard]] const MethodDefinition *BaseOverloadMethod() const noexcept 121 { 122 return baseOverloadMethod_; 123 } 124 BaseOverloadMethod()125 [[nodiscard]] MethodDefinition *BaseOverloadMethod() noexcept 126 { 127 return baseOverloadMethod_; 128 } 129 AsyncPairMethod()130 [[nodiscard]] const MethodDefinition *AsyncPairMethod() const noexcept 131 { 132 return asyncPairMethod_; 133 } 134 AsyncPairMethod()135 [[nodiscard]] MethodDefinition *AsyncPairMethod() noexcept 136 { 137 return asyncPairMethod_; 138 } 139 GetOverloadInfo()140 [[nodiscard]] OverloadInfo &GetOverloadInfo() noexcept 141 { 142 return overloadInfo_; 143 } 144 SetOverloads(OverloadsT && overloads)145 void SetOverloads(OverloadsT &&overloads) 146 { 147 overloads_ = std::move(overloads); 148 } 149 ClearOverloads()150 void ClearOverloads() 151 { 152 overloads_.clear(); 153 } 154 AddOverload(MethodDefinition * const overload)155 void AddOverload(MethodDefinition *const overload) 156 { 157 ES2PANDA_ASSERT(overload != nullptr && overload->Function() != nullptr); 158 overloads_.emplace_back(overload); 159 overload->Function()->AddFlag((ir::ScriptFunctionFlags::OVERLOAD)); 160 overload->SetBaseOverloadMethod(this); 161 } 162 SetBaseOverloadMethod(MethodDefinition * const baseOverloadMethod)163 void SetBaseOverloadMethod(MethodDefinition *const baseOverloadMethod) 164 { 165 baseOverloadMethod_ = baseOverloadMethod; 166 } 167 SetAsyncPairMethod(MethodDefinition * const method)168 void SetAsyncPairMethod(MethodDefinition *const method) 169 { 170 asyncPairMethod_ = method; 171 } 172 HasOverload(MethodDefinition * overload)173 [[nodiscard]] bool HasOverload(MethodDefinition *overload) noexcept 174 { 175 return std::find(overloads_.begin(), overloads_.end(), overload) != overloads_.end(); 176 } 177 178 ScriptFunction *Function(); 179 const ScriptFunction *Function() const; 180 void InitializeOverloadInfo(); 181 PrivateFieldKind ToPrivateFieldKind(bool isStatic) const override; 182 183 [[nodiscard]] MethodDefinition *Clone(ArenaAllocator *allocator, AstNode *parent) override; 184 185 void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; 186 void Iterate(const NodeTraverser &cb) const override; 187 188 void ResolveReferences(const NodeTraverser &cb) const; 189 190 void Dump(ir::AstDumper *dumper) const override; 191 void Dump(ir::SrcDumper *dumper) const override; 192 void Compile(compiler::PandaGen *pg) const override; 193 void Compile(compiler::ETSGen *etsg) const override; 194 checker::Type *Check(checker::TSChecker *checker) override; 195 checker::VerifiedType Check(checker::ETSChecker *checker) override; 196 Accept(ASTVisitorT * v)197 void Accept(ASTVisitorT *v) override 198 { 199 v->Accept(this); 200 } 201 202 void CleanUp() override; 203 204 protected: 205 MethodDefinition *Construct(ArenaAllocator *allocator) override; 206 void CopyTo(AstNode *other) const override; 207 208 private: 209 void DumpPrefix(ir::SrcDumper *dumper) const; 210 void ResetOverloads(); 211 void DumpModifierPrefix(ir::SrcDumper *dumper) const; 212 bool DumpNamespaceForDeclGen(ir::SrcDumper *dumper) const; 213 void DumpPrefixForDeclGen(ir::SrcDumper *dumper) const; 214 bool FilterForDeclGen(ir::SrcDumper *dumper) const; 215 216 friend class SizeOfNodeTest; 217 bool isDefault_ = false; 218 MethodDefinitionKind kind_; 219 // Overloads are stored like in an 1:N fashion. 220 // The very firstly processed method becomes the base(1) and the others tied into it as overloads(N). 221 OverloadsT overloads_; 222 // Base overload method points at the first overload of the overloads. 223 MethodDefinition *baseOverloadMethod_; 224 // Pair method points at the original async method in case of an implement method and vice versa an implement 225 // method's point at the async method 226 MethodDefinition *asyncPairMethod_; 227 OverloadInfo overloadInfo_; 228 }; 229 } // namespace ark::es2panda::ir 230 231 #endif 232