File indexing completed on 2024-06-16 04:23:16
0001 /* 0002 SPDX-FileCopyrightText: 2006 Roberto Raggi <roberto@kdevelop.org> 0003 SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org> 0004 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #include "functiontype.h" 0010 0011 #include "typeregister.h" 0012 #include "typesystem.h" 0013 0014 namespace KDevelop { 0015 REGISTER_TYPE(FunctionType); 0016 0017 DEFINE_LIST_MEMBER_HASH(FunctionTypeData, m_arguments, IndexedType) 0018 0019 FunctionType::FunctionType(const FunctionType& rhs) : AbstractType(copyData<FunctionType>(*rhs.d_func())) 0020 { 0021 } 0022 0023 FunctionType::FunctionType(FunctionTypeData& data) : AbstractType(data) 0024 { 0025 } 0026 0027 AbstractType* FunctionType::clone() const 0028 { 0029 return new FunctionType(*this); 0030 } 0031 0032 bool FunctionType::equals(const AbstractType* _rhs) const 0033 { 0034 if (this == _rhs) 0035 return true; 0036 0037 if (!AbstractType::equals(_rhs)) 0038 return false; 0039 0040 Q_ASSERT(dynamic_cast<const FunctionType*>(_rhs)); 0041 const auto* rhs = static_cast<const FunctionType*>(_rhs); 0042 0043 TYPE_D(FunctionType); 0044 if (d->m_argumentsSize() != rhs->d_func()->m_argumentsSize()) 0045 return false; 0046 0047 if (( bool )rhs->d_func()->m_returnType != ( bool )d->m_returnType) 0048 return false; 0049 0050 if (d->m_returnType != rhs->d_func()->m_returnType) 0051 return false; 0052 0053 for (unsigned int a = 0; a < d->m_argumentsSize(); ++a) 0054 if (d->m_arguments()[a] != rhs->d_func()->m_arguments()[a]) 0055 return false; 0056 0057 return true; 0058 } 0059 0060 FunctionType::FunctionType() 0061 : AbstractType(createData<FunctionType>()) 0062 { 0063 } 0064 0065 FunctionType::~FunctionType() 0066 { 0067 } 0068 0069 void FunctionType::addArgument(const AbstractType::Ptr& argument, int index) 0070 { 0071 if (index == -1) 0072 d_func_dynamic()->m_argumentsList().append(IndexedType(argument)); 0073 else 0074 d_func_dynamic()->m_argumentsList().insert(index, IndexedType(argument)); 0075 } 0076 0077 void FunctionType::removeArgument(int i) 0078 { 0079 d_func_dynamic()->m_argumentsList().remove(i); 0080 } 0081 0082 void FunctionType::setReturnType(const AbstractType::Ptr& returnType) 0083 { 0084 d_func_dynamic()->m_returnType = IndexedType(returnType); 0085 } 0086 0087 AbstractType::Ptr FunctionType::returnType() const 0088 { 0089 return d_func()->m_returnType.abstractType(); 0090 } 0091 0092 QList<AbstractType::Ptr> FunctionType::arguments() const 0093 { 0094 ///@todo Don't do the conversion 0095 QList<AbstractType::Ptr> ret; 0096 ret.reserve(d_func()->m_argumentsSize()); 0097 FOREACH_FUNCTION(const IndexedType &arg, d_func()->m_arguments) 0098 ret << arg.abstractType(); 0099 return ret; 0100 } 0101 0102 const IndexedType* FunctionType::indexedArguments() const 0103 { 0104 return d_func()->m_arguments(); 0105 } 0106 0107 uint FunctionType::indexedArgumentsSize() const 0108 { 0109 return d_func()->m_argumentsSize(); 0110 } 0111 0112 void FunctionType::accept0(TypeVisitor* v) const 0113 { 0114 TYPE_D(FunctionType); 0115 if (v->visit(this)) { 0116 acceptType(d->m_returnType.abstractType(), v); 0117 0118 for (unsigned int i = 0; i < d->m_argumentsSize(); ++i) 0119 acceptType(d->m_arguments()[i].abstractType(), v); 0120 } 0121 0122 v->endVisit(this); 0123 } 0124 0125 void FunctionType::exchangeTypes(TypeExchanger* exchanger) 0126 { 0127 TYPE_D_DYNAMIC(FunctionType); 0128 for (uint i = 0; i < d->m_argumentsSize(); ++i) 0129 d->m_argumentsList()[i] = IndexedType(exchanger->exchange(d->m_arguments()[i].abstractType())); 0130 0131 d->m_returnType = IndexedType(exchanger->exchange(d->m_returnType.abstractType())); 0132 } 0133 0134 QString FunctionType::partToString(SignaturePart sigPart) const 0135 { 0136 QString args; 0137 TYPE_D(FunctionType); 0138 if (sigPart == SignatureArguments || sigPart == SignatureWhole) { 0139 QStringList types; 0140 types.reserve(d->m_argumentsSize()); 0141 FOREACH_FUNCTION(const IndexedType &type, d->m_arguments) { 0142 types.append(type ? type.abstractType()->toString() : QStringLiteral("<notype>")); 0143 } 0144 args += QLatin1Char('(') + types.join(QLatin1String(", ")) + QLatin1Char(')'); 0145 } 0146 0147 if (sigPart == SignatureArguments) 0148 return args; 0149 else if (sigPart == SignatureWhole) 0150 return QStringLiteral("function %1 %2").arg(returnType() ? returnType()->toString() : QStringLiteral( 0151 "<notype>"), args); 0152 else if (sigPart == SignatureReturn) 0153 return returnType() ? returnType()->toString() : QString(); 0154 0155 return QStringLiteral("ERROR"); 0156 } 0157 0158 QString FunctionType::toString() const 0159 { 0160 return partToString(SignatureWhole) + AbstractType::toString(true); 0161 } 0162 0163 AbstractType::WhichType FunctionType::whichType() const 0164 { 0165 return TypeFunction; 0166 } 0167 0168 uint FunctionType::hash() const 0169 { 0170 KDevHash kdevhash(AbstractType::hash()); 0171 kdevhash << d_func()->m_returnType.hash(); 0172 0173 FOREACH_FUNCTION(const IndexedType &t, d_func()->m_arguments) { 0174 kdevhash << t.hash(); 0175 } 0176 0177 return kdevhash; 0178 } 0179 }