From f18bc981d514e469795223fa37c041d2e8a41599 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 15 Sep 2015 16:24:52 +0200 Subject: [PATCH] Clang: Fix reloading documents Fix the following use case: * Open foo.h * Open foo.cpp * Change both files externally (e.g. git checkout) e.g. by adding a function (declaration + definition) * Confirm the reload dialog in Qt Creator * The added function in foo.cpp gets a diagnostic that it's out of line although foo.h is also reloaded. TextDocument::contentsChangedWithPosition() is also emitted during a reload. However, the revision of the document at that point is not yet updated. This led to an out-dated copy of the unsaved files in the clang backend. Change-Id: I70580d32bb7a34dc43356dc05019cc18addf950e Reviewed-by: Marco Bubke --- .../clangmodelmanagersupport.cpp | 50 ++++++++++++++++--- .../clangcodemodel/clangmodelmanagersupport.h | 5 ++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index eb29947d7ae..95a2e51065c 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -116,25 +116,43 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument) { // Handle externally changed documents + connect(textDocument, &Core::IDocument::aboutToReload, + this, &ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit, + Qt::UniqueConnection); connect(textDocument, &Core::IDocument::reloadFinished, this, &ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit, Qt::UniqueConnection); // Handle changes from e.g. refactoring actions - connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition, - this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit, - Qt::UniqueConnection); + connectToTextDocumentContentsChangedForTranslationUnit(textDocument); } void ModelManagerSupportClang::connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument) { // Handle externally changed documents + connect(textDocument, &Core::IDocument::aboutToReload, + this, &ModelManagerSupportClang::onCppDocumentAboutToReloadOnUnsavedFile, + Qt::UniqueConnection); connect(textDocument, &Core::IDocument::reloadFinished, this, &ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile, Qt::UniqueConnection); // Handle changes from e.g. refactoring actions - connect(textDocument, &TextEditor::TextDocument::contentsChanged, + connectToTextDocumentContentsChangedForUnsavedFile(textDocument); +} + +void ModelManagerSupportClang::connectToTextDocumentContentsChangedForTranslationUnit( + TextEditor::TextDocument *textDocument) +{ + connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition, + this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit, + Qt::UniqueConnection); +} + +void ModelManagerSupportClang::connectToTextDocumentContentsChangedForUnsavedFile( + TextEditor::TextDocument *textDocument) +{ + connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition, this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile, Qt::UniqueConnection); } @@ -168,11 +186,19 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) } } +void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit() +{ + TextEditor::TextDocument *textDocument = qobject_cast(sender()); + disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition, + this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit); +} + void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool success) { if (success) { - Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator.requestDiagnostics(document); + TextEditor::TextDocument *textDocument = qobject_cast(sender()); + connectToTextDocumentContentsChangedForTranslationUnit(textDocument); + m_ipcCommunicator.requestDiagnostics(textDocument); } } @@ -187,11 +213,19 @@ void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int m_ipcCommunicator.updateTranslationUnitIfNotCurrentDocument(document); } +void ModelManagerSupportClang::onCppDocumentAboutToReloadOnUnsavedFile() +{ + TextEditor::TextDocument *textDocument = qobject_cast(sender()); + disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition, + this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile); +} + void ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile(bool success) { if (success) { - Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator.updateUnsavedFile(document); + TextEditor::TextDocument *textDocument = qobject_cast(sender()); + connectToTextDocumentContentsChangedForUnsavedFile(textDocument); + m_ipcCommunicator.updateUnsavedFile(textDocument); } } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index b433f4c0ecf..54478a6ee53 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -72,10 +72,12 @@ public: private: void onEditorOpened(Core::IEditor *editor); void onCurrentEditorChanged(Core::IEditor *newCurrent); + void onCppDocumentAboutToReloadOnTranslationUnit(); void onCppDocumentReloadFinishedOnTranslationUnit(bool success); void onCppDocumentContentsChangedOnTranslationUnit(int position, int charsRemoved, int charsAdded); + void onCppDocumentAboutToReloadOnUnsavedFile(); void onCppDocumentReloadFinishedOnUnsavedFile(bool success); void onCppDocumentContentsChangedOnUnsavedFile(); @@ -93,6 +95,9 @@ private: void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument); void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument); + void connectToTextDocumentContentsChangedForTranslationUnit( + TextEditor::TextDocument *textDocument); + void connectToTextDocumentContentsChangedForUnsavedFile(TextEditor::TextDocument *textDocument); void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget); private: