language/duchain
ducontextdata.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ducontextdata_H
00023 #define ducontextdata_H
00024
00025 #include <QtCore/QMutex>
00026 #include <QtCore/QMultiHash>
00027 #include <QtCore/QMap>
00028
00029 #include "../editor/simplecursor.h"
00030
00031 #include "duchainbase.h"
00032 #include "ducontext.h"
00033 #include "duchainpointer.h"
00034 #include "declaration.h"
00035 #include "use.h"
00036 #include "../languageexport.h"
00037 #include <util/google/dense_hash_map>
00038
00039 namespace KTextEditor {
00040 class SmartRange;
00041 }
00042
00043
00044 namespace KDevelop{
00045 class DUContext;
00046
00047 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_childContexts, LocalIndexedDUContext)
00048 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_importers, IndexedDUContext)
00049 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_importedContexts, DUContext::Import)
00050 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_localDeclarations, LocalIndexedDeclaration)
00051 KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(DUContextData, m_uses, Use)
00052
00054 class KDEVPLATFORMLANGUAGE_EXPORT DUContextData : public DUChainBaseData
00055 {
00056 public:
00057 DUContextData();
00058 ~DUContextData();
00059 DUContextData(const DUContextData& rhs);
00060 DUContext::ContextType m_contextType;
00061 IndexedQualifiedIdentifier m_scopeIdentifier;
00062 IndexedDeclaration m_owner;
00063 typedef DUContext::Import Import;
00064 START_APPENDED_LISTS_BASE(DUContextData, DUChainBaseData);
00065 APPENDED_LIST_FIRST(DUContextData, Import, m_importedContexts);
00066 APPENDED_LIST(DUContextData, LocalIndexedDUContext, m_childContexts, m_importedContexts);
00067
00070 APPENDED_LIST(DUContextData, IndexedDUContext, m_importers, m_childContexts);
00071
00073 APPENDED_LIST(DUContextData, LocalIndexedDeclaration, m_localDeclarations, m_importers);
00078 APPENDED_LIST(DUContextData, Use, m_uses, m_localDeclarations);
00079 END_APPENDED_LISTS(DUContextData, m_uses);
00080
00081 bool m_inSymbolTable : 1;
00082 bool m_anonymousInParent : 1;
00083 bool m_propagateDeclarations : 1;
00084 private:
00085 DUContextData& operator=(const DUContextData&) {
00086 return *this;
00087 }
00088 };
00089
00091 class DUContextDynamicData
00092 {
00093 private:
00094 inline const DUContextData* d_func() { return m_context->d_func(); }
00095 static inline const DUContextData* ctx_d_func(DUContext* ctx) { return ctx->d_func(); }
00096 static inline DUContextDynamicData* ctx_dynamicData(DUContext* ctx) { return ctx->m_dynamicData; }
00097
00098 public:
00099 DUContextDynamicData( DUContext* );
00100 DUContextPointer m_parentContext;
00101
00102 TopDUContext* m_topContext;
00103
00104
00105 typedef QMultiHash<Identifier, DeclarationPointer> DeclarationsHash;
00106
00107
00108 bool m_hasLocalDeclarationsHash;
00109
00110 static QMutex m_localDeclarationsMutex;
00112 DeclarationsHash m_localDeclarationsHash;
00113
00114 uint m_indexInTopContext;
00115
00120 mutable QVector<KTextEditor::SmartRange*> m_rangesForUses;
00121
00122 DUContext* m_context;
00123
00124 mutable bool m_rangesChanged : 1;
00131 void addChildContext(DUContext* context);
00132
00136 bool removeChildContext(DUContext* context);
00137
00138 void addImportedChildContext( DUContext * context );
00139 void removeImportedChildContext( DUContext * context );
00140
00141 void addDeclaration(Declaration* declaration);
00142
00146 bool removeDeclaration(Declaration* declaration);
00147
00148
00149 void scopeIdentifier(bool includeClasses, QualifiedIdentifier& target) const;
00150
00157 void addDeclarationToHash(const Identifier& identifer, Declaration* declaration);
00159 void removeDeclarationFromHash(const Identifier& identifer, Declaration* declaration);
00160
00162 void enableLocalDeclarationsHash(DUContext* ctx, const Identifier& currentIdentifier = Identifier(), Declaration* currentDecl = 0);
00163
00164 void disableLocalDeclarationsHash();
00165
00166 bool needsLocalDeclarationsHash();
00167
00168
00169 class VisibleDeclarationIterator {
00170 public:
00171 struct StackEntry {
00172 StackEntry() : data(0), item(0), endItem(0), nextChild(0) {
00173 }
00174
00175 DUContextDynamicData* data;
00176 const LocalIndexedDeclaration* item;
00177 const LocalIndexedDeclaration* endItem;
00178 uint nextChild;
00179 };
00180
00181 VisibleDeclarationIterator(DUContextDynamicData* data) {
00182 current.data = data;
00183 current.item = data->d_func()->m_localDeclarations();
00184 current.endItem = current.item + data->d_func()->m_localDeclarationsSize();
00185 current.nextChild = 0;
00186 toValidPosition();
00187 }
00188
00189 Declaration* operator*() const {
00190 return current.item->data(current.data->m_topContext);
00191 }
00192
00193 VisibleDeclarationIterator& operator++() {
00194 ++current.item;
00195 toValidPosition();
00196 return *this;
00197 }
00198
00199 operator bool() const {
00200 return (bool)current.data;
00201 }
00202
00203
00204 void toValidPosition() {
00205 if(current.item == current.endItem) {
00206 {
00207 const DUContextData* data = current.data->d_func();
00208
00209
00210 uint childContextCount = data->m_childContextsSize();
00211 const LocalIndexedDUContext* childContexts = data->m_childContexts();
00212
00213 for(unsigned int a = 0; a < childContextCount; ++a) {
00214 DUContext* child = childContexts[a].data(current.data->m_topContext);
00215 if(ctx_d_func(child)->m_propagateDeclarations) {
00216 current.nextChild = a+1;
00217 stack.append(current);
00218 current.data = ctx_dynamicData(child);
00219 current.item = ctx_d_func(child)->m_localDeclarations();
00220 current.endItem = current.item + ctx_d_func(child)->m_localDeclarationsSize();
00221 current.nextChild = 0;
00222 toValidPosition();
00223 return;
00224 }
00225 }
00226 }
00227 upwards:
00228
00229 if(stack.isEmpty()) {
00230 current = StackEntry();
00231 return;
00232 }
00233
00234 current = stack.back();
00235 stack.pop_back();
00236
00237 const DUContextData* data = current.data->d_func();
00238 uint childContextCount = data->m_childContextsSize();
00239 const LocalIndexedDUContext* childContexts = data->m_childContexts();
00240
00241 for(unsigned int a = current.nextChild; a < childContextCount; ++a) {
00242 DUContext* child = childContexts[a].data(current.data->m_topContext);
00243
00244 if(ctx_d_func(child)->m_propagateDeclarations) {
00245
00246 current.nextChild = a+1;
00247 stack.append(current);
00248
00249 current.data = ctx_dynamicData(child);
00250 current.item = ctx_d_func(child)->m_localDeclarations();
00251 current.endItem = current.item + ctx_d_func(child)->m_localDeclarationsSize();
00252 current.nextChild = 0;
00253 toValidPosition();
00254 return;
00255 }
00256 }
00257
00258 goto upwards;
00259 }
00260 }
00261
00262 StackEntry current;
00263
00264 KDevVarLengthArray<StackEntry> stack;
00265 };
00266
00270 bool imports(const DUContext* context, const TopDUContext* source, int maxDepth) const;
00271
00276 struct ImportsHash_Op {
00277 size_t operator() (const DUContextDynamicData* data) const {
00278 return (size_t)data;
00279 }
00280 };
00281
00282 typedef google::dense_hash_map<const DUContextDynamicData*, bool, ImportsHash_Op> ImportsHash;
00283
00284 bool importsSafeButSlow(const DUContext* context, const TopDUContext* source, ImportsHash& checked) const;
00285 };
00286
00287 }
00288
00289
00290 #endif
00291
00292