1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Creator. 7 ** 8 ** Commercial License Usage 9 ** Licensees holding valid commercial Qt licenses may use this file in 10 ** accordance with the commercial license agreement provided with the 11 ** Software or, alternatively, in accordance with the terms contained in 12 ** a written agreement between you and The Qt Company. For licensing terms 13 ** and conditions see https://www.qt.io/terms-conditions. For further 14 ** information use the contact form at https://www.qt.io/contact-us. 15 ** 16 ** GNU General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU 18 ** General Public License version 3 as published by the Free Software 19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 20 ** included in the packaging of this file. Please review the following 21 ** information to ensure the GNU General Public License requirements will 22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 23 ** 24 ****************************************************************************/ 25 26 #pragma once 27 28 #include "cpptools_global.h" 29 30 #include "cppmodelmanagerinterface.h" 31 #include "refactoringengineinterface.h" 32 #include "projectinfo.h" 33 #include "projectpart.h" 34 #include <projectexplorer/headerpath.h> 35 36 #include <cplusplus/cppmodelmanagerbase.h> 37 #include <coreplugin/find/ifindfilter.h> 38 #include <coreplugin/locator/ilocatorfilter.h> 39 40 #include <QFuture> 41 #include <QObject> 42 #include <QStringList> 43 44 namespace Core { 45 class IDocument; 46 class IEditor; 47 } 48 namespace CPlusPlus { class LookupContext; } 49 namespace ProjectExplorer { class Project; } 50 namespace TextEditor { 51 class BaseHoverHandler; 52 class TextDocument; 53 } // namespace TextEditor 54 55 namespace CppTools { 56 57 class AbstractEditorSupport; 58 class AbstractOverviewModel; 59 class BaseEditorDocumentProcessor; 60 class CppCompletionAssistProvider; 61 class CppEditorDocumentHandle; 62 class CppIndexingSupport; 63 class CppLocatorData; 64 class ModelManagerSupportProvider; 65 class FollowSymbolInterface; 66 class SymbolFinder; 67 class WorkingCopy; 68 69 namespace Internal { 70 class CppSourceProcessor; 71 class CppModelManagerPrivate; 72 class CppToolsPluginPrivate; 73 } 74 75 namespace Tests { 76 class ModelManagerTestHelper; 77 } 78 79 enum class RefactoringEngineType : int 80 { 81 BuiltIn = 0, 82 ClangCodeModel = 1, 83 ClangRefactoring = 2 84 }; 85 86 class CPPTOOLS_EXPORT CppModelManager final : public CPlusPlus::CppModelManagerBase, 87 public RefactoringEngineInterface, 88 public CppModelManagerInterface 89 { 90 Q_OBJECT 91 92 private: 93 friend class Internal::CppToolsPluginPrivate; 94 CppModelManager(); 95 ~CppModelManager() override; 96 97 public: 98 using Document = CPlusPlus::Document; 99 100 static CppModelManager *instance(); 101 102 void registerJsExtension(); 103 104 // Documented in source file. 105 enum ProgressNotificationMode { 106 ForcedProgressNotification, 107 ReservedProgressNotification 108 }; 109 110 QFuture<void> updateSourceFiles(const QSet<QString> &sourceFiles, 111 ProgressNotificationMode mode = ReservedProgressNotification); 112 void updateCppEditorDocuments(bool projectsUpdated = false) const; 113 WorkingCopy workingCopy() const; 114 QByteArray codeModelConfiguration() const; 115 CppLocatorData *locatorData() const; 116 117 QList<ProjectInfo> projectInfos() const; 118 ProjectInfo projectInfo(ProjectExplorer::Project *project) const; 119 QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo, 120 const QSet<QString> &additionalFiles = {}); 121 122 /// \return The project part with the given project file 123 ProjectPart::Ptr projectPartForId(const QString &projectPartId) const override; 124 /// \return All project parts that mention the given file name as one of the sources/headers. 125 QList<ProjectPart::Ptr> projectPart(const Utils::FilePath &fileName) const; projectPart(const QString & fileName)126 QList<ProjectPart::Ptr> projectPart(const QString &fileName) const 127 { return projectPart(Utils::FilePath::fromString(fileName)); } 128 /// This is a fall-back function: find all files that includes the file directly or indirectly, 129 /// and return its \c ProjectPart list for use with this file. 130 QList<ProjectPart::Ptr> projectPartFromDependencies(const Utils::FilePath &fileName) const; 131 /// \return A synthetic \c ProjectPart which consists of all defines/includes/frameworks from 132 /// all loaded projects. 133 ProjectPart::Ptr fallbackProjectPart(); 134 135 CPlusPlus::Snapshot snapshot() const override; 136 Document::Ptr document(const QString &fileName) const; 137 bool replaceDocument(Document::Ptr newDoc); 138 139 void emitDocumentUpdated(Document::Ptr doc); 140 void emitAbstractEditorSupportContentsUpdated(const QString &filePath, 141 const QString &sourcePath, 142 const QByteArray &contents); 143 void emitAbstractEditorSupportRemoved(const QString &filePath); 144 145 static bool isCppEditor(Core::IEditor *editor); 146 static bool supportsOutline(const TextEditor::TextDocument *document); 147 bool isClangCodeModelActive() const; 148 149 QSet<AbstractEditorSupport*> abstractEditorSupports() const; 150 void addExtraEditorSupport(AbstractEditorSupport *editorSupport); 151 void removeExtraEditorSupport(AbstractEditorSupport *editorSupport); 152 153 QList<CppEditorDocumentHandle *> cppEditorDocuments() const; 154 CppEditorDocumentHandle *cppEditorDocument(const QString &filePath) const; 155 void registerCppEditorDocument(CppEditorDocumentHandle *cppEditorDocument); 156 void unregisterCppEditorDocument(const QString &filePath); 157 158 QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); 159 160 void startLocalRenaming(const CursorInEditor &data, 161 CppTools::ProjectPart *projectPart, 162 RenameCallback &&renameSymbolsCallback) final; 163 void globalRename(const CursorInEditor &data, UsagesCallback &&renameCallback, 164 const QString &replacement) final; 165 void findUsages(const CppTools::CursorInEditor &data, 166 UsagesCallback &&showUsagesCallback) const final; 167 void globalFollowSymbol(const CursorInEditor &data, 168 Utils::ProcessLinkCallback &&processLinkCallback, 169 const CPlusPlus::Snapshot &snapshot, 170 const Document::Ptr &documentFromSemanticInfo, 171 SymbolFinder *symbolFinder, 172 bool inNextSplit) const final; 173 174 bool positionRequiresSignal(const QString &filePath, const QByteArray &content, 175 int position) const; 176 177 void renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, 178 const QString &replacement = QString()); 179 void findUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); 180 181 void findMacroUsages(const CPlusPlus::Macro ¯o); 182 void renameMacroUsages(const CPlusPlus::Macro ¯o, const QString &replacement); 183 184 void finishedRefreshingSourceFiles(const QSet<QString> &files); 185 186 void activateClangCodeModel(ModelManagerSupportProvider *modelManagerSupportProvider); 187 CppCompletionAssistProvider *completionAssistProvider() const; 188 CppCompletionAssistProvider *functionHintAssistProvider() const; 189 BaseEditorDocumentProcessor *createEditorDocumentProcessor( 190 TextEditor::TextDocument *baseTextDocument) const; 191 TextEditor::BaseHoverHandler *createHoverHandler() const; 192 FollowSymbolInterface &followSymbolInterface() const; 193 std::unique_ptr<AbstractOverviewModel> createOverviewModel() const; 194 195 void setIndexingSupport(CppIndexingSupport *indexingSupport); 196 CppIndexingSupport *indexingSupport(); 197 198 QStringList projectFiles(); 199 200 ProjectExplorer::HeaderPaths headerPaths(); 201 202 // Use this *only* for auto tests 203 void setHeaderPaths(const ProjectExplorer::HeaderPaths &headerPaths); 204 205 ProjectExplorer::Macros definedMacros(); 206 207 void enableGarbageCollector(bool enable); 208 209 SymbolFinder *symbolFinder(); 210 211 QThreadPool *sharedThreadPool(); 212 213 static QSet<QString> timeStampModifiedFiles(const QList<Document::Ptr> &documentsToCheck); 214 215 static Internal::CppSourceProcessor *createSourceProcessor(); 216 static QString configurationFileName(); 217 static QString editorConfigurationFileName(); 218 219 static void addRefactoringEngine(RefactoringEngineType type, 220 RefactoringEngineInterface *refactoringEngine); 221 static void removeRefactoringEngine(RefactoringEngineType type); 222 static RefactoringEngineInterface *builtinRefactoringEngine(); 223 static FollowSymbolInterface &builtinFollowSymbol(); 224 225 void setLocatorFilter(std::unique_ptr<Core::ILocatorFilter> &&filter); 226 void setClassesFilter(std::unique_ptr<Core::ILocatorFilter> &&filter); 227 void setIncludesFilter(std::unique_ptr<Core::ILocatorFilter> &&filter); 228 void setFunctionsFilter(std::unique_ptr<Core::ILocatorFilter> &&filter); 229 void setSymbolsFindFilter(std::unique_ptr<Core::IFindFilter> &&filter); 230 void setCurrentDocumentFilter(std::unique_ptr<Core::ILocatorFilter> &&filter); 231 232 Core::ILocatorFilter *locatorFilter() const; 233 Core::ILocatorFilter *classesFilter() const; 234 Core::ILocatorFilter *includesFilter() const; 235 Core::ILocatorFilter *functionsFilter() const; 236 Core::IFindFilter *symbolsFindFilter() const; 237 Core::ILocatorFilter *currentDocumentFilter() const; 238 239 /* 240 * try to find build system target that depends on the given file - if the file is no header 241 * try to find the corresponding header and use this instead to find the respective target 242 */ 243 QSet<QString> dependingInternalTargets(const Utils::FilePath &file) const; 244 245 QSet<QString> internalTargets(const Utils::FilePath &filePath) const; 246 247 void renameIncludes(const Utils::FilePath &oldFilePath, const Utils::FilePath &newFilePath); 248 249 // for VcsBaseSubmitEditor 250 Q_INVOKABLE QSet<QString> symbolsInFiles(const QSet<Utils::FilePath> &files) const; 251 252 signals: 253 /// Project data might be locked while this is emitted. 254 void aboutToRemoveFiles(const QStringList &files); 255 256 void documentUpdated(CPlusPlus::Document::Ptr doc); 257 void sourceFilesRefreshed(const QSet<QString> &files); 258 259 void projectPartsUpdated(ProjectExplorer::Project *project); 260 void projectPartsRemoved(const QStringList &projectPartIds); 261 262 void globalSnapshotChanged(); 263 264 void gcFinished(); // Needed for tests. 265 266 void abstractEditorSupportContentsUpdated(const QString &filePath, 267 const QString &sourcePath, 268 const QByteArray &contents); 269 void abstractEditorSupportRemoved(const QString &filePath); 270 271 public slots: 272 void updateModifiedSourceFiles(); 273 void GC(); 274 275 private: 276 // This should be executed in the GUI thread. 277 friend class Tests::ModelManagerTestHelper; 278 void onAboutToLoadSession(); 279 void onProjectAdded(ProjectExplorer::Project *project); 280 void onAboutToRemoveProject(ProjectExplorer::Project *project); 281 void onActiveProjectChanged(ProjectExplorer::Project *project); 282 void onSourceFilesRefreshed() const; 283 void onCurrentEditorChanged(Core::IEditor *editor); 284 void onCoreAboutToClose(); 285 void setupFallbackProjectPart(); 286 287 void initializeBuiltinModelManagerSupport(); 288 void delayedGC(); 289 void recalculateProjectPartMappings(); 290 void watchForCanceledProjectIndexer(const QFuture<void> &future, 291 ProjectExplorer::Project *project); 292 293 void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot); 294 void removeFilesFromSnapshot(const QSet<QString> &removedFiles); 295 void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo); 296 297 WorkingCopy buildWorkingCopyList(); 298 299 void ensureUpdated(); 300 QStringList internalProjectFiles() const; 301 ProjectExplorer::HeaderPaths internalHeaderPaths() const; 302 ProjectExplorer::Macros internalDefinedMacros() const; 303 304 void dumpModelManagerConfiguration(const QString &logFileId); 305 void initCppTools(); 306 307 private: 308 Internal::CppModelManagerPrivate *d; 309 }; 310 311 } // namespace CppTools 312