ClangCodeModel: Handle UI header updates with clangd

We need to manually refresh the documents that include the generated
header, as clangd does not know about it.

Change-Id: I8c4303ac029bbb56c01aa99b7950dcc651701678
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-11-12 11:33:07 +01:00
parent d2c378ef75
commit 95e8afabba
3 changed files with 28 additions and 0 deletions

View File

@@ -1539,6 +1539,30 @@ QString ClangdClient::displayNameFromDocumentSymbol(SymbolKind kind, const QStri
}
}
// Force re-parse of all open files that include the changed ui header.
// Otherwise, we potentially have stale diagnostics.
void ClangdClient::handleUiHeaderChange(const QString &fileName)
{
const QRegularExpression includeRex("#include.*" + fileName + R"([>"])");
const QVector<Client *> &allClients = LanguageClientManager::clients();
for (Client * const client : allClients) {
if (!client->reachable() || !qobject_cast<ClangdClient *>(client))
continue;
for (IDocument * const doc : DocumentModel::openedDocuments()) {
const auto textDoc = qobject_cast<TextDocument *>(doc);
if (!textDoc || !client->documentOpen(textDoc))
continue;
const QTextCursor includePos = textDoc->document()->find(includeRex);
if (includePos.isNull())
continue;
qCDebug(clangdLog) << "updating" << textDoc->filePath() << "due to change in UI header"
<< fileName;
client->documentContentsChanged(textDoc, 0, 0, 0);
break; // No sane project includes the same UI header twice.
}
}
}
void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations)
{
const auto refData = runningFindUsages.find(key);

View File

@@ -86,6 +86,8 @@ public:
static QString displayNameFromDocumentSymbol(LanguageServerProtocol::SymbolKind kind,
const QString &name, const QString &detail);
static void handleUiHeaderChange(const QString &fileName);
signals:
void indexingFinished();
void foundReferences(const QList<Core::SearchResultItem> &items);

View File

@@ -608,6 +608,7 @@ void ClangModelManagerSupport::onAbstractEditorSupportContentsUpdated(const QStr
const QString mappedPath = m_uiHeaderOnDiskManager.write(filePath, content);
m_communicator.unsavedFilesUpdated(mappedPath, content, 0);
ClangdClient::handleUiHeaderChange(Utils::FilePath::fromString(filePath).fileName());
}
void ClangModelManagerSupport::onAbstractEditorSupportRemoved(const QString &filePath)
@@ -618,6 +619,7 @@ void ClangModelManagerSupport::onAbstractEditorSupportRemoved(const QString &fil
const QString mappedPath = m_uiHeaderOnDiskManager.remove(filePath);
const QString projectPartId = projectPartIdForFile(filePath);
m_communicator.unsavedFilesRemoved({{mappedPath, projectPartId}});
ClangdClient::handleUiHeaderChange(Utils::FilePath::fromString(filePath).fileName());
}
}