forked from qt-creator/qt-creator
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 <david.schulz@qt.io>
This commit is contained in:
@@ -90,6 +90,7 @@ void ClangCodeModelPlugin::initialize()
|
||||
addTest<Tests::ClangdTestFindReferences>();
|
||||
addTest<Tests::ClangdTestFollowSymbol>();
|
||||
addTest<Tests::ClangdTestHighlighting>();
|
||||
addTest<Tests::ClangdTestIndirectChanges>();
|
||||
addTest<Tests::ClangdTestLocalReferences>();
|
||||
addTest<Tests::ClangdTestTooltips>();
|
||||
addTest<Tests::ClangFixItTest>();
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "clangeditordocumentprocessor.h"
|
||||
|
||||
#include "clangdclient.h"
|
||||
#include "clangmodelmanagersupport.h"
|
||||
|
||||
#include <cppeditor/builtincursorinfo.h>
|
||||
@@ -15,6 +16,8 @@
|
||||
#include <cppeditor/cppworkingcopy.h>
|
||||
#include <cppeditor/editordocumenthandle.h>
|
||||
|
||||
#include <languageclient/languageclientmanager.h>
|
||||
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
@@ -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<ClangdClient *>(
|
||||
LanguageClient::LanguageClientManager::clientForDocument(doc))) {
|
||||
client->documentContentsChanged(doc, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -60,5 +60,10 @@
|
||||
<file>fixits/diagnostic_comparison_fixit.cpp</file>
|
||||
<file>fixits/diagnostic_semicolon_fixit_expected.cpp</file>
|
||||
<file>fixits/diagnostic_semicolon_fixit.cpp</file>
|
||||
<file>indirect-changes/directheader.h</file>
|
||||
<file>indirect-changes/indirect-changes.pro</file>
|
||||
<file>indirect-changes/indirectheader.h</file>
|
||||
<file>indirect-changes/main.cpp</file>
|
||||
<file>indirect-changes/unrelatedheader.h</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -0,0 +1 @@
|
||||
#include "indirectheader.h"
|
@@ -0,0 +1,4 @@
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES = main.cpp
|
||||
HEADERS = directheader.h indirectheader.h unrelatedheader.h
|
@@ -0,0 +1,3 @@
|
||||
#include "directheader.h"
|
||||
|
||||
int main() {}
|
@@ -283,6 +283,7 @@ void BuiltinEditorDocumentProcessor::onParserFinished(CPlusPlus::Document::Ptr d
|
||||
if (!cppDoc->includedFiles().contains(document->filePath()))
|
||||
continue;
|
||||
cppEditorDoc->scheduleProcessDocument();
|
||||
forceUpdate(cppEditorDoc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,8 @@ private:
|
||||
|
||||
SemanticInfo::Source createSemanticInfoSource(bool force) const;
|
||||
|
||||
virtual void forceUpdate(TextEditor::TextDocument *) {}
|
||||
|
||||
private:
|
||||
BuiltinEditorDocumentParser::Ptr m_parser;
|
||||
QFuture<void> m_parserFuture;
|
||||
|
Reference in New Issue
Block a user