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