mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 19:32:54 +00:00
392 lines
16 KiB
C++
392 lines
16 KiB
C++
/* This file is part of KDevelop
|
|
Copyright 2006 Hamish Rodda <rodda@kde.org>
|
|
Copyright 2007-2009 David Nolden <david.nolden.kdevelop@art-master.de>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef KDEVPLATFORM_TOPDUCONTEXT_H
|
|
#define KDEVPLATFORM_TOPDUCONTEXT_H
|
|
|
|
#include "ducontext.h"
|
|
#include <language/util/setrepository.h>
|
|
#include <QMetaType>
|
|
|
|
template< class T >
|
|
class KSharedPtr;
|
|
|
|
namespace KDevelop
|
|
{
|
|
class IAstContainer;
|
|
class QualifiedIdentifier;
|
|
class DUChain;
|
|
class ParsingEnvironmentFile;
|
|
class TopDUContextData;
|
|
class TopDUContextLocalPrivate;
|
|
class IndexedTopDUContext;
|
|
// class TopDUContextDynamicData;
|
|
class Problem;
|
|
class DeclarationChecker;
|
|
class TopDUContext;
|
|
|
|
struct KDEVPLATFORMLANGUAGE_EXPORT RecursiveImportRepository {
|
|
static Utils::BasicSetRepository* repository();
|
|
};
|
|
|
|
///Maps an imported top-context to a pair:
|
|
///1. The distance to the top-context, and 2. The next step towards the top-context
|
|
///in the chain.
|
|
typedef QHash<const TopDUContext*, QPair<int, const TopDUContext*> > RecursiveImports;
|
|
|
|
typedef DUChainPointer<TopDUContext> TopDUContextPointer;
|
|
|
|
typedef KSharedPtr<Problem> ProblemPointer;
|
|
|
|
///KDevelop can unload unused top-context at any time. To prevent unloading,
|
|
///keep a ReferencedTopDUContext.
|
|
class KDEVPLATFORMLANGUAGE_EXPORT ReferencedTopDUContext {
|
|
public:
|
|
ReferencedTopDUContext(TopDUContext* context = 0);
|
|
ReferencedTopDUContext(const ReferencedTopDUContext& rhs);
|
|
~ReferencedTopDUContext();
|
|
|
|
ReferencedTopDUContext& operator=(const ReferencedTopDUContext& rhs);
|
|
|
|
inline TopDUContext* data() const {
|
|
return m_topContext;
|
|
}
|
|
|
|
inline operator TopDUContext*() const {
|
|
return m_topContext;
|
|
}
|
|
|
|
inline bool operator==(const ReferencedTopDUContext& rhs) const {
|
|
return m_topContext == rhs.m_topContext;
|
|
}
|
|
|
|
inline bool operator!=(const ReferencedTopDUContext& rhs) const {
|
|
return m_topContext != rhs.m_topContext;
|
|
}
|
|
|
|
inline TopDUContext* operator->() const {
|
|
return m_topContext;
|
|
}
|
|
|
|
inline uint hash() const {
|
|
return (uint)(((quint64)m_topContext) * 37);
|
|
}
|
|
|
|
private:
|
|
TopDUContext* m_topContext;
|
|
};
|
|
|
|
/**
|
|
* The top context in a definition-use chain for one source file.
|
|
*
|
|
* Implements SymbolTable lookups and locking for the chain.
|
|
*
|
|
* Contexts and Classes can only be found through TopDUContext if they are in the symbol table.
|
|
* @see DUContext::setInSymbolTable, Declaration::setInSymbolTable
|
|
*
|
|
* \todo move the registration with DUChain here
|
|
*
|
|
* @warning Do not delete top-contexts directly, use DUChain::removeDocumentChain instead.
|
|
*/
|
|
class KDEVPLATFORMLANGUAGE_EXPORT TopDUContext : public DUContext
|
|
{
|
|
public:
|
|
explicit TopDUContext(const IndexedString& url, const RangeInRevision& range, ParsingEnvironmentFile* file = 0);
|
|
explicit TopDUContext(TopDUContextData& data);
|
|
|
|
TopDUContext* topContext() const override;
|
|
|
|
///Returns an indexed representation of this top-context. Indexed representations stay valid even if the top-context is unloaded.
|
|
IndexedTopDUContext indexed() const;
|
|
|
|
uint ownIndex() const;
|
|
|
|
IndexedString url() const;
|
|
|
|
/**
|
|
* @see ParsingEnvironmentFile
|
|
* May return zero if no file was set.
|
|
* */
|
|
KSharedPtr<ParsingEnvironmentFile> parsingEnvironmentFile() const;
|
|
|
|
/// Returns true if this object is being deleted, otherwise false.
|
|
bool deleting() const;
|
|
|
|
/// Returns true if this object is registered in the du-chain. If it is not, all sub-objects(context, declarations, etc.) can be changed
|
|
virtual bool inDUChain() const;
|
|
/// This flag is only used by DUChain, never change it from outside.
|
|
void setInDuChain(bool);
|
|
|
|
/// Whether this top-context has a stored version on disk
|
|
bool isOnDisk() const;
|
|
|
|
/**
|
|
* Returns a list of all problems encountered while parsing this top-context.
|
|
* Does not include the problems of imported contexts.
|
|
* */
|
|
QList<ProblemPointer> problems() const;
|
|
|
|
/**
|
|
* Add a parsing-problem to this context.
|
|
*
|
|
* \note you must be holding a write lock when you access this function.
|
|
* */
|
|
void addProblem(const ProblemPointer& problem);
|
|
|
|
/**
|
|
* Clear the list of problems
|
|
*
|
|
* \note you must be holding a write lock when you access this function.
|
|
*/
|
|
void clearProblems();
|
|
|
|
/**
|
|
* Set the list of problems, replacing all existing ones.
|
|
*
|
|
* \note you must be holding a write lock when you access this function.
|
|
*/
|
|
void setProblems(const QList<ProblemPointer>& pointers);
|
|
|
|
/**
|
|
* Determine if this chain imports another chain recursively.
|
|
*
|
|
* This uses the imports-cache for speedup if it is available, thus it is not necessarily 100% correct
|
|
* if the cache is not up-to-date.
|
|
*
|
|
* \note you must be holding a read but not a write chain lock when you access this function.
|
|
*/
|
|
virtual bool imports(const DUContext* origin, const CursorInRevision& position) const;
|
|
|
|
enum {
|
|
Identity = 4
|
|
};
|
|
|
|
enum Flags {
|
|
NoFlags = 0,
|
|
///Can be used by language parts to mark contexts they currently update(for their internal usage)
|
|
UpdatingContext = 1,
|
|
///You can define own language-dependent flags behind this flag
|
|
LastFlag = 2
|
|
};
|
|
|
|
enum Features {
|
|
///Top-context features standard that can be requested from the duchain, and that are stored in the features() member.
|
|
Empty = 0, //Only the top-context structure (imports etc.) is built, but no declarations and no contexts
|
|
SimplifiedVisibleDeclarationsAndContexts = 2, //The top-context should only contain publically simplified accessible declarations and contexts, without doing type look-up,
|
|
//without extended information like function-argument declarations, etc., imported contexts can be parsed with 'Empty' features
|
|
//This flag essentially leads to a ctags-like processing level.
|
|
VisibleDeclarationsAndContexts = SimplifiedVisibleDeclarationsAndContexts + 4, //Default: The top-context should only contain publically accessible declarations and contexts
|
|
AllDeclarationsAndContexts = VisibleDeclarationsAndContexts + 8, //The top-context should also contain non-public declarations and contexts, but no uses
|
|
AllDeclarationsContextsAndUses = 16 + AllDeclarationsAndContexts, //The top-context should contain uses and all declarations + contexts
|
|
AST = 32, //Signalizes that the ast() should be filled
|
|
AllDeclarationsContextsUsesAndAST = AST | AllDeclarationsContextsAndUses, //Convenience flag, combining AST and AllDeclarationsContextsAndUses
|
|
|
|
///Additional update-flags that have a special meaning during updating, but are not set stored into a top-context
|
|
Recursive = 64, //Request the given features on all recursively imported contexts. Only the features are applied recursively (including AST)
|
|
ForceUpdate = 128, //Enforce updating the top-context
|
|
ForceUpdateRecursive = ForceUpdate | 256, //Enforce updating the top-context and all its imports
|
|
|
|
///You can define own language-dependent features behind this flag
|
|
LastFeature = 512
|
|
};
|
|
|
|
///Returns the currently active features of this top-context. The features will include AST if ast() is valid.
|
|
Features features() const;
|
|
///Set the features of this top-context. These features are ignored: AST, ForceUpdate, and ForceUpdateRecursive.
|
|
void setFeatures(Features);
|
|
|
|
/**
|
|
* Retrieves or creates a local index that is to be used for referencing the given @param declaration
|
|
* in local uses. Also registers this context as a user of the declaration.
|
|
* @param create If this is false, only already registered indices will be returned.
|
|
* If the declaration is not registered, std::numeric_limits<int>::max() is returned
|
|
*
|
|
* The duchain must be write-locked if create is true, else it must at least be read-locked.
|
|
* */
|
|
int indexForUsedDeclaration(Declaration* declaration, bool create = true);
|
|
|
|
/**
|
|
* Tries to retrieve the used declaration @param declarationIndex
|
|
* @param context must be the context where the use happened
|
|
* */
|
|
Declaration* usedDeclarationForIndex(unsigned int declarationIndex) const;
|
|
|
|
/**
|
|
* You can use this before you rebuild all uses. This does not affect any uses directly,
|
|
* it only invalidates the mapping of declarationIndices to Declarations.
|
|
*
|
|
* usedDeclarationForIndex(..) must not be called until the use has gotten a new index through
|
|
* indexForUsedDeclaration(..).
|
|
* */
|
|
void clearUsedDeclarationIndices();
|
|
|
|
|
|
/**
|
|
* Recursively deletes all contained uses, declaration-indices, etc.
|
|
*/
|
|
virtual void deleteUsesRecursively();
|
|
|
|
/**
|
|
* Use flags to mark top-contexts for special behavior. Any flags above LastFlag may be used for language-specific stuff.
|
|
* */
|
|
Flags flags() const;
|
|
void setFlags(Flags f);
|
|
|
|
/**
|
|
* Returns the AST Container, that contains the AST created during parsing.
|
|
* This is only created if you request the AST feature for parsing.
|
|
* It may be discarded at any time. Every update without the AST feature will discard it.
|
|
* The actual contents is language-specific.
|
|
*
|
|
* @todo Figure out logic to get rid of AST when it is not needed/useful
|
|
*/
|
|
KSharedPtr<IAstContainer> ast() const;
|
|
|
|
/**
|
|
* Sets the AST Container.
|
|
*/
|
|
void setAst(KSharedPtr<IAstContainer> ast);
|
|
|
|
/**
|
|
* Utility function to clear the AST Container
|
|
*/
|
|
void clearAst();
|
|
|
|
///@param temporary If this is true, importers of this context will not be notified of the new imports. This greatly increases performance while removing the context,
|
|
///but creates in inconsistent import-structure. Therefore it is only suitable for temporary imports. These imports will not be visible from contexts that import this one.
|
|
///When this top-context does not own its private data, the import is added locally only to this context, not into the shared data.
|
|
virtual void addImportedParentContext(DUContext* context, const CursorInRevision& position = CursorInRevision(), bool anonymous=false, bool temporary=false);
|
|
///Use this for mass-adding of imported contexts, it is faster than adding them individually.
|
|
///@param temporary If this is true, importers of this context will not be notified of the new imports. This greatly increases performance while removing the context,
|
|
///but creates in inconsistent import-structure. Therefore it is only suitable for temporary imports. These imports will not be visible from contexts that import this one.
|
|
///When this top-context does not own its private data, the import is added locally only to this context, not into the shared data.
|
|
virtual void addImportedParentContexts(const QList<QPair<TopDUContext*, CursorInRevision> >& contexts, bool temporary=false);
|
|
|
|
///When this top-context does not own its private data, the import is removed locally only from this context, not from the shared data.
|
|
virtual void removeImportedParentContext(DUContext* context);
|
|
///Use this for mass-removing of imported contexts, it is faster than removing them individually.
|
|
///When this top-context does not own its private data, the import is removed locally only from this context, not from the shared data.
|
|
virtual void removeImportedParentContexts(const QList<TopDUContext*>& contexts);
|
|
|
|
///When this top-context does not own its private data, only the local imports of this context are removed, not those from the shared data.
|
|
virtual void clearImportedParentContexts();
|
|
|
|
typedef Utils::StorableSet<IndexedTopDUContext, IndexedTopDUContextIndexConversion, RecursiveImportRepository, true> IndexedRecursiveImports;
|
|
|
|
virtual QVector<Import> importedParentContexts() const;
|
|
|
|
virtual QVector<DUContext*> importers() const;
|
|
|
|
///Returns all currently loade importers
|
|
virtual QList<DUContext*> loadedImporters() const;
|
|
|
|
virtual CursorInRevision importPosition(const DUContext* target) const;
|
|
|
|
///Returns the set of all recursively imported top-contexts. If import-caching is used, this returns the cached set.
|
|
///The list also contains this context itself. This set is used to determine declaration-visibility from within this top-context.
|
|
const IndexedRecursiveImports& recursiveImportIndices() const;
|
|
|
|
/**
|
|
* Updates the cache of recursive imports. When you call this, from that moment on the set returned by recursiveImportIndices() is fixed, until
|
|
* you call it again to update them. If your language has a very complex often-changing import-structure,
|
|
* like for example in the case of C++, it is recommended to call this during while parsing, instead of using
|
|
* the expensive builtin implicit mechanism.
|
|
* Note that if you use caching, you _must_ call this before you see any visibility-effect after adding imports.
|
|
*
|
|
* Using import-caching has another big advantage: A top-context can be loaded without loading all its imports.
|
|
*
|
|
* Note: This is relatively expensive since it requires loading all imported contexts.
|
|
*
|
|
* When this is called, the top-context must already be registered in the duchain.
|
|
*/
|
|
void updateImportsCache();
|
|
|
|
bool usingImportsCache() const;
|
|
|
|
virtual bool findDeclarationsInternal(const SearchItem::PtrList& identifiers, const CursorInRevision& position, const AbstractType::Ptr& dataType, DeclarationList& ret, const TopDUContext* source, SearchFlags flags, uint depth) const;
|
|
protected:
|
|
void setParsingEnvironmentFile(ParsingEnvironmentFile*);
|
|
|
|
/**
|
|
* Does the same as DUContext::updateAliases, except that it uses the symbol-store, and processes the whole identifier.
|
|
* @param canBeNamespace whether the searched identifier may be a namespace.
|
|
* If this is true, namespace-aliasing is applied to the last elements of the identifiers.
|
|
* */
|
|
template<class Acceptor>
|
|
void applyAliases( const SearchItem::PtrList& identifiers, Acceptor& accept, const CursorInRevision& position, bool canBeNamespace ) const;
|
|
|
|
protected:
|
|
virtual ~TopDUContext();
|
|
|
|
void clearFeaturesSatisfied();
|
|
void rebuildDynamicData(DUContext* parent, uint ownIndex);
|
|
//Must be called after all imported top-contexts were loaded into the du-chain
|
|
void rebuildDynamicImportStructure();
|
|
|
|
struct AliasChainElement;
|
|
struct FindDeclarationsAcceptor;
|
|
struct DeclarationChecker;
|
|
struct ApplyAliasesBuddyInfo;
|
|
|
|
template<class Acceptor>
|
|
bool applyAliases( const QualifiedIdentifier& previous, const SearchItem::Ptr& identifier, Acceptor& acceptor, const CursorInRevision& position, bool canBeNamespace, ApplyAliasesBuddyInfo* buddy, uint recursionDepth ) const;
|
|
//Same as imports, without the slow access-check, for internal usage
|
|
bool importsPrivate(const DUContext * origin, const CursorInRevision& position) const;
|
|
DUCHAIN_DECLARE_DATA(TopDUContext)
|
|
|
|
///Called by DUChain::removeDocumentChain to destroy this top-context.
|
|
void deleteSelf();
|
|
|
|
//Most of these classes need access to m_dynamicData
|
|
friend class DUChain;
|
|
friend class DUChainPrivate;
|
|
friend class TopDUContextData;
|
|
friend class TopDUContextLocalPrivate;
|
|
friend class TopDUContextDynamicData;
|
|
friend class Declaration;
|
|
friend class DUContext;
|
|
friend class Problem;
|
|
friend class IndexedDeclaration;
|
|
friend class IndexedDUContext;
|
|
friend class LocalIndexedDeclaration;
|
|
friend class LocalIndexedDUContext;
|
|
friend class LocalIndexedProblem;
|
|
friend class DeclarationId;
|
|
friend class ParsingEnvironmentFile;
|
|
|
|
TopDUContextLocalPrivate* m_local;
|
|
|
|
class TopDUContextDynamicData* m_dynamicData;
|
|
};
|
|
|
|
/**
|
|
* Returns all uses of the given declaration within this top-context and all sub-contexts
|
|
* */
|
|
KDEVPLATFORMLANGUAGE_EXPORT QList<RangeInRevision> allUses(TopDUContext* context, Declaration* declaration, bool noEmptyRanges = false);
|
|
|
|
inline uint qHash(const ReferencedTopDUContext& ctx) {
|
|
return ctx.hash();
|
|
}
|
|
|
|
}
|
|
Q_DECLARE_METATYPE(KDevelop::ReferencedTopDUContext);
|
|
|
|
#endif // KDEVPLATFORM_TOPDUCONTEXT_H
|
|
|
|
// kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on
|