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 }