From b33b99e2d9e4c343f7427bcf1ccdf652e7575557 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 22 Aug 2023 14:10:22 +0200 Subject: [PATCH] ClangCodeModel: Take changes from header files into account immediately ... in the dependent sources. That's also how the built-in code model behaves, but clangd itself only does this when a document is saved. Change-Id: I52d6badb0b7f063e5924c05dbf83a6e9849c9f6f Reviewed-by: David Schulz --- .../clangcodemodel/clangcodemodelplugin.cpp | 1 + .../clangeditordocumentprocessor.cpp | 11 +++++ .../clangeditordocumentprocessor.h | 3 +- .../clangcodemodel/test/clangdtests.cpp | 41 +++++++++++++++++++ src/plugins/clangcodemodel/test/clangdtests.h | 11 +++++ .../test/data/clangtestdata.qrc | 5 +++ .../test/data/indirect-changes/directheader.h | 1 + .../indirect-changes/indirect-changes.pro | 4 ++ .../data/indirect-changes/indirectheader.h | 0 .../test/data/indirect-changes/main.cpp | 3 ++ .../data/indirect-changes/unrelatedheader.h | 0 .../builtineditordocumentprocessor.cpp | 1 + .../builtineditordocumentprocessor.h | 2 + 13 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/plugins/clangcodemodel/test/data/indirect-changes/directheader.h create mode 100644 src/plugins/clangcodemodel/test/data/indirect-changes/indirect-changes.pro create mode 100644 src/plugins/clangcodemodel/test/data/indirect-changes/indirectheader.h create mode 100644 src/plugins/clangcodemodel/test/data/indirect-changes/main.cpp create mode 100644 src/plugins/clangcodemodel/test/data/indirect-changes/unrelatedheader.h diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 62dae070400..ac194abfbf9 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -90,6 +90,7 @@ void ClangCodeModelPlugin::initialize() addTest(); addTest(); addTest(); + addTest(); addTest(); addTest(); addTest(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index d7c94d81247..83667dde05e 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -3,6 +3,7 @@ #include "clangeditordocumentprocessor.h" +#include "clangdclient.h" #include "clangmodelmanagersupport.h" #include @@ -15,6 +16,8 @@ #include #include +#include + #include #include #include @@ -77,5 +80,13 @@ ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const Utils::Fil CppEditor::CppModelManager::cppEditorDocumentProcessor(filePath)); } +void ClangEditorDocumentProcessor::forceUpdate(TextEditor::TextDocument *doc) +{ + if (const auto client = qobject_cast( + LanguageClient::LanguageClientManager::clientForDocument(doc))) { + client->documentContentsChanged(doc, 0, 0, 0); + } +} + } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index bd151554003..fe2bc6a0166 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -22,7 +22,6 @@ public: void setParserConfig(const CppEditor::BaseEditorDocumentParser::Configuration &config) override; CppEditor::BaseEditorDocumentParser::Configuration parserConfig(); -public: static ClangEditorDocumentProcessor *get(const Utils::FilePath &filePath); signals: @@ -30,6 +29,8 @@ signals: const CppEditor::BaseEditorDocumentParser::Configuration &config); private: + void forceUpdate(TextEditor::TextDocument *doc) override; + TextEditor::TextDocument &m_document; }; diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 190c0b55c76..54c9bfa7c1d 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -2061,6 +2061,47 @@ void ClangdTestExternalChanges::test() QVERIFY(waitForSignalOrTimeout(newClient, &ClangdClient::textMarkCreated, timeOutInMs())); } +ClangdTestIndirectChanges::ClangdTestIndirectChanges() +{ + setProjectFileName("indirect-changes.pro"); + setSourceFileNames({"main.cpp", "directheader.h", "indirectheader.h", "unrelatedheader.h"}); +} + +void ClangdTestIndirectChanges::test() +{ + // Initially, everything is fine. + const TextDocument * const src = document("main.cpp"); + QVERIFY(src); + QVERIFY(src->marks().isEmpty()); + + // Write into an indirectly included header file. Our source file should have diagnostics now. + const TextDocument * const indirectHeader = document("indirectheader.h"); + QVERIFY(indirectHeader); + QTextCursor cursor(indirectHeader->document()); + cursor.insertText("blubb"); + while (src->marks().isEmpty()) + QVERIFY(waitForSignalOrTimeout(client(), &ClangdClient::textMarkCreated, timeOutInMs())); + + // Remove the inserted text again; the diagnostics should disappear. + cursor.document()->undo(); + QVERIFY(cursor.document()->toPlainText().isEmpty()); + while (!src->marks().isEmpty()) { + QVERIFY(waitForSignalOrTimeout(client(), &ClangdClient::highlightingResultsReady, + timeOutInMs())); + } + + // Now write into a header file that is not included anywhere. + // We expect diagnostics only for the header itself. + const TextDocument * const unrelatedHeader = document("unrelatedheader.h"); + QVERIFY(indirectHeader); + QTextCursor cursor2(unrelatedHeader->document()); + cursor2.insertText("blubb"); + while (waitForSignalOrTimeout(client(), &ClangdClient::textMarkCreated, timeOutInMs())) + ; + QVERIFY(!unrelatedHeader->marks().isEmpty()); + QVERIFY(src->marks().isEmpty()); +} + } // namespace Tests } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/test/clangdtests.h b/src/plugins/clangcodemodel/test/clangdtests.h index 92bf4efe90c..9d6e42d3a9e 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.h +++ b/src/plugins/clangcodemodel/test/clangdtests.h @@ -188,6 +188,17 @@ private slots: void test(); }; +class ClangdTestIndirectChanges : public ClangdTest +{ + Q_OBJECT + +public: + ClangdTestIndirectChanges(); + +private slots: + void test(); +}; + } // namespace Tests } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc index 1ee4bdee92c..f61e3f0633b 100644 --- a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc +++ b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc @@ -60,5 +60,10 @@ fixits/diagnostic_comparison_fixit.cpp fixits/diagnostic_semicolon_fixit_expected.cpp fixits/diagnostic_semicolon_fixit.cpp + indirect-changes/directheader.h + indirect-changes/indirect-changes.pro + indirect-changes/indirectheader.h + indirect-changes/main.cpp + indirect-changes/unrelatedheader.h diff --git a/src/plugins/clangcodemodel/test/data/indirect-changes/directheader.h b/src/plugins/clangcodemodel/test/data/indirect-changes/directheader.h new file mode 100644 index 00000000000..9ab7726e456 --- /dev/null +++ b/src/plugins/clangcodemodel/test/data/indirect-changes/directheader.h @@ -0,0 +1 @@ +#include "indirectheader.h" diff --git a/src/plugins/clangcodemodel/test/data/indirect-changes/indirect-changes.pro b/src/plugins/clangcodemodel/test/data/indirect-changes/indirect-changes.pro new file mode 100644 index 00000000000..b1648532ca6 --- /dev/null +++ b/src/plugins/clangcodemodel/test/data/indirect-changes/indirect-changes.pro @@ -0,0 +1,4 @@ +CONFIG -= qt + +SOURCES = main.cpp +HEADERS = directheader.h indirectheader.h unrelatedheader.h diff --git a/src/plugins/clangcodemodel/test/data/indirect-changes/indirectheader.h b/src/plugins/clangcodemodel/test/data/indirect-changes/indirectheader.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/plugins/clangcodemodel/test/data/indirect-changes/main.cpp b/src/plugins/clangcodemodel/test/data/indirect-changes/main.cpp new file mode 100644 index 00000000000..63ae802b071 --- /dev/null +++ b/src/plugins/clangcodemodel/test/data/indirect-changes/main.cpp @@ -0,0 +1,3 @@ +#include "directheader.h" + +int main() {} diff --git a/src/plugins/clangcodemodel/test/data/indirect-changes/unrelatedheader.h b/src/plugins/clangcodemodel/test/data/indirect-changes/unrelatedheader.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/plugins/cppeditor/builtineditordocumentprocessor.cpp b/src/plugins/cppeditor/builtineditordocumentprocessor.cpp index cb94e84a67b..94f86815f26 100644 --- a/src/plugins/cppeditor/builtineditordocumentprocessor.cpp +++ b/src/plugins/cppeditor/builtineditordocumentprocessor.cpp @@ -283,6 +283,7 @@ void BuiltinEditorDocumentProcessor::onParserFinished(CPlusPlus::Document::Ptr d if (!cppDoc->includedFiles().contains(document->filePath())) continue; cppEditorDoc->scheduleProcessDocument(); + forceUpdate(cppEditorDoc); } } diff --git a/src/plugins/cppeditor/builtineditordocumentprocessor.h b/src/plugins/cppeditor/builtineditordocumentprocessor.h index a061336587e..b33951aabe1 100644 --- a/src/plugins/cppeditor/builtineditordocumentprocessor.h +++ b/src/plugins/cppeditor/builtineditordocumentprocessor.h @@ -43,6 +43,8 @@ private: SemanticInfo::Source createSemanticInfoSource(bool force) const; + virtual void forceUpdate(TextEditor::TextDocument *) {} + private: BuiltinEditorDocumentParser::Ptr m_parser; QFuture m_parserFuture;