1 /* 2 SPDX-FileCopyrightText: 2002-2005 Roberto Raggi <roberto@kdevelop.org> 3 SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org> 4 SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org> 5 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 6 7 SPDX-License-Identifier: LGPL-2.0-only 8 */ 9 10 #ifndef KDEVPLATFORM_IDENTIFIEDTYPE_H 11 #define KDEVPLATFORM_IDENTIFIEDTYPE_H 12 13 #include "../identifier.h" 14 #include "../declarationid.h" 15 16 namespace KDevelop { 17 class DUContext; 18 class Declaration; 19 class DeclarationId; 20 class TopDUContext; 21 class AbstractType; 22 23 /** 24 * Data structure for identified types. 25 */ 26 class IdentifiedTypeData 27 { 28 public: 29 DeclarationId m_id; 30 }; 31 32 /** 33 * \short An IdentifiedType is a type that has a declaration. 34 * 35 * Example of an identified type: 36 * - A class type 37 * 38 * Example of types which are not identified: 39 * - Pointer types (they can point to identified types, but by themselves have no declaration) 40 * - Reference types (the same) 41 * */ 42 class KDEVPLATFORMLANGUAGE_EXPORT IdentifiedType 43 { 44 public: 45 /// Destructor 46 virtual ~IdentifiedType(); 47 48 /** 49 * Test for equivalence with another type. 50 * 51 * \param rhs other type to check for equivalence 52 * \returns true if equal, otherwise false. 53 */ 54 bool equals(const IdentifiedType* rhs) const; 55 56 /// Clear the identifier 57 void clear(); 58 59 /** 60 * Determine the qualified identifier for this identified type. 61 * 62 * \note This is relatively expensive. Use declarationId() instead when possible! 63 * \returns the type's qualified identifier 64 */ 65 QualifiedIdentifier qualifiedIdentifier() const; 66 67 /// Determine this identified type's hash value. \returns the hash value 68 uint hash() const; 69 70 /** 71 * Access the identified type's declaration id, which is a unique global identifier for the 72 * type even when the same identifier represents a different type in a different context 73 * or source file. 74 * 75 * \returns the declaration identifier. 76 * \sa DeclarationId 77 */ 78 DeclarationId declarationId() const; 79 80 /** 81 * Set the globally unique declaration \a id. 82 * \param id new identifier 83 */ 84 void setDeclarationId(const DeclarationId& id); 85 86 /** 87 * Look up the declaration of this type in the given \a top context. 88 * 89 * \param top Top context to search for the declaration within 90 * \returns the declaration corresponding to this identified type 91 */ 92 Declaration* declaration(const TopDUContext* top) const; 93 94 /** 95 * \param top Top context to search for the declaration within 96 * Convenience function that returns the internal context of the attached declaration, 97 * or zero if no declaration is found, or if it does not have an internal context. 98 */ 99 DUContext* internalContext(const TopDUContext* top) const; 100 101 /** 102 * Set the declaration which created this type. 103 * 104 * \note You should be careful when setting this, because it also changes the meaning of the declaration. 105 * 106 * The logic is: 107 * If a declaration has a set abstractType(), and that abstractType() has set the same declaration as declaration(), 108 * then the declaration declares the type(thus it is a type-declaration, see Declaration::kind()) 109 * 110 * \param declaration Declaration which created the type 111 * */ 112 void setDeclaration(Declaration* declaration); 113 114 /// Allow IdentifiedType to access its data. 115 virtual IdentifiedTypeData* idData() = 0; 116 /// Allow IdentifiedType to access its data. 117 virtual const IdentifiedTypeData* idData() const = 0; 118 }; 119 120 ///Implements everything necessary to merge the given Parent class with IdentifiedType 121 ///Your used Data class must be based on the Data member class 122 template <class Parent> 123 class MergeIdentifiedType 124 : public Parent 125 , public IdentifiedType 126 { 127 public: 128 129 class Data 130 : public Parent::Data 131 , public IdentifiedTypeData 132 { 133 }; 134 MergeIdentifiedType()135 MergeIdentifiedType() 136 { 137 } 138 MergeIdentifiedType(Data & data)139 explicit MergeIdentifiedType(Data& data) : Parent(data) 140 { 141 } 142 143 MergeIdentifiedType(const MergeIdentifiedType& rhs) = delete; 144 idData()145 IdentifiedTypeData* idData() override 146 { 147 return static_cast<Data*>(this->d_func_dynamic()); 148 } 149 idData()150 const IdentifiedTypeData* idData() const override 151 { 152 return static_cast<const Data*>(this->d_func()); 153 } 154 equals(const KDevelop::AbstractType * rhs)155 bool equals(const KDevelop::AbstractType* rhs) const override 156 { 157 if (!Parent::equals(rhs)) 158 return false; 159 160 const auto* rhsId = dynamic_cast<const IdentifiedType*>(rhs); 161 Q_ASSERT(rhsId); 162 163 return IdentifiedType::equals(static_cast<const IdentifiedType*>(rhsId)); 164 } 165 }; 166 } 167 168 #endif 169