Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / ducontextdata.h
blob769406b04838eef8a1ebcedb0919f4ec02989690
1 /***************************************************************************
2 * This file is part of KDevelop *
3 * Copyright 2006 Hamish Rodda <rodda@kde.org> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Library General Public License as *
7 * published by the Free Software Foundation; either version 2 of the *
8 * License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Library General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #ifndef ducontext_p_H
22 #define ducontext_p_H
24 #include <QtCore/QMutex>
25 #include <QtCore/QMultiHash>
26 #include <QtCore/QMap>
28 #include "../editor/simplecursor.h"
30 #include "duchainbase.h"
31 #include "ducontext.h"
32 #include "duchainpointer.h"
33 #include "declaration.h"
34 #include "use.h"
35 #include "../languageexport.h"
37 namespace KTextEditor {
38 class SmartRange;
42 namespace KDevelop{
43 class DUContext;
45 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_childContexts, LocalIndexedDUContext)
46 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_importers, IndexedDUContext)
47 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_importedContexts, DUContext::Import)
48 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_localDeclarations, LocalIndexedDeclaration)
49 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_uses, Use)
51 ///This class contains data that needs to be stored to disk
52 class KDEVPLATFORMLANGUAGE_EXPORT DUContextData : public DUChainBaseData
54 public:
55 DUContextData();
56 ~DUContextData();
57 DUContextData(const DUContextData& rhs);
58 DUContext::ContextType m_contextType;
59 IndexedQualifiedIdentifier m_scopeIdentifier;
60 IndexedDeclaration m_owner;
62 START_APPENDED_LISTS_BASE(DUContextData, DUChainBaseData);
63 APPENDED_LIST_FIRST(DUContextData, DUContext::Import, m_importedContexts);
64 APPENDED_LIST(DUContextData, LocalIndexedDUContext, m_childContexts, m_importedContexts);
66 ///@todo eventually move the importers into some separate structure
67 APPENDED_LIST(DUContextData, IndexedDUContext, m_importers, m_childContexts);
69 ///@warning: Whenever m_localDeclarations is read or written, DUContextDynamicData::m_localDeclarationsMutex must be locked.
70 APPENDED_LIST(DUContextData, LocalIndexedDeclaration, m_localDeclarations, m_importers);
71 /**
72 * Vector of all uses in this context
73 * Mutable for range synchronization
74 * */
75 APPENDED_LIST(DUContextData, Use, m_uses, m_localDeclarations);
76 END_APPENDED_LISTS(DUContextData, m_uses);
78 bool m_inSymbolTable : 1;
79 bool m_anonymousInParent : 1; //Whether this context was added anonymously into the parent. This means that it cannot be found as child-context in the parent.
80 bool m_propagateDeclarations : 1;
81 private:
82 DUContextData& operator=(const DUContextData&) {
83 return *this;
87 ///This class contains data that is only runtime-dependant and does not need to be stored to disk
88 class DUContextDynamicData
90 public:
91 DUContextDynamicData( DUContext* );
92 DUContextPointer m_parentContext;
94 TopDUContext* m_topContext;
96 //Use DeclarationPointer instead of declaration, so we can locate management-problems
97 typedef QMultiHash<Identifier, DeclarationPointer> DeclarationsHash;
99 //Whether this context uses m_localDeclarationsHash
100 bool m_hasLocalDeclarationsHash;
102 static QMutex m_localDeclarationsMutex;
103 ///@warning: Whenever m_localDeclarations is read or written, m_localDeclarationsHash must be locked.
104 DeclarationsHash m_localDeclarationsHash; //This hash can contain more declarations than m_localDeclarations, due to declarations propagated up from children.
106 uint m_indexInTopContext; //Index of this DUContext in the top-context
109 * If this document is loaded, this contains a smart-range for each use.
110 * This may temporarily contain zero ranges.
111 * */
112 mutable QVector<KTextEditor::SmartRange*> m_rangesForUses;
114 DUContext* m_context;
116 mutable bool m_rangesChanged : 1;
118 * Adds a child context.
120 * \note Be sure to have set the text location first, so that
121 * the chain is sorted correctly.
123 void addChildContext(DUContext* context);
125 /**Removes the context from childContexts
126 * @return Whether a context was removed
127 * */
128 bool removeChildContext(DUContext* context);
130 void addImportedChildContext( DUContext * context );
131 void removeImportedChildContext( DUContext * context );
133 void addDeclaration(Declaration* declaration);
135 /**Removes the declaration from localDeclarations
136 * @return Whether a declaration was removed
137 * */
138 bool removeDeclaration(Declaration* declaration);
140 //Files the scope identifier into target
141 void scopeIdentifier(bool includeClasses, QualifiedIdentifier& target) const;
144 * This propagates the declaration into the parent search-hashes,
145 * up to the first parent that has m_propagateDeclarations set to false.
147 * Must be called with m_localDeclarationsMutex locked
149 void addDeclarationToHash(const Identifier& identifer, Declaration* declaration);
150 ///Must be called with m_localDeclarationsMutex locked
151 void removeDeclarationFromHash(const Identifier& identifer, Declaration* declaration);
153 ///Adds all declarations that should be in the hash into the hash
154 void enableLocalDeclarationsHash(DUContext* ctx, const Identifier& currentIdentifier = Identifier(), Declaration* currentDecl = 0);
156 void disableLocalDeclarationsHash();
158 bool needsLocalDeclarationsHash();
160 //Iterates through all visible declarations within a given context, including the ones propagated from sub-contexts
161 struct VisibleDeclarationIterator {
163 struct StackEntry {
164 StackEntry() : data(0), item(0), endItem(0), nextChild(0) {
167 DUContextDynamicData* data;
168 const LocalIndexedDeclaration* item;
169 const LocalIndexedDeclaration* endItem;
170 uint nextChild;
173 VisibleDeclarationIterator(DUContextDynamicData* data) {
174 current.data = data;
175 current.item = data->m_context->d_func()->m_localDeclarations();
176 current.endItem = current.item + data->m_context->d_func()->m_localDeclarationsSize();
177 current.nextChild = 0;
178 toValidPosition();
181 Declaration* operator*() const {
182 return current.item->data(current.data->m_topContext);
185 VisibleDeclarationIterator& operator++() {
186 ++current.item;
187 toValidPosition();
188 return *this;
191 operator bool() const {
192 return (bool)current.data;
195 //Moves the cursor to the next valid position, from an invalid one(currentPos.back() == current.data->declarationCount())
196 void toValidPosition() {
197 if(current.item == current.endItem) {
199 const DUContextData* data = current.data->m_context->d_func();
201 //Check if we can proceed into a propagating child-context
202 uint childContextCount = data->m_childContextsSize();
203 const LocalIndexedDUContext* childContexts = data->m_childContexts();
205 for(unsigned int a = 0; a < childContextCount; ++a) {
206 DUContext* child = childContexts[a].data(current.data->m_topContext);
207 if(child->d_func()->m_propagateDeclarations) {
208 current.nextChild = a+1;
209 stack.append(current);
210 current.data = child->m_dynamicData;
211 current.item = child->d_func()->m_localDeclarations();
212 current.endItem = current.item + child->d_func()->m_localDeclarationsSize();
213 current.nextChild = 0;
214 toValidPosition();
215 return;
219 upwards:
220 //Go up and into the next valid context
221 if(stack.isEmpty()) {
222 current = StackEntry();
223 return;
226 current = stack.back();
227 stack.pop_back();
229 const DUContextData* data = current.data->m_context->d_func();
230 uint childContextCount = data->m_childContextsSize();
231 const LocalIndexedDUContext* childContexts = data->m_childContexts();
233 for(unsigned int a = current.nextChild; a < childContextCount; ++a) {
234 DUContext* child = childContexts[a].data(current.data->m_topContext);
236 if(child->d_func()->m_propagateDeclarations) {
238 current.nextChild = a+1;
239 stack.append(current);
241 current.data = child->m_dynamicData;
242 current.item = child->d_func()->m_localDeclarations();
243 current.endItem = current.item + child->d_func()->m_localDeclarationsSize();
244 current.nextChild = 0;
245 toValidPosition();
246 return;
250 goto upwards;
254 StackEntry current;
256 KDevVarLengthArray<StackEntry> stack;
260 * Returns true if this context is imported by the given one, on any level.
261 * */
262 bool isThisImportedBy(const DUContext* context) const;
268 #endif
270 //kate: space-indent on; indent-width 2; replace-tabs on; auto-insert-doxygen on; indent-mode cstyle;