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#include "tsSignatureDeclaration.h" 17 18#include <binder/binder.h> 19#include <binder/scope.h> 20#include <ir/astDump.h> 21#include <ir/typeNode.h> 22#include <ir/ts/tsTypeParameter.h> 23#include <ir/ts/tsTypeParameterDeclaration.h> 24#include <typescript/checker.h> 25 26namespace panda::es2panda::ir { 27 28void TSSignatureDeclaration::Iterate(const NodeTraverser &cb) const 29{ 30 if (typeParams_) { 31 cb(typeParams_); 32 } 33 34 for (auto *it : params_) { 35 cb(it); 36 } 37 38 if (returnTypeAnnotation_) { 39 cb(returnTypeAnnotation_); 40 } 41} 42 43void TSSignatureDeclaration::Dump(ir::AstDumper *dumper) const 44{ 45 dumper->Add({{"type", (kind_ == TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE) 46 ? "TSCallSignatureDeclaration" 47 : "TSConstructSignatureDeclaration"}, 48 {"params", params_}, 49 {"typeParameters", AstDumper::Optional(typeParams_)}, 50 {"returnType", AstDumper::Optional(returnTypeAnnotation_)}}); 51} 52 53void TSSignatureDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} 54 55checker::Type *TSSignatureDeclaration::Check(checker::Checker *checker) const 56{ 57 auto found = checker->NodeCache().find(this); 58 if (found != checker->NodeCache().end()) { 59 return found->second; 60 } 61 62 checker::ScopeContext scopeCtx(checker, scope_); 63 64 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator()); 65 checker->CheckFunctionParameterDeclarations(params_, signatureInfo); 66 67 bool isCallSignature = (Kind() == ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE); 68 69 if (!returnTypeAnnotation_) { 70 if (isCallSignature) { 71 checker->ThrowTypeError( 72 "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.", Start()); 73 } 74 75 checker->ThrowTypeError( 76 "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.", Start()); 77 } 78 79 returnTypeAnnotation_->Check(checker); 80 checker::Type *returnType = returnTypeAnnotation_->AsTypeNode()->GetType(checker); 81 82 auto *signature = checker->Allocator()->New<checker::Signature>(signatureInfo, returnType); 83 84 checker::Type *placeholderObj = nullptr; 85 86 if (isCallSignature) { 87 placeholderObj = checker->CreateObjectTypeWithCallSignature(signature); 88 } else { 89 placeholderObj = checker->CreateObjectTypeWithConstructSignature(signature); 90 } 91 92 checker->NodeCache().insert({this, placeholderObj}); 93 94 return placeholderObj; 95} 96 97void TSSignatureDeclaration::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) 98{ 99 auto scopeCtx = binder::LexicalScope<binder::Scope>::Enter(binder, scope_); 100 101 if (typeParams_) { 102 typeParams_ = std::get<ir::AstNode *>(cb(typeParams_))->AsTSTypeParameterDeclaration(); 103 } 104 105 for (auto iter = params_.begin(); iter != params_.end(); iter++) { 106 *iter = std::get<ir::AstNode *>(cb(*iter))->AsExpression(); 107 } 108 109 if (returnTypeAnnotation_) { 110 returnTypeAnnotation_ = std::get<ir::AstNode *>(cb(returnTypeAnnotation_))->AsExpression(); 111 } 112} 113 114} // namespace panda::es2panda::ir 115