From 5d33982513e0bbb517120d2cb216490a0c110de6 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 5 Jul 2021 09:45:44 +0200 Subject: [PATCH] LSP: reload semantic token if we encounter corrupted data Change-Id: I73185b0b7be57d348fc1a461b1db0383313d7208 Reviewed-by: Christian Kandeler Reviewed-by: Qt CI Bot --- .../semantichighlightsupport.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index db6cd9f907d..3aafaf5b42f 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -39,10 +39,11 @@ using namespace LanguageServerProtocol; using namespace TextEditor; namespace LanguageClient { -namespace SemanticHighligtingSupport { static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg); +namespace SemanticHighligtingSupport { + static const QList> highlightScopes(const ServerCapabilities &capabilities) { return capabilities.semanticHighlighting() @@ -399,15 +400,27 @@ void SemanticTokenSupport::handleSemanticTokensDelta( newData.reserve(newDataSize); auto it = data.begin(); + const auto end = data.end(); for (const SemanticTokensEdit &edit : qAsConst(edits)) { if (edit.start() > data.size()) // prevent edits after the previously reported data return; for (const auto start = data.begin() + edit.start(); it < start; ++it) newData.append(*it); newData.append(edit.data().value_or(QList())); - it += edit.deleteCount(); + int deleteCount = edit.deleteCount(); + if (deleteCount > std::distance(it, end)) { + qCDebug(LOGLSPHIGHLIGHT) + << "We shall delete more highlight data entries than we actually have, " + "so we are out of sync with the server. " + "Request full semantic tokens again."; + TextDocument *doc = TextDocument::textDocumentForFilePath(filePath); + if (doc && LanguageClientManager::clientForDocument(doc) == m_client) + reloadSemanticTokens(doc); + return; + } + it += deleteCount; } - for (const auto end = data.end(); it != end; ++it) + for (; it != end; ++it) newData.append(*it); tokens.setData(newData);