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 *> &¶ms, 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