00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef DUCONTEXT_H
00021 #define DUCONTEXT_H
00022
00023 #include <QtCore/QHash>
00024 #include <QtCore/QList>
00025 #include <QtCore/QSet>
00026 #include <QtCore/QVector>
00027 #include <util/kdevvarlengtharray.h>
00028
00029 #include "../editor/documentcursorobject.h"
00030 #include "identifier.h"
00031 #include "duchainbase.h"
00032 #include "types/abstracttype.h"
00033 #include "duchainpointer.h"
00034 #include "declarationid.h"
00035 #include "indexeditems.h"
00036
00037 class QWidget;
00038
00039 namespace KTextEditor {
00040 class SmartRange;
00041 }
00042
00043 namespace KDevelop
00044 {
00045
00046 class Declaration;
00047 class DUChain;
00048 class Use;
00049 class TopDUContext;
00050 class DUContext;
00051 class DUContextData;
00052
00054 class KDEVPLATFORMLANGUAGE_EXPORT IndexedDUContext {
00055 public:
00056 IndexedDUContext(DUContext* decl);
00057 IndexedDUContext(uint topContext = 0, uint contextIndex = 0);
00058
00060 DUContext* context() const;
00061
00063 DUContext* data() const {
00064 return context();
00065 }
00066
00067 bool operator==(const IndexedDUContext& rhs) const {
00068 return m_topContext == rhs.m_topContext && m_contextIndex == rhs.m_contextIndex;
00069 }
00070 uint hash() const {
00071 return (m_topContext * 57 + m_contextIndex) * 29;
00072 }
00073
00074 bool isValid() const {
00075 return !isDummy() && context() != 0;
00076 }
00077
00078 bool operator<(const IndexedDUContext& rhs) const {
00079 Q_ASSERT(!isDummy());
00080 return m_topContext < rhs.m_topContext || (m_topContext == rhs.m_topContext && m_contextIndex < rhs.m_contextIndex);
00081 }
00082
00083
00084 uint localIndex() const {
00085 if(isDummy())
00086 return 0;
00087
00088 return m_contextIndex;
00089 }
00090
00091 uint topContextIndex() const {
00092 return m_topContext;
00093 }
00094
00095 IndexedTopDUContext indexedTopContext() const;
00096
00101 void setIsDummy(bool dummy) {
00102 if(isDummy() == dummy)
00103 return;
00104 if(dummy)
00105 m_topContext = 1 << 31;
00106 else
00107 m_topContext = 0;
00108 m_contextIndex = 0;
00109 }
00110
00111 bool isDummy() const {
00112
00113
00114 return (bool)(m_topContext & (1 << 31));
00115 }
00116
00117 QPair<uint, uint> dummyData() const {
00118 Q_ASSERT(isDummy());
00119 return qMakePair(m_topContext & (~(1<<31)), m_contextIndex);
00120 }
00121
00123 void setDummyData(QPair<uint, uint> data) {
00124 Q_ASSERT(isDummy());
00125
00126 m_topContext = data.first;
00127 m_contextIndex = data.second;
00128 Q_ASSERT(!isDummy());
00129 m_topContext |= (1 << 31);
00130 Q_ASSERT(isDummy());
00131 Q_ASSERT(dummyData() == data);
00132 }
00133
00134 private:
00135 uint m_topContext;
00136 uint m_contextIndex;
00137 };
00138
00140 class KDEVPLATFORMLANGUAGE_EXPORT LocalIndexedDUContext {
00141 public:
00142 LocalIndexedDUContext(DUContext* decl);
00143 LocalIndexedDUContext(uint contextIndex = 0);
00144
00145
00146 DUContext* data(TopDUContext* top) const;
00147
00148 bool operator==(const LocalIndexedDUContext& rhs) const {
00149 return m_contextIndex == rhs.m_contextIndex;
00150 }
00151
00152 bool isValid() const {
00153 return m_contextIndex != 0;
00154 }
00155
00156 uint hash() const {
00157 return m_contextIndex * 29;
00158 }
00159
00160 bool operator<(const LocalIndexedDUContext& rhs) const {
00161 return m_contextIndex < rhs.m_contextIndex;
00162 }
00163
00164
00165 uint localIndex() const {
00166 return m_contextIndex;
00167 }
00168
00169 bool isLoaded(TopDUContext* top) const;
00170 private:
00171 uint m_contextIndex;
00172 };
00173
00175 class ImportTraceItem
00176 {
00177 public:
00178
00179 ImportTraceItem(const DUContext* _ctx, SimpleCursor _pos = SimpleCursor::invalid()) : ctx(_ctx), position(_pos) {
00180 }
00181 ImportTraceItem() {
00182 }
00183
00184
00185 const DUContext* ctx;
00186 SimpleCursor position;
00187 };
00188
00189 class ImportTrace : public KDevVarLengthArray<ImportTraceItem, 40>
00190 {
00191 };
00192
00193 template<class T>
00194 class DUChainPointer;
00195 typedef DUChainPointer<DUContext> DUContextPointer;
00196
00210 class KDEVPLATFORMLANGUAGE_EXPORT DUContext : public DUChainBase
00211 {
00212 friend class Use;
00213 friend class Declaration;
00214 friend class DeclarationData;
00215 friend class DUContextData;
00216 friend class DUContextDynamicData;
00217 friend class Definition;
00218 friend class VisibleDeclarationIterator;
00219
00220 public:
00228 explicit DUContext(const SimpleRange& range, DUContext* parent = 0, bool anonymous = false);
00229 explicit DUContext(DUContextData&);
00230
00235 virtual ~DUContext();
00236
00237 enum ContextType {
00238 Global ,
00239 Namespace ,
00240 Class ,
00241 Function ,
00242 Template ,
00243 Enum ,
00244 Helper ,
00248 Other
00249 };
00250
00251 enum SearchFlag {
00252 NoSearchFlags = 0 ,
00253 InImportedParentContext = 1 ,
00254 OnlyContainerTypes = 2 ,
00255 DontSearchInParent = 4 ,
00256 NoUndefinedTemplateParams = 8 ,
00257 DirectQualifiedLookup = 16 ,
00258 NoFiltering = 32 ,
00259 OnlyFunctions = 64 ,
00260 NoImportsCheck = 128
00261 };
00262
00263 Q_DECLARE_FLAGS(SearchFlags, SearchFlag)
00264
00265
00266 ContextType type() const;
00267 void setType(ContextType type);
00268
00273 Declaration* owner() const;
00278 void setOwner(Declaration* decl);
00279
00283 int depth() const;
00284
00288 virtual TopDUContext* topContext() const;
00289
00295 DUContext* findContextAt(const SimpleCursor& position, bool includeBorders = false) const;
00296
00301 Declaration* findDeclarationAt(const SimpleCursor& position) const;
00302
00306 DUContext* findContextIncluding(const SimpleRange& range) const;
00307
00311 QualifiedIdentifier scopeIdentifier(bool includeClasses = false) const;
00312
00317 bool equalScopeIdentifier(const DUContext* rhs) const;
00318
00323 QualifiedIdentifier localScopeIdentifier() const;
00324
00326 IndexedQualifiedIdentifier indexedLocalScopeIdentifier() const;
00327
00332 void setLocalScopeIdentifier(const QualifiedIdentifier& identifier);
00333
00337 bool inSymbolTable() const;
00338
00343 void setInSymbolTable(bool inSymbolTable);
00344
00348 DUContext* parentContext() const;
00349
00351 struct KDEVPLATFORMLANGUAGE_EXPORT Import {
00353 Import(DUContext* context, const DUContext* importer, const SimpleCursor& position = SimpleCursor::invalid());
00354 Import() : position(SimpleCursor::invalid()) {
00355 }
00356 Import(const DeclarationId& id, const SimpleCursor& position = SimpleCursor::invalid());
00357 bool operator==(const Import& rhs) const {
00358 return m_context == rhs.m_context && m_declaration == rhs.m_declaration;
00359 }
00360
00363 DUContext* context(const TopDUContext* topContext) const;
00364
00365
00366 uint topContextIndex() const {
00367 return m_context.topContextIndex();
00368 }
00369
00370 IndexedDUContext indexedContext() const {
00371 return m_context;
00372 }
00373
00375 bool isDirect() const;
00376
00378 DeclarationId indirectDeclarationId() const {
00379 return m_declaration;
00380 }
00381
00382 SimpleCursor position;
00383 private:
00384
00386 DeclarationId m_declaration;
00387 IndexedDUContext m_context;
00388 };
00389
00396 virtual QVector<Import> importedParentContexts() const;
00397
00403 virtual SimpleCursor importPosition(const DUContext* target) const;
00404
00408 virtual bool imports(const DUContext* origin, const SimpleCursor& position = SimpleCursor::invalid()) const;
00409
00421 virtual void addImportedParentContext(DUContext* context, const SimpleCursor& position = SimpleCursor::invalid(), bool anonymous = false, bool temporary = false);
00422
00430 bool addIndirectImport(const DUContext::Import& import);
00431
00435 virtual void removeImportedParentContext(DUContext* context);
00436
00440 virtual void clearImportedParentContexts();
00441
00446 void setPropagateDeclarations(bool propagate);
00447
00448 bool isPropagateDeclarations() const;
00449
00454 virtual QVector<DUContext*> importers() const;
00455
00459 KDevVarLengthArray<IndexedDUContext> indexedImporters() const;
00460
00465 QVector<DUContext*> childContexts() const;
00466
00471 void deleteChildContextsRecursively();
00472
00474 virtual bool inDUChain() const;
00475
00484 virtual DUContext* specialize(IndexedInstantiationInformation specialization, const TopDUContext* topContext, int upDistance = 0);
00485
00500 QList<Declaration*> findDeclarations(const QualifiedIdentifier& identifier, const SimpleCursor& position = SimpleCursor::invalid(), const AbstractType::Ptr& dataType = AbstractType::Ptr(), const TopDUContext* topContext = 0, SearchFlags flags = NoSearchFlags) const;
00501
00516 QList<Declaration*> findDeclarations(const Identifier& identifier, const SimpleCursor& position = SimpleCursor::invalid(), const TopDUContext* topContext = 0, SearchFlags flags = NoSearchFlags) const;
00517
00524 QList<Declaration*> findLocalDeclarations(const Identifier& identifier, const SimpleCursor& position = SimpleCursor::invalid(), const TopDUContext* topContext = 0, const AbstractType::Ptr& dataType = AbstractType::Ptr(), SearchFlags flags = NoSearchFlags) const;
00525
00530 QVector<Declaration*> clearLocalDeclarations();
00531
00536 void deleteLocalDeclarations();
00537
00543 virtual QVector<Declaration*> localDeclarations(const TopDUContext* source = 0) const;
00544
00554 DUContext* findContext(const SimpleCursor& position, DUContext* parent = 0) const;
00555
00569 QList<DUContext*> findContexts(ContextType contextType, const QualifiedIdentifier& identifier, const SimpleCursor& position = SimpleCursor::invalid(), const TopDUContext* source = 0, SearchFlags flags = NoSearchFlags) const;
00570
00575 bool parentContextOf(DUContext* context) const;
00576
00592 QList< QPair<Declaration*, int> > allDeclarations(const SimpleCursor& position, const TopDUContext* topContext, bool searchInParents=true) const;
00593
00598 QList<Declaration*> allLocalDeclarations(const Identifier& identifier) const;
00599
00603 void cleanIfNotEncountered(const QSet<DUChainBase*>& encountered);
00604
00608 void changingIdentifier( Declaration* decl, const Identifier& from, const Identifier& to );
00609
00632 const Use* uses() const;
00633
00635 int usesCount() const;
00636
00641 int findUseAt(const SimpleCursor& position) const;
00642
00646 KTextEditor::SmartRange* useSmartRange(int useIndex);
00647
00653 void setUseSmartRange(int useIndex, KTextEditor::SmartRange* range);
00654
00658 void clearUseSmartRanges();
00659
00663 void setUseDeclaration(int useIndex, int declarationIndex);
00664
00676 int createUse(int declarationIndex, const SimpleRange& range, KTextEditor::SmartRange* smartRange, int insertBefore = -1);
00677
00681 void deleteUse(int index);
00682
00686 virtual void deleteUses();
00687
00691 virtual void deleteUsesRecursively();
00692
00696 QVector<KTextEditor::SmartRange*> useRanges();
00697
00701 QVector<KTextEditor::SmartRange*> takeUseRanges();
00702
00717 virtual QWidget* createNavigationWidget(Declaration* decl = 0, TopDUContext* topContext = 0, const QString& htmlPrefix = QString(), const QString& htmlSuffix = QString()) const;
00718
00719 enum {
00720 Identity = 2
00721 };
00722
00727 struct KDEVPLATFORMLANGUAGE_EXPORT SearchItem : public KShared {
00728
00729 typedef KSharedPtr<SearchItem> Ptr;
00730 typedef KDevVarLengthArray<Ptr, 256> PtrList;
00731
00734 SearchItem(const QualifiedIdentifier& id, Ptr nextItem = Ptr(), int start = 0);
00735
00738 SearchItem(const QualifiedIdentifier& id, const PtrList& nextItems, int start = 0);
00739
00740 SearchItem(bool explicitlyGlobal, Identifier id, const PtrList& nextItems);
00741 SearchItem(bool explicitlyGlobal, Identifier id, Ptr nextItem);
00742
00743 bool isEmpty() const;
00744 bool hasNext() const;
00745
00751 void addToEachNode(Ptr item);
00752 void addToEachNode(PtrList items);
00753
00755 bool match(const QualifiedIdentifier& id, int offset = 0) const;
00756
00757
00758 QList<QualifiedIdentifier> toList(const QualifiedIdentifier& prefix=QualifiedIdentifier()) const;
00759
00760 void addNext(Ptr other);
00761
00762 bool isExplicitlyGlobal;
00763 Identifier identifier;
00764 PtrList next;
00765 };
00766
00769
00781 typedef KDevVarLengthArray<Declaration*, 40> DeclarationList;
00782
00783 virtual bool findDeclarationsInternal(const SearchItem::PtrList& identifiers, const SimpleCursor& position, const AbstractType::Ptr& dataType, DeclarationList& ret, const TopDUContext* source, SearchFlags flags, uint depth ) const;
00784
00786 void squeeze();
00787
00790 QList<QualifiedIdentifier> fullyApplyAliases(KDevelop::QualifiedIdentifier id, const KDevelop::TopDUContext* source) const;
00791
00792 protected:
00793
00798 virtual bool foundEnough( const DeclarationList& decls , SearchFlags flags ) const;
00804 virtual void mergeDeclarationsInternal(QList< QPair<Declaration*, int> >& definitions, const SimpleCursor& position, QHash<const DUContext*, bool>& hadContexts, const TopDUContext* source, bool searchInParents = true, int currentDepth = 0) const;
00805
00807 QualifiedIdentifier scopeIdentifierInternal(DUContext* context) const;
00808
00809 virtual void findLocalDeclarationsInternal( const Identifier& identifier, const SimpleCursor & position, const AbstractType::Ptr& dataType, DeclarationList& ret, const TopDUContext* source, SearchFlags flags ) const;
00810
00812 virtual void findContextsInternal(ContextType contextType, const SearchItem::PtrList& identifiers, const SimpleCursor& position, QList<DUContext*>& ret, const TopDUContext* source, SearchFlags flags = NoSearchFlags) const;
00813
00818 void applyAliases(const SearchItem::PtrList& identifiers, SearchItem::PtrList& targetIdentifiers, const SimpleCursor& position, bool canBeNamespace, bool onlyImports = false) const;
00824 virtual void applyUpwardsAliases(SearchItem::PtrList& identifiers, const TopDUContext* source) const;
00825
00826 DUContext(DUContextData& dd, const SimpleRange& range, DUContext* parent = 0, bool anonymous = false);
00827
00829 DUContext(DUContext& useDataFrom);
00830
00832 bool isAnonymous() const;
00833
00839 virtual bool shouldSearchInParent(SearchFlags flags) const;
00840
00841 private:
00842 void rebuildDynamicData(DUContext* parent, uint ownIndex);
00843
00844 friend class TopDUContext;
00845 friend class IndexedDUContext;
00846 friend class LocalIndexedDUContext;
00847 friend class TopDUContextDynamicData;
00848 void synchronizeUsesFromSmart() const;
00849 void synchronizeUsesToSmart() const;
00850
00851 void clearDeclarationIndices();
00852 void updateDeclarationIndices();
00853
00854 virtual void rangePositionChanged(KTextEditor::SmartRange* range);
00855 virtual void rangeDeleted(KTextEditor::SmartRange* range);
00856
00857 DUCHAIN_DECLARE_DATA(DUContext)
00858 class DUContextDynamicData* m_dynamicData;
00859 };
00860
00867 KDEVPLATFORMLANGUAGE_EXPORT extern const Identifier& globalImportIdentifier;
00868
00872 KDEVPLATFORMLANGUAGE_EXPORT QList<SimpleRange> allUses(DUContext* context, int declarationIndex, bool noEmptyRanges = false);
00873
00877 KDEVPLATFORMLANGUAGE_EXPORT QList<KTextEditor::SmartRange*> allSmartUses(DUContext* context, int declarationIndex);
00878 }
00879
00880 #endif // DUCONTEXT_H
00881
00882