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

View File

@@ -86,16 +86,23 @@ private:
LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests(
TextEditor::TextDocument *document) const;
void handleSemanticTokens(const Utils::FilePath &filePath,
const LanguageServerProtocol::SemanticTokensResult &result);
const LanguageServerProtocol::SemanticTokensResult &result,
int documentVersion);
void handleSemanticTokensDelta(const Utils::FilePath &filePath,
const LanguageServerProtocol::SemanticTokensDeltaResult &result);
const LanguageServerProtocol::SemanticTokensDeltaResult &result,
int documentVersion);
void highlight(const Utils::FilePath &filePath);
void updateFormatHash();
void currentEditorChanged();
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_tokenModifiers;
QHash<int, QTextCharFormat> m_formatHash;