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 23namespace panda::es2panda::compiler { 24class PandaGen; 25} // namespace panda::es2panda::compiler 26 27namespace panda::es2panda::checker { 28class Checker; 29class Type; 30} // namespace panda::es2panda::checker 31 32namespace panda::es2panda::binder { 33class FunctionScope; 34} // namespace panda::es2panda::binder 35 36namespace panda::es2panda::ir { 37 38class TSTypeParameterDeclaration; 39 40class ScriptFunction : public AstNode { 41public: 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 68 const Identifier *Id() const 69 { 70 return id_; 71 } 72 73 Identifier *Id() 74 { 75 return id_; 76 } 77 78 const ArenaVector<Expression *> &Params() const 79 { 80 return params_; 81 } 82 83 ArenaVector<Expression *> &Params() 84 { 85 return params_; 86 } 87 88 const TSTypeParameterDeclaration *TypeParams() const 89 { 90 return typeParams_; 91 } 92 93 TSTypeParameterDeclaration *TypeParams() 94 { 95 return typeParams_; 96 } 97 98 const Expression *ThisParams() const 99 { 100 return thisParam_; 101 } 102 103 Expression *ThisParams() 104 { 105 return thisParam_; 106 } 107 108 const AstNode *Body() const 109 { 110 return body_; 111 } 112 113 AstNode *Body() 114 { 115 return body_; 116 } 117 118 const Expression *ReturnTypeAnnotation() const 119 { 120 return returnTypeAnnotation_; 121 } 122 123 Expression *ReturnTypeAnnotation() 124 { 125 return returnTypeAnnotation_; 126 } 127 128 bool IsGenerator() const 129 { 130 return (flags_ & ir::ScriptFunctionFlags::GENERATOR) != 0; 131 } 132 133 bool IsAsync() const 134 { 135 return (flags_ & ir::ScriptFunctionFlags::ASYNC) != 0; 136 } 137 138 bool IsArrow() const 139 { 140 return (flags_ & ir::ScriptFunctionFlags::ARROW) != 0; 141 } 142 143 bool IsOverload() const 144 { 145 return (flags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0; 146 } 147 148 bool IsConstructor() const 149 { 150 return (flags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0; 151 } 152 153 bool IsStaticInitializer() const 154 { 155 return (flags_ & ir::ScriptFunctionFlags::STATIC_INITIALIZER) != 0; 156 } 157 158 bool IsInstanceInitializer() const 159 { 160 return (flags_ & ir::ScriptFunctionFlags::INSTANCE_INITIALIZER) != 0; 161 } 162 163 bool IsMethod() const 164 { 165 return (flags_ & ir::ScriptFunctionFlags::METHOD) != 0 || IsInstanceInitializer() || IsStaticInitializer(); 166 } 167 168 bool FunctionBodyIsExpression() const 169 { 170 return (flags_ & ir::ScriptFunctionFlags::EXPRESSION) != 0; 171 } 172 173 bool Declare() const 174 { 175 return declare_; 176 } 177 178 void SetIdent(Identifier *id) 179 { 180 id_ = id; 181 } 182 183 void SetAsExportDefault() 184 { 185 exportDefault_ = true; 186 } 187 188 void AddFlag(ir::ScriptFunctionFlags flags) 189 { 190 flags_ |= flags; 191 } 192 193 bool HasFlag(ir::ScriptFunctionFlags flag) const 194 { 195 return (flags_ & flag) != 0; 196 } 197 198 void SetInSendable() 199 { 200 inSendable_ = true; 201 } 202 203 size_t FormalParamsLength() const; 204 util::StringView GetName() const; 205 206 binder::FunctionScope *Scope() const 207 { 208 return scope_; 209 } 210 211 bool IsConcurrent() const 212 { 213 return (flags_ & ir::ScriptFunctionFlags::CONCURRENT) != 0; 214 } 215 216 bool IsSendable() const 217 { 218 return (flags_ & ir::ScriptFunctionFlags::SENDABLE) != 0; 219 } 220 221 bool CanBeConcurrent() const 222 { 223 return !(IsGenerator() || IsArrow()); 224 } 225 226 void AddConcurrentModuleRequest(int moduleRequestId) 227 { 228 if (!IsConcurrent()) { 229 return; 230 } 231 232 concurrentModuleRequests_.emplace_back(moduleRequestId); 233 } 234 235 std::vector<int> GetConcurrentModuleRequests() const 236 { 237 return concurrentModuleRequests_; 238 } 239 240 bool InSendable() const 241 { 242 return inSendable_; 243 } 244 245 void Iterate(const NodeTraverser &cb) const override; 246 void Dump(ir::AstDumper *dumper) const override; 247 void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; 248 checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; 249 void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override; 250 util::StringView SourceCode(binder::Binder *binder) const; 251 252private: 253 static constexpr std::string_view THIS_PARAM = "this"; 254 255 binder::FunctionScope *scope_; 256 Identifier *id_; 257 Expression *thisParam_; 258 ArenaVector<Expression *> params_; 259 TSTypeParameterDeclaration *typeParams_; 260 AstNode *body_; 261 Expression *returnTypeAnnotation_; 262 ir::ScriptFunctionFlags flags_; 263 bool declare_; 264 bool exportDefault_; 265 std::vector<int> concurrentModuleRequests_; 266 bool inSendable_ {false}; 267}; 268 269} // namespace panda::es2panda::ir 270 271#endif 272