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