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_SCRIPT_FUNCTION_H
17 #define ES2PANDA_PARSER_INCLUDE_AST_SCRIPT_FUNCTION_H
18 
19 #include "ir/statements/returnStatement.h"
20 #include "checker/types/signature.h"
21 #include "ir/astNode.h"
22 #include "varbinder/scope.h"
23 #include "util/enumbitops.h"
24 #include "util/language.h"
25 #include "scriptFunctionSignature.h"
26 
27 namespace ark::es2panda::checker {
28 class Signature;
29 
30 }  // namespace ark::es2panda::checker
31 
32 namespace ark::es2panda::ir {
33 class TSTypeParameterDeclaration;
34 class TypeNode;
35 
36 class ScriptFunction : public AstNode {
37 public:
38     // Need to reduce the number of constructor parameters to pass OHOS CI code check
39     struct ScriptFunctionData {
40         AstNode *body = nullptr;
41         FunctionSignature &&signature;
42         ir::ScriptFunctionFlags funcFlags = ir::ScriptFunctionFlags::NONE;
43         ir::ModifierFlags flags = ir::ModifierFlags::NONE;
44         bool declare = false;
45         ark::es2panda::Language lang {Language::Id::ETS};
46     };
47 
48     ScriptFunction() = delete;
49     ~ScriptFunction() override = default;
50 
51     NO_COPY_SEMANTIC(ScriptFunction);
52     NO_MOVE_SEMANTIC(ScriptFunction);
53 
54     explicit ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data);
55 
56     [[nodiscard]] const Identifier *Id() const noexcept
57     {
58         return id_;
59     }
60 
61     [[nodiscard]] Identifier *Id() noexcept
62     {
63         return id_;
64     }
65 
66     [[nodiscard]] const checker::Signature *Signature() const noexcept
67     {
68         return signature_;
69     }
70 
71     [[nodiscard]] checker::Signature *Signature() noexcept
72     {
73         return signature_;
74     }
75 
76     [[nodiscard]] const ArenaVector<Expression *> &Params() const noexcept
77     {
78         return irSignature_.Params();
79     }
80 
81     [[nodiscard]] ArenaVector<Expression *> &Params() noexcept
82     {
83         return irSignature_.Params();
84     }
85 
86     size_t DefaultParamIndex() const noexcept
87     {
88         return this->irSignature_.DefaultParamIndex();
89     }
90 
ReturnStatements() const91     const ArenaVector<ReturnStatement *> &ReturnStatements() const
92     {
93         return returnStatements_;
94     }
95 
ReturnStatements()96     ArenaVector<ReturnStatement *> &ReturnStatements()
97     {
98         return returnStatements_;
99     }
100 
101     [[nodiscard]] const TSTypeParameterDeclaration *TypeParams() const noexcept
102     {
103         return irSignature_.TypeParams();
104     }
105 
106     [[nodiscard]] TSTypeParameterDeclaration *TypeParams() noexcept
107     {
108         return irSignature_.TypeParams();
109     }
110 
111     [[nodiscard]] const AstNode *Body() const noexcept
112     {
113         return body_;
114     }
115 
116     [[nodiscard]] AstNode *Body() noexcept
117     {
118         return body_;
119     }
120 
AddReturnStatement(ReturnStatement *returnStatement)121     void AddReturnStatement(ReturnStatement *returnStatement)
122     {
123         returnStatements_.push_back(returnStatement);
124     }
125 
126     void SetBody(AstNode *body) noexcept
127     {
128         body_ = body;
129     }
130 
131     [[nodiscard]] const TypeNode *ReturnTypeAnnotation() const noexcept
132     {
133         return irSignature_.ReturnType();
134     }
135 
136     [[nodiscard]] TypeNode *ReturnTypeAnnotation() noexcept
137     {
138         return irSignature_.ReturnType();
139     }
140 
141     void SetReturnTypeAnnotation(TypeNode *node) noexcept;
142 
143     [[nodiscard]] bool IsEntryPoint() const noexcept
144     {
145         return (funcFlags_ & ir::ScriptFunctionFlags::ENTRY_POINT) != 0;
146     }
147 
148     [[nodiscard]] bool IsGenerator() const noexcept
149     {
150         return (funcFlags_ & ir::ScriptFunctionFlags::GENERATOR) != 0;
151     }
152 
153     [[nodiscard]] bool IsAsyncFunc() const noexcept
154     {
155         return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC) != 0;
156     }
157 
158     [[nodiscard]] bool IsAsyncImplFunc() const noexcept
159     {
160         return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC_IMPL) != 0;
161     }
162 
163     [[nodiscard]] bool IsArrow() const noexcept
164     {
165         return (funcFlags_ & ir::ScriptFunctionFlags::ARROW) != 0;
166     }
167 
168     [[nodiscard]] bool IsOverload() const noexcept
169     {
170         return (funcFlags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0;
171     }
172 
IsExternalOverload() const173     [[nodiscard]] bool IsExternalOverload() const
174     {
175         return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD) != 0;
176     }
177 
178     [[nodiscard]] bool IsConstructor() const noexcept
179     {
180         return (funcFlags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0;
181     }
182 
183     [[nodiscard]] bool IsGetter() const noexcept
184     {
185         return (funcFlags_ & ir::ScriptFunctionFlags::GETTER) != 0;
186     }
187 
188     [[nodiscard]] bool IsSetter() const noexcept
189     {
190         return (funcFlags_ & ir::ScriptFunctionFlags::SETTER) != 0;
191     }
192 
193     [[nodiscard]] bool IsMethod() const noexcept
194     {
195         return (funcFlags_ & ir::ScriptFunctionFlags::METHOD) != 0;
196     }
197 
198     [[nodiscard]] bool IsProxy() const noexcept
199     {
200         return (funcFlags_ & ir::ScriptFunctionFlags::PROXY) != 0;
201     }
202 
203     [[nodiscard]] bool IsStaticBlock() const noexcept
204     {
205         return (funcFlags_ & ir::ScriptFunctionFlags::STATIC_BLOCK) != 0;
206     }
207 
208     [[nodiscard]] bool IsEnum() const noexcept
209     {
210         return (funcFlags_ & ir::ScriptFunctionFlags::ENUM) != 0;
211     }
212 
213     [[nodiscard]] bool IsHidden() const noexcept
214     {
215         return (funcFlags_ & ir::ScriptFunctionFlags::HIDDEN) != 0;
216     }
217 
218     [[nodiscard]] bool IsExternal() const noexcept
219     {
220         return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL) != 0;
221     }
222 
223     [[nodiscard]] bool IsImplicitSuperCallNeeded() const noexcept
224     {
225         return (funcFlags_ & ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED) != 0;
226     }
227 
228     [[nodiscard]] bool HasBody() const noexcept
229     {
230         return body_ != nullptr;
231     }
232 
233     [[nodiscard]] bool HasRestParameter() const noexcept
234     {
235         return signature_->RestVar() != nullptr;
236     }
237 
238     [[nodiscard]] bool HasReturnStatement() const noexcept
239     {
240         return (funcFlags_ & ir::ScriptFunctionFlags::HAS_RETURN) != 0;
241     }
242 
243     [[nodiscard]] bool IsThrowing() const noexcept
244     {
245         return (funcFlags_ & ir::ScriptFunctionFlags::THROWS) != 0;
246     }
247 
248     [[nodiscard]] bool IsRethrowing() const noexcept
249     {
250         return (funcFlags_ & ir::ScriptFunctionFlags::RETHROWS) != 0;
251     }
252 
253     [[nodiscard]] bool IsDynamic() const noexcept
254     {
255         return lang_.IsDynamic();
256     }
257 
258     [[nodiscard]] bool IsExtensionMethod() const noexcept
259     {
260         return (funcFlags_ & ir::ScriptFunctionFlags::INSTANCE_EXTENSION_METHOD) != 0;
261     }
262 
263     [[nodiscard]] bool Declare() const noexcept
264     {
265         return declare_;
266     }
267 
268     [[nodiscard]] ir::ScriptFunctionFlags Flags() const noexcept
269     {
270         return funcFlags_;
271     }
272 
273     void SetIdent(Identifier *id) noexcept;
274 
275     void SetSignature(checker::Signature *signature) noexcept
276     {
277         signature_ = signature;
278     }
279 
280     void AddFlag(ir::ScriptFunctionFlags flags) noexcept
281     {
282         funcFlags_ |= flags;
283     }
284 
285     void AddModifier(ir::ModifierFlags flags) noexcept
286     {
287         flags_ |= flags;
288     }
289 
290     [[nodiscard]] std::size_t FormalParamsLength() const noexcept;
291 
292     [[nodiscard]] bool IsScopeBearer() const noexcept override
293     {
294         return true;
295     }
296 
297     [[nodiscard]] varbinder::FunctionScope *Scope() const noexcept override
298     {
299         return scope_;
300     }
301 
302     void SetScope(varbinder::FunctionScope *scope) noexcept
303     {
304         scope_ = scope;
305     }
306 
307     void ClearScope() noexcept override
308     {
309         scope_ = nullptr;
310     }
311 
312     [[nodiscard]] es2panda::Language Language() const noexcept
313     {
314         return lang_;
315     }
316 
317     [[nodiscard]] ScriptFunction *Clone(ArenaAllocator *allocator, AstNode *parent) override;
318 
319     void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
320     void Iterate(const NodeTraverser &cb) const override;
321 
322     void Dump(ir::AstDumper *dumper) const override;
323     void Dump(ir::SrcDumper *dumper) const override;
324     void Compile(compiler::PandaGen *pg) const override;
325     void Compile(compiler::ETSGen *etsg) const override;
326     checker::Type *Check(checker::TSChecker *checker) override;
327     checker::Type *Check(checker::ETSChecker *checker) override;
328 
329     void Accept(ASTVisitorT *v) override
330     {
331         v->Accept(this);
332     }
333 
334 private:
335     Identifier *id_ {};
336     FunctionSignature irSignature_;
337     AstNode *body_;
338     varbinder::FunctionScope *scope_ {nullptr};
339     ir::ScriptFunctionFlags funcFlags_;
340     checker::Signature *signature_ {};
341     bool declare_;
342     es2panda::Language lang_;
343     ArenaVector<ReturnStatement *> returnStatements_;
344 };
345 }  // namespace ark::es2panda::ir
346 
347 #endif
348