LanguageClient: save document version for semantic tokens

Change-Id: Icd17e7f140cd172b2515711a3562c479f0ad488d
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2021-10-22 10:52:48 +02:00
parent 9f7cdd6d3c
commit 86061fb44a
2 changed files with 30 additions and 15 deletions

View File

@@ -192,8 +192,9 @@ void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument)
return; return;
const Utils::FilePath filePath = textDocument->filePath(); const Utils::FilePath filePath = textDocument->filePath();
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(filePath)); const TextDocumentIdentifier docId(DocumentUri::fromFilePath(filePath));
auto responseCallback = [this, filePath](const SemanticTokensFullRequest::Response &response){ auto responseCallback = [this, filePath, documentVersion = m_client->documentVersion(filePath)](
handleSemanticTokens(filePath, response.result().value_or(nullptr)); const SemanticTokensFullRequest::Response &response) {
handleSemanticTokens(filePath, response.result().value_or(nullptr), documentVersion);
}; };
/*if (supportedRequests.testFlag(SemanticRequestType::Range)) { /*if (supportedRequests.testFlag(SemanticRequestType::Range)) {
const int start = widget->firstVisibleBlockNumber(); const int start = widget->firstVisibleBlockNumber();
@@ -223,15 +224,18 @@ void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument)
const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument); const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument);
if (supportedRequests.testFlag(SemanticRequestType::FullDelta)) { if (supportedRequests.testFlag(SemanticRequestType::FullDelta)) {
const Utils::FilePath filePath = textDocument->filePath(); const Utils::FilePath filePath = textDocument->filePath();
const QString &previousResultId = m_tokens.value(filePath).resultId().value_or(QString()); const QString &previousResultId = m_tokens.value(filePath).tokens.resultId().value_or(QString());
if (!previousResultId.isEmpty()) { if (!previousResultId.isEmpty()) {
SemanticTokensDeltaParams params; SemanticTokensDeltaParams params;
params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath))); params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
params.setPreviousResultId(previousResultId); params.setPreviousResultId(previousResultId);
SemanticTokensFullDeltaRequest request(params); SemanticTokensFullDeltaRequest request(params);
request.setResponseCallback( request.setResponseCallback(
[this, filePath](const SemanticTokensFullDeltaRequest::Response &response) { [this, filePath, documentVersion = m_client->documentVersion(filePath)](
handleSemanticTokensDelta(filePath, response.result().value_or(nullptr)); const SemanticTokensFullDeltaRequest::Response &response) {
handleSemanticTokensDelta(filePath,
response.result().value_or(nullptr),
documentVersion);
}); });
m_client->sendContent(request); m_client->sendContent(request);
return; return;
@@ -369,10 +373,11 @@ SemanticRequestTypes SemanticTokenSupport::supportedSemanticRequests(TextDocumen
} }
void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath, void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath,
const SemanticTokensResult &result) const SemanticTokensResult &result,
int documentVersion)
{ {
if (auto tokens = Utils::get_if<SemanticTokens>(&result)) { if (auto tokens = Utils::get_if<SemanticTokens>(&result)) {
m_tokens[filePath] = *tokens; m_tokens[filePath] = {*tokens, documentVersion};
highlight(filePath); highlight(filePath);
} else { } else {
m_tokens.remove(filePath); m_tokens.remove(filePath);
@@ -380,10 +385,12 @@ void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath,
} }
void SemanticTokenSupport::handleSemanticTokensDelta( void SemanticTokenSupport::handleSemanticTokensDelta(
const Utils::FilePath &filePath, const LanguageServerProtocol::SemanticTokensDeltaResult &result) const Utils::FilePath &filePath,
const LanguageServerProtocol::SemanticTokensDeltaResult &result,
int documentVersion)
{ {
if (auto tokens = Utils::get_if<SemanticTokens>(&result)) { if (auto tokens = Utils::get_if<SemanticTokens>(&result)) {
m_tokens[filePath] = *tokens; m_tokens[filePath] = {*tokens, documentVersion};
} else if (auto tokensDelta = Utils::get_if<SemanticTokensDelta>(&result)) { } else if (auto tokensDelta = Utils::get_if<SemanticTokensDelta>(&result)) {
QList<SemanticTokensEdit> edits = tokensDelta->edits(); QList<SemanticTokensEdit> edits = tokensDelta->edits();
if (edits.isEmpty()) { if (edits.isEmpty()) {
@@ -393,7 +400,8 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
Utils::sort(edits, &SemanticTokensEdit::start); Utils::sort(edits, &SemanticTokensEdit::start);
SemanticTokens &tokens = m_tokens[filePath]; m_tokens[filePath].version = documentVersion;
SemanticTokens &tokens = m_tokens[filePath].tokens;
const QList<int> &data = tokens.data(); const QList<int> &data = tokens.data();
int newDataSize = data.size(); int newDataSize = data.size();
@@ -443,7 +451,7 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath)
SyntaxHighlighter *highlighter = doc->syntaxHighlighter(); SyntaxHighlighter *highlighter = doc->syntaxHighlighter();
if (!highlighter) if (!highlighter)
return; return;
const QList<SemanticToken> tokens = m_tokens.value(filePath).toTokens(m_tokenTypes, const QList<SemanticToken> tokens = m_tokens.value(filePath).tokens.toTokens(m_tokenTypes,
m_tokenModifiers); m_tokenModifiers);
if (m_tokensHandler) { if (m_tokensHandler) {
int line = 1; int line = 1;

View File

@@ -86,16 +86,23 @@ private:
LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests( LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests(
TextEditor::TextDocument *document) const; TextEditor::TextDocument *document) const;
void handleSemanticTokens(const Utils::FilePath &filePath, void handleSemanticTokens(const Utils::FilePath &filePath,
const LanguageServerProtocol::SemanticTokensResult &result); const LanguageServerProtocol::SemanticTokensResult &result,
int documentVersion);
void handleSemanticTokensDelta(const Utils::FilePath &filePath, void handleSemanticTokensDelta(const Utils::FilePath &filePath,
const LanguageServerProtocol::SemanticTokensDeltaResult &result); const LanguageServerProtocol::SemanticTokensDeltaResult &result,
int documentVersion);
void highlight(const Utils::FilePath &filePath); void highlight(const Utils::FilePath &filePath);
void updateFormatHash(); void updateFormatHash();
void currentEditorChanged(); void currentEditorChanged();
Client *m_client = nullptr; Client *m_client = nullptr;
QHash<Utils::FilePath, LanguageServerProtocol::SemanticTokens> m_tokens; struct VersionedTokens
{
LanguageServerProtocol::SemanticTokens tokens;
int version;
};
QHash<Utils::FilePath, VersionedTokens> m_tokens;
QList<int> m_tokenTypes; QList<int> m_tokenTypes;
QList<int> m_tokenModifiers; QList<int> m_tokenModifiers;
QHash<int, QTextCharFormat> m_formatHash; QHash<int, QTextCharFormat> m_formatHash;