File indexing completed on 2024-05-26 04:42:27
0001 /* 0002 SPDX-FileCopyrightText: 2015 Sergey Kalinichev <kalinichev.so.0@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "classspecializationtype.h" 0008 0009 using namespace KDevelop; 0010 0011 #include <language/duchain/appendedlist.h> 0012 #include <serialization/indexedstring.h> 0013 0014 // The type is registered in DUChainUtils::registerDUChainItems 0015 // REGISTER_TYPE(ClassSpecializationType); 0016 0017 DEFINE_LIST_MEMBER_HASH(ClassSpecializationTypeData, parameters, IndexedType) 0018 0019 ClassSpecializationTypeData::ClassSpecializationTypeData() 0020 { 0021 initializeAppendedLists(m_dynamic); 0022 } 0023 0024 ClassSpecializationTypeData::ClassSpecializationTypeData(const ClassSpecializationTypeData& rhs) 0025 : KDevelop::StructureTypeData(rhs) 0026 { 0027 initializeAppendedLists(m_dynamic); 0028 copyListsFrom(rhs); 0029 } 0030 0031 ClassSpecializationTypeData::~ClassSpecializationTypeData() 0032 { 0033 freeAppendedLists(); 0034 } 0035 0036 ClassSpecializationType::ClassSpecializationType(const ClassSpecializationType& rhs) 0037 : KDevelop::StructureType(copyData<ClassSpecializationType>(*rhs.d_func())) 0038 {} 0039 0040 ClassSpecializationType::ClassSpecializationType(ClassSpecializationTypeData& data) 0041 : KDevelop::StructureType(data) 0042 {} 0043 0044 AbstractType* ClassSpecializationType::clone() const 0045 { 0046 return new ClassSpecializationType(*this); 0047 } 0048 0049 ClassSpecializationType::ClassSpecializationType() 0050 : KDevelop::StructureType(createData<ClassSpecializationType>()) 0051 {} 0052 0053 uint ClassSpecializationType::hash() const 0054 { 0055 KDevHash kdevhash(StructureType::hash()); 0056 0057 FOREACH_FUNCTION(const auto& param, d_func()->parameters) { 0058 kdevhash << param.hash(); 0059 } 0060 return kdevhash; 0061 } 0062 0063 namespace { 0064 // we need to skip the template parameters of the last identifier, 0065 // so do the stringification manually here 0066 QString strippedQid(const QualifiedIdentifier& qid) 0067 { 0068 QString result; 0069 if (qid.explicitlyGlobal()) { 0070 result += QLatin1String("::"); 0071 } 0072 const auto parts = qid.count(); 0073 for (int i = 0; i < parts - 1; ++i) { 0074 result += qid.at(i).toString() + QLatin1String("::"); 0075 } 0076 const auto last = qid.at(parts - 1); 0077 result += last.identifier().str(); 0078 return result; 0079 } 0080 } 0081 0082 QString ClassSpecializationType::toString() const 0083 { 0084 QualifiedIdentifier id = qualifiedIdentifier(); 0085 if (!id.isEmpty()) { 0086 QString result = AbstractType::toString() + strippedQid(id) + QLatin1String("< "); 0087 bool first = true; 0088 const auto& templateParameters = this->templateParameters(); 0089 for (const auto& param : templateParameters) { 0090 if (first) { 0091 first = false; 0092 } else { 0093 result += QLatin1String(", "); 0094 } 0095 result += param.abstractType()->toString(); 0096 } 0097 result += QLatin1String(" >"); 0098 return result; 0099 } 0100 0101 return StructureType::toString(); 0102 } 0103 0104 bool ClassSpecializationType::equals(const KDevelop::AbstractType* rhs) const 0105 { 0106 if (this == rhs) { 0107 return true; 0108 } 0109 0110 auto tt = dynamic_cast<const ClassSpecializationType*>(rhs); 0111 if (!tt || templateParameters() != tt->templateParameters()) { 0112 return false; 0113 } 0114 0115 return StructureType::equals(rhs); 0116 } 0117 0118 QVector<KDevelop::IndexedType> ClassSpecializationType::templateParameters() const 0119 { 0120 const auto size = d_func()->parametersSize(); 0121 QVector<IndexedType> parameters(size); 0122 std::copy_n(d_func()->parameters(), size, parameters.begin()); 0123 0124 return parameters; 0125 } 0126 0127 void ClassSpecializationType::addParameter(const KDevelop::IndexedType& param) 0128 { 0129 d_func_dynamic()->parametersList().append(param); 0130 } 0131 0132 void ClassSpecializationType::clearParameters() 0133 { 0134 d_func_dynamic()->parametersList().clear(); 0135 }