File indexing completed on 2024-05-12 04:38:03
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #ifndef KDEVPLATFORM_PARSINGENVIRONMENT_H 0008 #define KDEVPLATFORM_PARSINGENVIRONMENT_H 0009 0010 #include <serialization/indexedstring.h> 0011 0012 #include <language/languageexport.h> 0013 #include "duchainbase.h" 0014 #include "topducontext.h" 0015 #include <language/editor/modificationrevisionset.h> 0016 0017 namespace KDevelop { 0018 /** 0019 * Just an enumeration of a few parsing-environment types. 0020 * Enumerate a few possible future parsing-environment types. 0021 * A parsing-environment could also have a type not in this enumeration, 0022 * the only important thing is that it's unique for the type. 0023 * 0024 * The type is needed to match ParsingEnvironment, ParsingEnvironmentFile, and ParsingEnvironmentManager together so they fit. 0025 * For example the c++-versions would have their specific type. 0026 * 0027 * The type must be unique(no other language may have the same type), 0028 * and the type must be persistent.(it must be same after restarting kdevelop) 0029 * 0030 * */ 0031 enum ParsingEnvironmentType 0032 { 0033 StandardParsingEnvironment /**< a basic standard parsing environment */, 0034 CppParsingEnvironment /**< a C++ parsing environment */, 0035 PythonParsingEnvironment /**< a python parsing environment */, 0036 CMakeParsingEnvironment /**< a CMake parsing environment */, 0037 CSharpParsingEnvironment /**< a CSharp parsing environment */, 0038 JavaParsingEnvironment /**< a JAva parsing environment */, 0039 RubyParsingEnvironment /**< a Ruby parsing environment */, 0040 PhpParsingEnvironment /**< a PHP parsing environment */ 0041 }; 0042 0043 ///Internal 0044 struct StaticParsingEnvironmentData 0045 { 0046 TopDUContext::IndexedRecursiveImports simplifiedVisibleDeclarationsSatisfied; 0047 TopDUContext::IndexedRecursiveImports visibleDeclarationsSatisfied; 0048 TopDUContext::IndexedRecursiveImports allDeclarationsSatisfied; 0049 TopDUContext::IndexedRecursiveImports allDeclarationsAndUsesSatisfied; 0050 TopDUContext::IndexedRecursiveImports ASTSatisfied; 0051 }; 0052 0053 /** 0054 * Use this as base-class to define new parsing-environments. 0055 * 0056 * Parsing-environments are needed for languages that create different 0057 * parsing-results depending on the environment. For example in c++, 0058 * the environment mainly consists of macros. The include-path can 0059 * be considered to be a part of the parsing-environment too, because 0060 * different files may be included using another include-path. 0061 * 0062 * The classes have to use the serialization scheme from the duchain. 0063 * Each class must be registered using REGISTER_DUCHAIN_ITEM with a unique id. 0064 * 0065 * \warning Access to this class must be serialized through du-chain locking 0066 * */ 0067 class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironment 0068 { 0069 public: 0070 ParsingEnvironment(); 0071 virtual ~ParsingEnvironment(); 0072 0073 ///@see ParsingEnvironmentType 0074 virtual int type() const; 0075 }; 0076 0077 ///The data class used for storing. Use this as base-class of your custom data classes for classes derived from 0078 ///ParsingEnvironmentFile 0079 class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironmentFileData 0080 : public DUChainBaseData 0081 { 0082 public: 0083 bool m_isProxyContext = false; 0084 TopDUContext::Features m_features = TopDUContext::VisibleDeclarationsAndContexts; 0085 KDevelop::ModificationRevision m_modificationTime; 0086 ModificationRevisionSet m_allModificationRevisions; 0087 KDevelop::IndexedString m_url; 0088 KDevelop::IndexedTopDUContext m_topContext; 0089 IndexedString m_language; 0090 0091 ///If this is not empty, it means that the cache is used instead of the implicit structure. 0092 TopDUContext::IndexedRecursiveImports m_importsCache; 0093 }; 0094 0095 using ParsingEnvironmentFilePointer = QExplicitlySharedDataPointer<ParsingEnvironmentFile>; 0096 0097 /** 0098 * This represents all information about a specific parsed file that is needed 0099 * to match the file to a parsing-environment. 0100 * 0101 * It is QSharedData because it is embedded into top-du-contexts and at the same time 0102 * references may be held by ParsingEnvironmentManager. 0103 * 0104 * \warning Access to this class must be serialized through du-chain locking 0105 * */ 0106 class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironmentFile 0107 : public DUChainBase 0108 , public QSharedData 0109 { 0110 public: 0111 ~ParsingEnvironmentFile() override; 0112 explicit ParsingEnvironmentFile(const IndexedString& url); 0113 ParsingEnvironmentFile(ParsingEnvironmentFileData& data, const IndexedString& url); 0114 explicit ParsingEnvironmentFile(ParsingEnvironmentFileData& data); 0115 0116 ParsingEnvironmentFile& operator=(const ParsingEnvironmentFile& rhs) = delete; 0117 0118 ///@see ParsingEnvironmentType 0119 virtual int type() const; 0120 0121 ///Should return whether this file matches into the given environment. The default-implementation always returns true. 0122 virtual bool matchEnvironment(const ParsingEnvironment* environment) const; 0123 0124 ///Convenience-function that returns the top-context 0125 TopDUContext* topContext() const override; 0126 0127 KDevelop::IndexedTopDUContext indexedTopContext() const; 0128 0129 KDevelop::IndexedString url() const override; 0130 0131 ///Can additionally use language-specific information to decide whether the top-context that has this data attached needs to be reparsed. 0132 ///The standard-implementation checks the modification-time of this file stored using setModificationRevision, and all other modification-times 0133 ///stored with addModificationRevision(..). 0134 virtual bool needsUpdate(const ParsingEnvironment* environment = nullptr) const; 0135 0136 /** 0137 * A language-specific flag used by C++ to mark one context as a proxy of another. 0138 * If this flag is set on a context, the first imported context should be used for any computations 0139 * like searches, listing, etc. instead of using this context. 0140 * 0141 * The problems should be stored within the proxy-contexts, and optionally there may be 0142 * any count of imported proxy-contexts imported behind the content-context(This can be used for tracking problems) 0143 * 0144 * Note: This flag does not directly change the behavior of the language-independent du-chain. 0145 */ 0146 bool isProxyContext() const; 0147 0148 ///Sets the flag 0149 void setIsProxyContext(bool); 0150 0151 ///The features of the attached top-context. They are automatically replicated here by the top-context, so they 0152 ///are accessible even without the top-context loaded. 0153 TopDUContext::Features features() const; 0154 0155 ///Returns the parsing-environment information of all importers of the coupled TopDUContext. This is more efficient than 0156 ///loading the top-context and finding out, because when a top-context is loaded, also all its recursive imports are loaded 0157 QList<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> importers() const; 0158 0159 ///Returns the parsing-environment information of all imports of the coupled TopDUContext. This is more efficient than 0160 ///loading the top-context and finding out 0161 QList<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> imports() const; 0162 0163 ///Returns true if this top-context satisfies at least the given minimum features. 0164 ///If there is static minimum features set up in ParseJob, this also checks against those. 0165 ///Features like "ForceUpdate" are treated specially. 0166 ///@p minimumFeatures The features that must be satisfied. May be an arbitrary combination of features. 0167 bool featuresSatisfied(TopDUContext::Features minimumFeatures) const; 0168 0169 ///Should return a correctly filled ModificationRevision of the source it was created from. 0170 void setModificationRevision(const KDevelop::ModificationRevision& rev); 0171 0172 KDevelop::ModificationRevision modificationRevision() const; 0173 0174 ///Clears the modification times of all dependencies 0175 void clearModificationRevisions(); 0176 0177 void addModificationRevision(const IndexedString& url, const ModificationRevision& revision); 0178 0179 const ModificationRevisionSet& allModificationRevisions() const; 0180 0181 void addModificationRevisions(const ModificationRevisionSet&); 0182 0183 /// Returns the language for this top-context. If the string is empty, the language is unknown. 0184 IndexedString language() const; 0185 0186 /// If the recursive imports of the attached TopDUContext are cached, this returns the cached imports. 0187 /// This works without loading the top-context. 0188 const TopDUContext::IndexedRecursiveImports& importsCache() const; 0189 0190 ///Sets the language for this top-context. Each top-context should get the language assigned that can by used 0191 ///in order to load the language using ILanguageController. 0192 void setLanguage(const IndexedString& language); 0193 0194 enum { 0195 Identity = 11 0196 }; 0197 0198 DUCHAIN_DECLARE_DATA(ParsingEnvironmentFile) 0199 0200 private: 0201 friend class TopDUContext; 0202 friend class DUChainPrivate; 0203 static StaticParsingEnvironmentData* m_staticData; 0204 ///The features are managed by TopDUContext. They are set to TopDUContext::Empty when the top-context is persistently destroyed, 0205 ///so the persistent feature-satisfaction cache can be cleared. 0206 void setFeatures(TopDUContext::Features); 0207 void setTopContext(KDevelop::IndexedTopDUContext context); 0208 bool featuresMatch(KDevelop::TopDUContext::Features minimumFeatures, 0209 QSet<const KDevelop::ParsingEnvironmentFile*>& checked) const; 0210 void setImportsCache(const TopDUContext::IndexedRecursiveImports&); 0211 }; 0212 0213 // TODO: why is this needed/what is it supposed to print? just the pointer value? 0214 inline QDebug operator<<(QDebug s, const QExplicitlySharedDataPointer<ParsingEnvironmentFile>& p) 0215 { 0216 s.nospace() << p->url(); 0217 return s.space(); 0218 } 0219 } 0220 0221 #endif