From 0ab08e8574f19f939b7d5d084ddb82d2e0f6d88d Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 6 May 2021 12:39:37 +0200 Subject: [PATCH] LanguageClient: fix semanctic token delta data manipulation Make sure that multiple edits are in order. The SemanticTokensEdit start is relative to the start of the data and not to the position of the previous edit. Do not try to be smart when calculating the start of the modification, but assume that start is always a preedit index. Change-Id: I3e1513f5fe631aac21fecb5e0611d987355e2c21 Reviewed-by: Christian Stenger --- .../semantichighlightsupport.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index 25b4c27c396..2038f91f18c 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -378,29 +378,29 @@ void SemanticTokenSupport::handleSemanticTokensDelta( if (auto tokens = Utils::get_if(&result)) { m_tokens[filePath] = *tokens; } else if (auto tokensDelta = Utils::get_if(&result)) { - const QList &edits = tokensDelta->edits(); + QList edits = tokensDelta->edits(); if (edits.isEmpty()) return; + Utils::sort(edits, &SemanticTokensEdit::start); + SemanticTokens &tokens = m_tokens[filePath]; - QList data = tokens.data(); + const QList &data = tokens.data(); int newDataSize = data.size(); - for (const SemanticTokensEdit &edit : edits) + for (const SemanticTokensEdit &edit : qAsConst(edits)) newDataSize += edit.dataSize() - edit.deleteCount(); QList newData; newData.reserve(newDataSize); auto it = data.begin(); - int currentDelta = 0; - for (const SemanticTokensEdit &edit : edits) { - for (const auto start = it + edit.start() + currentDelta; it != start; ++it) + 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); - const QList insertData = edit.data().value_or(QList()); - newData.append(insertData); - const int deleteCount = edit.deleteCount(); - currentDelta += insertData.size() - deleteCount; - it += deleteCount; + newData.append(edit.data().value_or(QList())); + it += edit.deleteCount(); } for (const auto end = data.end(); it != end; ++it) newData.append(*it);