File indexing completed on 2024-06-16 04:23:16
0001 /* 0002 SPDX-FileCopyrightText: 2011-2014 Sven Brauch <svenbrauch@googlemail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KDEVPLATFORM_CONTAINER_TYPES_H 0008 #define KDEVPLATFORM_CONTAINER_TYPES_H 0009 0010 #include "structuretype.h" 0011 #include "typesystemdata.h" 0012 #include "typeutils.h" 0013 #include "../duchainlock.h" 0014 0015 #include <language/languageexport.h> 0016 0017 namespace KDevelop { 0018 class KDEVPLATFORMLANGUAGE_EXPORT ListTypeData 0019 : public KDevelop::StructureTypeData 0020 { 0021 public: 0022 ListTypeData() 0023 : KDevelop::StructureTypeData() 0024 , m_contentType() { } 0025 0026 ListTypeData(const ListTypeData& rhs) 0027 : KDevelop::StructureTypeData(rhs) 0028 , m_contentType(rhs.m_contentType) { } 0029 0030 explicit ListTypeData(const KDevelop::StructureTypeData& rhs) 0031 : KDevelop::StructureTypeData(rhs) 0032 , m_contentType() { } 0033 0034 ~ListTypeData() = default; 0035 0036 ListTypeData& operator=(const ListTypeData& rhs) = delete; 0037 0038 IndexedType m_contentType; 0039 }; 0040 0041 /** 0042 * @brief Represents a list-like object which can have a content type. 0043 * 0044 * Example for Python: 0045 * @code 0046 * # in the file describing the built-in list type 0047 * class List: # (1) 0048 * pass 0049 * 0050 * # in the user's code: 0051 * a = [] # (2) 0052 * a.append(3) # (3) 0053 * @endcode 0054 * 0055 * This type class can be used to determine the type of a as "list of int" as follows: 0056 * (1) When creating the type for the List class, 0057 * create a ListType instead of a structure type. 0058 * (Your language plugin somehow needs to know 0059 * which classes are list-like; Python does this 0060 * through special comments for the class) 0061 * (2) Set the type of a to the type declared by the 0062 * List class, as usual. 0063 * (3) Call 0064 * \code 0065 * static_cast<ListType*>(a->abstractType())->addContentType(int_type) 0066 * \endcode 0067 * (Your language plugin needs to know which methods 0068 * add their argument's content to the type's content; 0069 * Python does this through special comments for the method) 0070 */ 0071 class KDEVPLATFORMLANGUAGE_EXPORT ListType 0072 : public KDevelop::StructureType 0073 { 0074 public: 0075 using Ptr = TypePtr<ListType>; 0076 0077 ListType(); 0078 ListType(const ListType& rhs); 0079 explicit ListType(StructureTypeData& data); 0080 0081 ListType& operator=(const ListType& rhs) = delete; 0082 0083 /** 0084 * @brief Adds @p typeToAdd to the content type of this list. 0085 * 0086 * If the list currently has no type, it is set to this type. 0087 * If @p typeToAdd equals this list's content type, or is a useless type 0088 * nothing happens. 0089 * Otherwise, the type of the list becomes an unsure type of the previous 0090 * and @p typeToAdd. 0091 * 0092 * Pass your language's UnsureType as a template parameter, as it will eventually 0093 * need to be instantiated. 0094 * 0095 * @note If the type is already assigned to a declaration, the duchain 0096 * must be write-locked when this is called. 0097 * 0098 * @param typeToAdd The new type the list's contents can possibly be of. 0099 */ 0100 template <typename LanguageUnsureType> 0101 void addContentType(const AbstractType::Ptr& typeToAdd) 0102 { 0103 auto newContentType = TypeUtils::mergeTypes<LanguageUnsureType>(contentType().abstractType(), typeToAdd); 0104 d_func_dynamic()->m_contentType = IndexedType(newContentType); 0105 } 0106 0107 /** 0108 * @brief Replaces this list's content type by @p newType. 0109 */ 0110 void replaceContentType(const AbstractType::Ptr& newType); 0111 0112 /** 0113 * @brief Get this lists's content type. 0114 */ 0115 IndexedType contentType() const; 0116 0117 /** 0118 * @brief Return only the container type, not the content type in a string. 0119 */ 0120 QString containerToString() const; 0121 0122 /** 0123 * @brief Formats this type (base type and content type) in a string. 0124 */ 0125 QString toString() const override; 0126 0127 AbstractType* clone() const override; 0128 uint hash() const override; 0129 bool equals(const AbstractType* rhs) const override; 0130 0131 enum { Identity = 58 }; 0132 0133 using Data = ListTypeData; 0134 0135 protected: 0136 TYPE_DECLARE_DATA(ListType); 0137 }; 0138 0139 class KDEVPLATFORMLANGUAGE_EXPORT MapTypeData 0140 : public ListTypeData 0141 { 0142 public: 0143 MapTypeData() 0144 : ListTypeData() 0145 , m_keyType() { } 0146 0147 MapTypeData(const MapTypeData& rhs) 0148 : ListTypeData(rhs) 0149 , m_keyType(rhs.m_keyType) { } 0150 0151 explicit MapTypeData(const ListTypeData& rhs) 0152 : ListTypeData(rhs) 0153 , m_keyType() { } 0154 0155 ~MapTypeData() = default; 0156 0157 MapTypeData& operator=(const ListTypeData& rhs) = delete; 0158 0159 IndexedType m_keyType; 0160 }; 0161 0162 /** 0163 * @brief Represents a hashmap-like object which can have a key and a content type. 0164 * 0165 * @see ListType 0166 * This works the same as ListType, except that you can also track the object's key type. 0167 */ 0168 class KDEVPLATFORMLANGUAGE_EXPORT MapType 0169 : public ListType 0170 { 0171 public: 0172 using Ptr = TypePtr<MapType>; 0173 0174 MapType(); 0175 MapType(const MapType& rhs); 0176 explicit MapType(ListTypeData& data); 0177 0178 MapType& operator=(const MapType& rhs) = delete; 0179 0180 /** 0181 * @brief Add @p typeToAdd to this map's key type. 0182 * Behaves like addContentType, except that it modifies the key type instead. 0183 */ 0184 template <typename LanguageUnsureType> 0185 void addKeyType(const AbstractType::Ptr& typeToAdd) 0186 { 0187 auto newKeyType = TypeUtils::mergeTypes<LanguageUnsureType>(keyType().abstractType(), typeToAdd); 0188 DUChainWriteLocker lock; 0189 d_func_dynamic()->m_keyType = IndexedType(newKeyType); 0190 } 0191 0192 /** 0193 * @brief Set this map's key type to @p newType. 0194 */ 0195 void replaceKeyType(const AbstractType::Ptr& newType); 0196 0197 /** 0198 * @brief Get this map's key type. 0199 */ 0200 IndexedType keyType() const; 0201 0202 /** 0203 * @brief Formats this type (base type and key+content type) in a string. 0204 */ 0205 QString toString() const override; 0206 0207 AbstractType* clone() const override; 0208 uint hash() const override; 0209 bool equals(const AbstractType* rhs) const override; 0210 0211 enum { Identity = 57 }; 0212 0213 using Data = MapTypeData; 0214 0215 protected: 0216 TYPE_DECLARE_DATA(MapType); 0217 }; 0218 } // namespace KDevelop 0219 0220 #endif // KDEVPLATFORM_CONTAINER_TYPES_H