File indexing completed on 2024-05-12 04:38:04
0001 /* 0002 SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KDEVPLATFORM_PROBLEM_H 0008 #define KDEVPLATFORM_PROBLEM_H 0009 0010 #include <QExplicitlySharedDataPointer> 0011 0012 #include <language/languageexport.h> 0013 0014 #include "duchainbase.h" 0015 #include <serialization/indexedstring.h> 0016 #include "indexedtopducontext.h" 0017 #include <interfaces/iproblem.h> 0018 #include <interfaces/iassistant.h> 0019 0020 namespace KDevelop { 0021 class IAssistant; 0022 class Problem; 0023 0024 using ProblemPointer = QExplicitlySharedDataPointer<Problem>; 0025 0026 /** 0027 * Represents a problem only by its index within the top-context 0028 * 0029 * Fixme: share code with the other LocalIndexed* classes 0030 */ 0031 class KDEVPLATFORMLANGUAGE_EXPORT LocalIndexedProblem 0032 { 0033 public: 0034 LocalIndexedProblem(const ProblemPointer& problem, const TopDUContext* top); 0035 explicit LocalIndexedProblem(uint index = 0) 0036 : m_index(index) 0037 {} 0038 0039 /** 0040 * \note Duchain must be read locked 0041 */ 0042 ProblemPointer data(const TopDUContext* top) const; 0043 0044 bool operator==(const LocalIndexedProblem& rhs) const 0045 { 0046 return m_index == rhs.m_index; 0047 } 0048 0049 bool isValid() const 0050 { 0051 return m_index; 0052 } 0053 0054 /** 0055 * Index of the Declaration within the top context 0056 */ 0057 uint localIndex() const 0058 { 0059 return m_index; 0060 } 0061 0062 private: 0063 uint m_index; 0064 }; 0065 0066 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(ProblemData, diagnostics, LocalIndexedProblem) 0067 0068 class KDEVPLATFORMLANGUAGE_EXPORT ProblemData 0069 : public DUChainBaseData 0070 { 0071 public: 0072 ProblemData() 0073 { 0074 initializeAppendedLists(); 0075 } 0076 0077 ProblemData(const ProblemData& rhs) 0078 : DUChainBaseData(rhs) 0079 , source(rhs.source) 0080 , severity(rhs.severity) 0081 , url(rhs.url) 0082 , description(rhs.description) 0083 , explanation(rhs.explanation) 0084 { 0085 initializeAppendedLists(); 0086 copyListsFrom(rhs); 0087 } 0088 0089 ~ProblemData() 0090 { 0091 freeAppendedLists(); 0092 } 0093 0094 ProblemData& operator=(const ProblemData& rhs) = delete; 0095 0096 IProblem::Source source = IProblem::Unknown; 0097 IProblem::Severity severity = IProblem::Error; 0098 IndexedString url; 0099 IndexedString description; 0100 IndexedString explanation; 0101 IProblem::FinalLocationMode finalLocationMode = IProblem::Range; 0102 0103 START_APPENDED_LISTS_BASE(ProblemData, DUChainBaseData); 0104 APPENDED_LIST_FIRST(ProblemData, LocalIndexedProblem, diagnostics); 0105 END_APPENDED_LISTS(ProblemData, diagnostics); 0106 }; 0107 0108 /** 0109 * An object representing a problem in preprocessing, parsing, definition-use chain compilation, etc. 0110 * 0111 * You should always use ProblemPointer, because Problem may be subclassed. 0112 * The subclass would be lost while copying. 0113 * 0114 * @warning Access to problems must be serialized through DUChainLock. 0115 */ 0116 class KDEVPLATFORMLANGUAGE_EXPORT Problem 0117 : public DUChainBase 0118 , public IProblem 0119 { 0120 public: 0121 using Ptr = QExplicitlySharedDataPointer<Problem>; 0122 0123 Problem(); 0124 explicit Problem(ProblemData& data); 0125 ~Problem() override; 0126 0127 Source source() const override; 0128 void setSource(IProblem::Source source) override; 0129 0130 /** 0131 * Returns a string version of the problem source 0132 */ 0133 QString sourceString() const override; 0134 0135 TopDUContext* topContext() const override; 0136 KDevelop::IndexedString url() const override; 0137 0138 /** 0139 * Location where this problem occurred 0140 * @warning Must only be called from the foreground 0141 * */ 0142 DocumentRange finalLocation() const override; 0143 void setFinalLocation(const DocumentRange& location) override; 0144 0145 FinalLocationMode finalLocationMode() const override; 0146 void setFinalLocationMode(FinalLocationMode mode) override; 0147 0148 /** 0149 * Returns child diagnostics of this particular problem 0150 * 0151 * Example: 0152 * @code 0153 * void foo(unsigned int); 0154 * void foo(const char*); 0155 * int main() { foo(0); } 0156 * @endcode 0157 * 0158 * => foo(0) is ambiguous. This will give us a ProblemPointer pointing to 'foo(0)'. 0159 * 0160 * Additionally, @p diagnostics may return the two locations to the ambiguous overloads, 0161 * with descriptions such as 'test.cpp:1: candidate : ...' 0162 */ 0163 void clearDiagnostics() override; 0164 0165 QVector<IProblem::Ptr> diagnostics() const override; 0166 void setDiagnostics(const QVector<IProblem::Ptr>& diagnostics) override; 0167 void addDiagnostic(const IProblem::Ptr& diagnostic) override; 0168 0169 /** 0170 * A brief description of the problem. 0171 */ 0172 QString description() const override; 0173 void setDescription(const QString& description) override; 0174 0175 /** 0176 * A (detailed) explanation of why the problem occurred. 0177 */ 0178 QString explanation() const override; 0179 void setExplanation(const QString& explanation) override; 0180 0181 /** 0182 * Get the severity of this problem. 0183 * This is used for example to decide for a highlighting color. 0184 * 0185 * @see setSeverity() 0186 */ 0187 Severity severity() const override; 0188 0189 /** 0190 * Set the severity of this problem. 0191 */ 0192 void setSeverity(Severity severity) override; 0193 0194 /** 0195 * Returns a string representation of the severity. 0196 */ 0197 QString severityString() const override; 0198 0199 /** 0200 * If this problem can be solved, this may return an assistant for the solution. 0201 */ 0202 QExplicitlySharedDataPointer<IAssistant> solutionAssistant() const override; 0203 0204 enum { 0205 Identity = 15 0206 }; 0207 0208 /** 0209 * Returns a string representation of this problem, useful for debugging. 0210 */ 0211 virtual QString toString() const; 0212 0213 private: 0214 void rebuildDynamicData(DUContext* parent, uint ownIndex) override; 0215 0216 Q_DISABLE_COPY(Problem) 0217 0218 DUCHAIN_DECLARE_DATA(Problem) 0219 friend class TopDUContext; 0220 friend class TopDUContextDynamicData; 0221 friend class LocalIndexedProblem; 0222 0223 //BEGIN dynamic data 0224 TopDUContextPointer m_topContext; 0225 mutable QList<Ptr> m_diagnostics; 0226 uint m_indexInTopContext = 0; 0227 //END dynamic data 0228 }; 0229 0230 class KDEVPLATFORMLANGUAGE_EXPORT StaticAssistantProblem 0231 : public KDevelop::Problem 0232 { 0233 public: 0234 KDevelop::IAssistant::Ptr solutionAssistant() const override 0235 { 0236 return m_solution; 0237 } 0238 void setSolutionAssistant(const KDevelop::IAssistant::Ptr& p) 0239 { 0240 m_solution = p; 0241 } 0242 0243 private: 0244 KDevelop::IAssistant::Ptr m_solution; 0245 }; 0246 } 0247 0248 Q_DECLARE_TYPEINFO(KDevelop::LocalIndexedProblem, Q_MOVABLE_TYPE); 0249 0250 KDEVPLATFORMLANGUAGE_EXPORT QDebug operator<<(QDebug s, const KDevelop::Problem& problem); 0251 KDEVPLATFORMLANGUAGE_EXPORT QDebug operator<<(QDebug s, const KDevelop::ProblemPointer& problem); 0252 0253 #endif // KDEVPLATFORM_PROBLEM_H