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