• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021 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/astNode.h>
20 #include <ir/expressions/identifier.h>
21 #include <util/enumbitops.h>
22 
23 namespace panda::es2panda::compiler {
24 class PandaGen;
25 }  // namespace panda::es2panda::compiler
26 
27 namespace panda::es2panda::checker {
28 class Checker;
29 class Type;
30 }  // namespace panda::es2panda::checker
31 
32 namespace panda::es2panda::binder {
33 class FunctionScope;
34 }  // namespace panda::es2panda::binder
35 
36 namespace panda::es2panda::ir {
37 
38 class TSTypeParameterDeclaration;
39 
40 class ScriptFunction : public AstNode {
41 public:
ScriptFunction(binder::FunctionScope * scope,ArenaVector<Expression * > && params,TSTypeParameterDeclaration * typeParams,AstNode * body,Expression * returnTypeAnnotation,ir::ScriptFunctionFlags flags,bool declare,bool isTsFunction)42     explicit ScriptFunction(binder::FunctionScope *scope, ArenaVector<Expression *> &&params,
43                             TSTypeParameterDeclaration *typeParams, AstNode *body, Expression *returnTypeAnnotation,
44                             ir::ScriptFunctionFlags flags, bool declare, bool isTsFunction)
45         : AstNode(AstNodeType::SCRIPT_FUNCTION),
46           scope_(scope),
47           id_(nullptr),
48           params_(std::move(params)),
49           typeParams_(typeParams),
50           body_(body),
51           returnTypeAnnotation_(returnTypeAnnotation),
52           flags_(flags),
53           declare_(declare),
54           exportDefault_(false)
55     {
56         thisParam_ = nullptr;
57         if (isTsFunction && !params_.empty()) {
58             auto *firstParam = params_.front();
59             if (firstParam->IsIdentifier() && firstParam->AsIdentifier()->Name().Is(THIS_PARAM)) {
60                 thisParam_ = firstParam;
61                 params_.erase(params_.begin());
62                 scope_->ParamScope()->RemoveThisParam(THIS_PARAM);
63                 scope_->Bindings().erase(THIS_PARAM);
64             }
65         }
66     }
67 
Id()68     const Identifier *Id() const
69     {
70         return id_;
71     }
72 
Id()73     Identifier *Id()
74     {
75         return id_;
76     }
77 
Params()78     const ArenaVector<Expression *> &Params() const
79     {
80         return params_;
81     }
82 
Params()83     ArenaVector<Expression *> &Params()
84     {
85         return params_;
86     }
87 
TypeParams()88     const TSTypeParameterDeclaration *TypeParams() const
89     {
90         return typeParams_;
91     }
92 
TypeParams()93     TSTypeParameterDeclaration *TypeParams()
94     {
95         return typeParams_;
96     }
97 
ThisParams()98     const Expression *ThisParams() const
99     {
100         return thisParam_;
101     }
102 
ThisParams()103     Expression *ThisParams()
104     {
105         return thisParam_;
106     }
107 
Body()108     const AstNode *Body() const
109     {
110         return body_;
111     }
112 
Body()113     AstNode *Body()
114     {
115         return body_;
116     }
117 
ReturnTypeAnnotation()118     const Expression *ReturnTypeAnnotation() const
119     {
120         return returnTypeAnnotation_;
121     }
122 
ReturnTypeAnnotation()123     Expression *ReturnTypeAnnotation()
124     {
125         return returnTypeAnnotation_;
126     }
127 
IsGenerator()128     bool IsGenerator() const
129     {
130         return (flags_ & ir::ScriptFunctionFlags::GENERATOR) != 0;
131     }
132 
IsAsync()133     bool IsAsync() const
134     {
135         return (flags_ & ir::ScriptFunctionFlags::ASYNC) != 0;
136     }
137 
IsArrow()138     bool IsArrow() const
139     {
140         return (flags_ & ir::ScriptFunctionFlags::ARROW) != 0;
141     }
142 
IsOverload()143     bool IsOverload() const
144     {
145         return (flags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0;
146     }
147 
IsConstructor()148     bool IsConstructor() const
149     {
150         return (flags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0 ||
151                (flags_ & ir::ScriptFunctionFlags::GENERATED_CONSTRUCTOR) != 0;
152     }
153 
IsStaticInitializer()154     bool IsStaticInitializer() const
155     {
156         return (flags_ & ir::ScriptFunctionFlags::STATIC_INITIALIZER) != 0;
157     }
158 
IsInstanceInitializer()159     bool IsInstanceInitializer() const
160     {
161         return (flags_ & ir::ScriptFunctionFlags::INSTANCE_INITIALIZER) != 0;
162     }
163 
IsMethod()164     bool IsMethod() const
165     {
166         return (flags_ & ir::ScriptFunctionFlags::METHOD) != 0 || IsInstanceInitializer() || IsStaticInitializer();
167     }
168 
FunctionBodyIsExpression()169     bool FunctionBodyIsExpression() const
170     {
171         return (flags_ & ir::ScriptFunctionFlags::EXPRESSION) != 0;
172     }
173 
Declare()174     bool Declare() const
175     {
176         return declare_;
177     }
178 
SetIdent(Identifier * id)179     void SetIdent(Identifier *id)
180     {
181         id_ = id;
182     }
183 
SetAsExportDefault()184     void SetAsExportDefault()
185     {
186         exportDefault_ = true;
187     }
188 
AddFlag(ir::ScriptFunctionFlags flags)189     void AddFlag(ir::ScriptFunctionFlags flags)
190     {
191         flags_ |= flags;
192     }
193 
HasFlag(ir::ScriptFunctionFlags flag)194     bool HasFlag(ir::ScriptFunctionFlags flag) const
195     {
196         return (flags_ & flag) != 0;
197     }
198 
SetInSendable()199     void SetInSendable()
200     {
201         inSendable_ = true;
202     }
203 
IncreasePropertyCount()204     void IncreasePropertyCount()
205     {
206         expectedPropertyCount_++;
207     }
208 
ExpectedPropertyCount()209     size_t ExpectedPropertyCount() const
210     {
211         return expectedPropertyCount_;
212     }
213 
214     size_t FormalParamsLength() const;
215     util::StringView GetName() const;
216 
Scope()217     binder::FunctionScope *Scope() const
218     {
219         return scope_;
220     }
221 
IsConcurrent()222     bool IsConcurrent() const
223     {
224         return (flags_ & ir::ScriptFunctionFlags::CONCURRENT) != 0;
225     }
226 
IsSendable()227     bool IsSendable() const
228     {
229         return (flags_ & ir::ScriptFunctionFlags::SENDABLE) != 0;
230     }
231 
CanBeConcurrent()232     bool CanBeConcurrent() const
233     {
234         return !(IsGenerator() || IsArrow());
235     }
236 
AddConcurrentModuleRequest(int moduleRequestId)237     void AddConcurrentModuleRequest(int moduleRequestId)
238     {
239         if (!IsConcurrent()) {
240             return;
241         }
242 
243         concurrentModuleRequests_.emplace_back(moduleRequestId);
244     }
245 
GetConcurrentModuleRequests()246     std::vector<int> GetConcurrentModuleRequests() const
247     {
248         return concurrentModuleRequests_;
249     }
250 
InSendable()251     bool InSendable() const
252     {
253         return inSendable_;
254     }
255 
256     void CalculateFunctionExpectedPropertyCount();
257     void ExtractThisPropertyFromStatement(const ir::Statement *stmt,
258                           const std::function<void(const util::StringView&)>& addPropertyName);
259 
260     void Iterate(const NodeTraverser &cb) const override;
261     void Dump(ir::AstDumper *dumper) const override;
262     void Compile([[maybe_unused]] compiler::PandaGen *pg) const override;
263     checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override;
264     void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override;
265     util::StringView SourceCode(binder::Binder *binder) const;
266 
267 private:
268     static constexpr std::string_view THIS_PARAM = "this";
269 
270     binder::FunctionScope *scope_;
271     Identifier *id_;
272     Expression *thisParam_;
273     ArenaVector<Expression *> params_;
274     TSTypeParameterDeclaration *typeParams_;
275     AstNode *body_;
276     Expression *returnTypeAnnotation_;
277     ir::ScriptFunctionFlags flags_;
278     bool declare_;
279     bool exportDefault_;
280     std::vector<int> concurrentModuleRequests_;
281     bool inSendable_ {false};
282     size_t expectedPropertyCount_ {0};
283 };
284 
285 }  // namespace panda::es2panda::ir
286 
287 #endif
288