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#include "callExpression.h" 17 18#include "checker/TSchecker.h" 19#include "compiler/core/ETSGen.h" 20#include "compiler/core/pandagen.h" 21#include "ir/astDump.h" 22#include "ir/srcDump.h" 23 24namespace ark::es2panda::ir { 25void CallExpression::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) 26{ 27 if (auto *transformedNode = cb(callee_); callee_ != transformedNode) { 28 callee_->SetTransformedNode(transformationName, transformedNode); 29 callee_ = transformedNode->AsExpression(); 30 } 31 32 if (typeParams_ != nullptr) { 33 if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) { 34 typeParams_->SetTransformedNode(transformationName, transformedNode); 35 typeParams_ = transformedNode->AsTSTypeParameterInstantiation(); 36 } 37 } 38 39 for (auto *&it : arguments_) { 40 if (auto *transformedNode = cb(it); it != transformedNode) { 41 it->SetTransformedNode(transformationName, transformedNode); 42 it = transformedNode->AsExpression(); 43 } 44 } 45} 46 47void CallExpression::Iterate(const NodeTraverser &cb) const 48{ 49 cb(callee_); 50 51 if (typeParams_ != nullptr) { 52 cb(typeParams_); 53 } 54 55 for (auto *it : arguments_) { 56 cb(it); 57 } 58 59 if (trailingBlock_ != nullptr) { 60 cb(trailingBlock_); 61 } 62} 63 64void CallExpression::Dump(ir::AstDumper *dumper) const 65{ 66 dumper->Add({{"type", "CallExpression"}, 67 {"callee", callee_}, 68 {"arguments", arguments_}, 69 {"optional", IsOptional()}, 70 {"typeParameters", AstDumper::Optional(typeParams_)}}); 71} 72 73void CallExpression::Dump(ir::SrcDumper *dumper) const 74{ 75 ASSERT(callee_); 76 callee_->Dump(dumper); 77 if (IsOptional()) { 78 dumper->Add("?."); 79 } 80 81 if (typeParams_ != nullptr) { 82 typeParams_->Dump(dumper); 83 } 84 85 dumper->Add("("); 86 for (auto arg : arguments_) { 87 arg->Dump(dumper); 88 if (arg != arguments_.back()) { 89 dumper->Add(", "); 90 } 91 } 92 dumper->Add(")"); 93 if (trailingBlock_ != nullptr) { 94 if (isTrailingBlockInNewLine_) { 95 dumper->Endl(); 96 } 97 trailingBlock_->Dump(dumper); 98 } 99} 100 101void CallExpression::Compile(compiler::PandaGen *pg) const 102{ 103 pg->GetAstCompiler()->Compile(this); 104} 105 106void CallExpression::Compile(compiler::ETSGen *etsg) const 107{ 108 etsg->GetAstCompiler()->Compile(this); 109} 110 111checker::Type *CallExpression::Check(checker::TSChecker *checker) 112{ 113 return checker->GetAnalyzer()->Check(this); 114} 115 116bool CallExpression::IsETSConstructorCall() const 117{ 118 return callee_->IsThisExpression() || callee_->IsSuperExpression(); 119} 120 121checker::Type *CallExpression::Check(checker::ETSChecker *checker) 122{ 123 return checker->GetAnalyzer()->Check(this); 124} 125 126CallExpression::CallExpression(CallExpression const &other, ArenaAllocator *const allocator) 127 : MaybeOptionalExpression(static_cast<MaybeOptionalExpression const &>(other)), 128 arguments_(allocator->Adapter()), 129 signature_(other.signature_), 130 trailingComma_(other.trailingComma_), 131 isTrailingBlockInNewLine_(other.isTrailingBlockInNewLine_) 132{ 133 callee_ = other.callee_->Clone(allocator, this)->AsExpression(); 134 typeParams_ = other.typeParams_ != nullptr ? other.typeParams_->Clone(allocator, this) : nullptr; 135 136 for (auto *const argument : other.arguments_) { 137 arguments_.emplace_back(argument->Clone(allocator, this)->AsExpression()); 138 } 139 140 trailingBlock_ = 141 other.trailingBlock_ != nullptr ? other.trailingBlock_->Clone(allocator, this)->AsBlockStatement() : nullptr; 142} 143 144CallExpression *CallExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) 145{ 146 if (auto *const clone = allocator->New<CallExpression>(*this, allocator); clone != nullptr) { 147 if (parent != nullptr) { 148 clone->SetParent(parent); 149 } 150 151 clone->SetRange(Range()); 152 return clone; 153 } 154 155 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); 156} 157 158void CallExpression::SetTypeParams(TSTypeParameterInstantiation *typeParams) noexcept 159{ 160 typeParams_ = typeParams; 161 if (typeParams_ != nullptr) { 162 typeParams_->SetParent(this); 163 } 164} 165 166void CallExpression::SetTrailingBlock(ir::BlockStatement *const block) noexcept 167{ 168 trailingBlock_ = block; 169 if (trailingBlock_ != nullptr) { 170 trailingBlock_->SetParent(this); 171 } 172} 173} // namespace ark::es2panda::ir 174