File indexing completed on 2024-05-12 04:38:01
0001 /* 0002 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0003 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef DUCONTEXTDYNAMICDATA_H 0009 #define DUCONTEXTDYNAMICDATA_H 0010 0011 #include "ducontextdata.h" 0012 0013 namespace KDevelop { 0014 ///This class contains data that is only runtime-dependent and does not need to be stored to disk 0015 class DUContextDynamicData 0016 { 0017 private: 0018 inline const DUContextData* d_func() const { return m_context->d_func(); } 0019 inline DUContextData* d_func_dynamic() { return m_context->d_func_dynamic(); } 0020 static inline const DUContextData* ctx_d_func(DUContext* ctx) { return ctx->d_func(); } 0021 static inline DUContextDynamicData* ctx_dynamicData(DUContext* ctx) { return ctx->m_dynamicData; } 0022 0023 public: 0024 explicit DUContextDynamicData(DUContext*); 0025 DUContextPointer m_parentContext; 0026 0027 TopDUContext* m_topContext; 0028 0029 uint m_indexInTopContext; //Index of this DUContext in the top-context 0030 0031 DUContext* m_context; 0032 0033 // cache of unserialized child contexts 0034 QVector<DUContext*> m_childContexts; 0035 // cache of unserialized local declarations 0036 QVector<Declaration*> m_localDeclarations; 0037 0038 /** 0039 * Adds a child context. 0040 * 0041 * \note Be sure to have set the text location first, so that 0042 * the chain is sorted correctly. 0043 */ 0044 void addChildContext(DUContext* context); 0045 0046 /**Removes the context from childContexts 0047 * @return Whether a context was removed 0048 * */ 0049 bool removeChildContext(DUContext* context); 0050 0051 void addImportedChildContext(DUContext* context); 0052 void removeImportedChildContext(DUContext* context); 0053 0054 void addDeclaration(Declaration* declaration); 0055 0056 /**Removes the declaration from localDeclarations 0057 * @return Whether a declaration was removed 0058 * */ 0059 bool removeDeclaration(Declaration* declaration); 0060 0061 //Files the scope identifier into target 0062 void scopeIdentifier(bool includeClasses, QualifiedIdentifier& target) const; 0063 0064 //Iterates through all visible declarations within a given context, including the ones propagated from sub-contexts 0065 class VisibleDeclarationIterator 0066 { 0067 public: 0068 struct StackEntry 0069 { 0070 explicit StackEntry(const DUContextDynamicData* data = nullptr) 0071 : data(data) 0072 , index(0) 0073 , nextChild(0) 0074 { 0075 } 0076 0077 const DUContextDynamicData* data; 0078 int index; 0079 uint nextChild; 0080 }; 0081 0082 explicit VisibleDeclarationIterator(const DUContextDynamicData* data) 0083 : current(data) 0084 { 0085 toValidPosition(); 0086 } 0087 0088 inline Declaration* operator*() const 0089 { 0090 return current.data ? current.data->m_localDeclarations.value(current.index) : nullptr; 0091 } 0092 0093 inline VisibleDeclarationIterator& operator++() 0094 { 0095 ++current.index; 0096 toValidPosition(); 0097 return *this; 0098 } 0099 0100 inline operator bool() const 0101 { 0102 return current.data && !current.data->m_localDeclarations.isEmpty(); 0103 } 0104 0105 // Moves the cursor to the next valid position, from an invalid one 0106 void toValidPosition() 0107 { 0108 if (!current.data || current.index < current.data->m_localDeclarations.size()) { 0109 // still valid 0110 return; 0111 } 0112 0113 do { 0114 // Check if we can proceed into a propagating child-context 0115 for (int a = current.nextChild; a < current.data->m_childContexts.size(); ++a) { 0116 DUContext* child = current.data->m_childContexts[a]; 0117 0118 if (ctx_d_func(child)->m_propagateDeclarations) { 0119 current.nextChild = a + 1; 0120 stack.append(current); 0121 current = StackEntry(ctx_dynamicData(child)); 0122 toValidPosition(); 0123 return; 0124 } 0125 } 0126 0127 //Go up and into the next valid context 0128 if (stack.isEmpty()) { 0129 current = StackEntry(); 0130 return; 0131 } 0132 0133 current = stack.back(); 0134 stack.pop_back(); 0135 } while (true); 0136 } 0137 0138 StackEntry current; 0139 0140 KDevVarLengthArray<StackEntry> stack; 0141 }; 0142 0143 /** 0144 * Returns true if this context is imported by the given one, on any level. 0145 * */ 0146 bool imports(const DUContext* context, const TopDUContext* source, 0147 QSet<const DUContextDynamicData*>* recursionGuard) const; 0148 }; 0149 } 0150 0151 Q_DECLARE_TYPEINFO(KDevelop::DUContextDynamicData::VisibleDeclarationIterator::StackEntry, Q_MOVABLE_TYPE); 0152 0153 #endif