forked from qt-creator/qt-creator
LanguageClient: keep semantic tokens after receiving error
A usual error we receive for semantic request is that the request got canceled. This can be due to external changes. But a server might still be able to calculate a diff against a previous token set. So just keep the previously reported tokens and rerequest a new highlight. If the server is not able to calculate a diff it also might send a full token set as a result for the delta request according to the protocol. Fixes: QTCREATORBUG-26624 Change-Id: Ia91e599706519dbbf4cd22050484e4f36cecdab8 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -67,19 +67,33 @@ void SemanticTokenSupport::refresh()
|
||||
}
|
||||
|
||||
void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument)
|
||||
{
|
||||
reloadSemanticTokensImpl(textDocument);
|
||||
}
|
||||
|
||||
void SemanticTokenSupport::reloadSemanticTokensImpl(TextDocument *textDocument,
|
||||
int remainingRerequests)
|
||||
{
|
||||
const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument);
|
||||
if (supportedRequests.testFlag(SemanticRequestType::None))
|
||||
return;
|
||||
const Utils::FilePath filePath = textDocument->filePath();
|
||||
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(filePath));
|
||||
auto responseCallback = [this, filePath, documentVersion = m_client->documentVersion(filePath)](
|
||||
auto responseCallback = [this,
|
||||
remainingRerequests,
|
||||
filePath,
|
||||
documentVersion = m_client->documentVersion(filePath)](
|
||||
const SemanticTokensFullRequest::Response &response) {
|
||||
if (const auto error = response.error()) {
|
||||
qCDebug(LOGLSPHIGHLIGHT)
|
||||
<< "received error" << error->code() << error->message() << "for" << filePath;
|
||||
if (remainingRerequests > 0) {
|
||||
if (auto document = TextDocument::textDocumentForFilePath(filePath))
|
||||
reloadSemanticTokensImpl(document, remainingRerequests - 1);
|
||||
}
|
||||
} else {
|
||||
handleSemanticTokens(filePath, response.result().value_or(nullptr), documentVersion);
|
||||
}
|
||||
handleSemanticTokens(filePath, response.result().value_or(nullptr), documentVersion);
|
||||
};
|
||||
/*if (supportedRequests.testFlag(SemanticRequestType::Range)) {
|
||||
const int start = widget->firstVisibleBlockNumber();
|
||||
@@ -107,6 +121,12 @@ void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument)
|
||||
}
|
||||
|
||||
void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument)
|
||||
{
|
||||
updateSemanticTokensImpl(textDocument);
|
||||
}
|
||||
|
||||
void SemanticTokenSupport::updateSemanticTokensImpl(TextDocument *textDocument,
|
||||
int remainingRerequests)
|
||||
{
|
||||
const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument);
|
||||
if (supportedRequests.testFlag(SemanticRequestType::FullDelta)) {
|
||||
@@ -122,15 +142,22 @@ void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument)
|
||||
params.setPreviousResultId(previousResultId);
|
||||
SemanticTokensFullDeltaRequest request(params);
|
||||
request.setResponseCallback(
|
||||
[this, filePath, documentVersion](
|
||||
[this, filePath, documentVersion, remainingRerequests](
|
||||
const SemanticTokensFullDeltaRequest::Response &response) {
|
||||
if (const auto error = response.error()) {
|
||||
qCDebug(LOGLSPHIGHLIGHT) << "received error" << error->code()
|
||||
<< error->message() << "for" << filePath;
|
||||
if (auto document = TextDocument::textDocumentForFilePath(filePath)) {
|
||||
if (remainingRerequests > 0)
|
||||
updateSemanticTokensImpl(document, remainingRerequests - 1);
|
||||
else
|
||||
reloadSemanticTokensImpl(document, 1); // try a full reload once
|
||||
}
|
||||
} else {
|
||||
handleSemanticTokensDelta(filePath,
|
||||
response.result().value_or(nullptr),
|
||||
documentVersion);
|
||||
}
|
||||
handleSemanticTokensDelta(filePath,
|
||||
response.result().value_or(nullptr),
|
||||
documentVersion);
|
||||
});
|
||||
qCDebug(LOGLSPHIGHLIGHT)
|
||||
<< "Requesting delta for" << filePath << "with version" << documentVersion;
|
||||
@@ -292,11 +319,6 @@ void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath,
|
||||
if (auto tokens = Utils::get_if<SemanticTokens>(&result)) {
|
||||
m_tokens[filePath] = {*tokens, documentVersion};
|
||||
highlight(filePath);
|
||||
} else {
|
||||
qCDebug(LOGLSPHIGHLIGHT)
|
||||
<< "no data in reply to full semantic tokens request, clearing tokens"
|
||||
<< m_client->name() << filePath;
|
||||
m_tokens.remove(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,12 +385,6 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
|
||||
qCDebug(LOGLSPHIGHLIGHT) << "New Data " << newData;
|
||||
tokens.setData(newData);
|
||||
tokens.setResultId(tokensDelta->resultId());
|
||||
} else {
|
||||
qCDebug(LOGLSPHIGHLIGHT)
|
||||
<< "no data in reply to semantic tokens delta request, clearing tokens"
|
||||
<< m_client->name() << filePath;
|
||||
m_tokens.remove(filePath);
|
||||
return;
|
||||
}
|
||||
highlight(filePath);
|
||||
}
|
||||
|
@@ -83,6 +83,8 @@ public:
|
||||
void setTokensHandler(const SemanticTokensHandler &handler) { m_tokensHandler = handler; }
|
||||
|
||||
private:
|
||||
void reloadSemanticTokensImpl(TextEditor::TextDocument *doc, int remainingRerequests = 3);
|
||||
void updateSemanticTokensImpl(TextEditor::TextDocument *doc, int remainingRerequests = 3);
|
||||
LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests(
|
||||
TextEditor::TextDocument *document) const;
|
||||
void handleSemanticTokens(const Utils::FilePath &filePath,
|
||||
|
Reference in New Issue
Block a user