From 6aa2c58842c4fc7ade585eaa6e786c063f1c34b6 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 29 Nov 2021 09:44:46 +0100 Subject: [PATCH] LanguageClient: remove semantic highlighting proposal The semantichighlighting proposal from https://github.com/microsoft/vscode-languageserver-node/pull/367 was replaced with semantic tokens in the final protocol version 3.16. This reverts 307f1d8e6eb24a88c2113b6b03b3133092ff81b7 Task-number: QTCREATORBUG-26624 Change-Id: I635f0b4763a197edabf9edf8d9041143dcf531e3 Reviewed-by: Christian Kandeler --- .../clientcapabilities.h | 19 --- src/libs/languageserverprotocol/jsonkeys.h | 4 - .../languagefeatures.cpp | 62 -------- .../languageserverprotocol/languagefeatures.h | 57 ------- .../servercapabilities.cpp | 44 ------ .../servercapabilities.h | 17 --- src/plugins/languageclient/client.cpp | 71 +-------- src/plugins/languageclient/client.h | 3 - .../languageclient/languageclientmanager.cpp | 1 - .../semantichighlightsupport.cpp | 141 ++---------------- .../languageclient/semantichighlightsupport.h | 12 +- 11 files changed, 11 insertions(+), 420 deletions(-) diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h index 693fc231f26..bc6151a1740 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.h +++ b/src/libs/languageserverprotocol/clientcapabilities.h @@ -195,25 +195,6 @@ public: { insert(synchronizationKey, synchronization); } void clearSynchronization() { remove(synchronizationKey); } - class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingCapabilities : public JsonObject - { - public: - using JsonObject::JsonObject; - - bool semanticHighlighting() const { return typedValue(semanticHighlightingKey); } - void setSemanticHighlighting(bool semanticHighlighting) - { insert(semanticHighlightingKey, semanticHighlighting); } - - bool isValid() const override { return contains(semanticHighlightingKey); } - }; - - Utils::optional semanticHighlightingCapabilities() const - { return optionalValue(semanticHighlightingCapabilitiesKey); } - void setSemanticHighlightingCapabilities( - const SemanticHighlightingCapabilities &semanticHighlightingCapabilities) - { insert(semanticHighlightingCapabilitiesKey, semanticHighlightingCapabilities); } - void clearSemanticHighlightingCapabilities() { remove(semanticHighlightingCapabilitiesKey); } - class LANGUAGESERVERPROTOCOL_EXPORT CompletionCapabilities : public DynamicRegistrationCapabilities { public: diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h index 332571fb2cf..24187d77b07 100644 --- a/src/libs/languageserverprotocol/jsonkeys.h +++ b/src/libs/languageserverprotocol/jsonkeys.h @@ -187,11 +187,8 @@ constexpr char rootUriKey[] = "rootUri"; constexpr char saveKey[] = "save"; constexpr char schemeKey[] = "scheme"; constexpr char scopeUriKey[] = "scopeUri"; -constexpr char scopesKey[] = "scopes"; constexpr char sectionKey[] = "section"; constexpr char selectionRangeKey[] = "selectionRange"; -constexpr char semanticHighlightingCapabilitiesKey[] = "semanticHighlightingCapabilities"; -constexpr char semanticHighlightingKey[] = "semanticHighlighting"; constexpr char semanticTokensKey[] = "semanticTokens"; constexpr char semanticTokensProviderKey[] = "semanticTokensProvider"; constexpr char serverInfoKey[] = "serverInfo"; @@ -220,7 +217,6 @@ constexpr char titleKey[] = "title"; constexpr char tokenKey[] = "token"; constexpr char tokenModifiersKey[] = "tokenModifiers"; constexpr char tokenTypesKey[] = "tokenTypes"; -constexpr char tokensKey[] = "tokens"; constexpr char traceKey[] = "trace"; constexpr char triggerCharacterKey[] = "triggerCharacter"; constexpr char triggerCharactersKey[] = "triggerCharacters"; diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index 59fb9688b78..08d09cc3b8c 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -48,7 +48,6 @@ constexpr const char DocumentRangeFormattingRequest::methodName[]; constexpr const char DocumentOnTypeFormattingRequest::methodName[]; constexpr const char RenameRequest::methodName[]; constexpr const char SignatureHelpRequest::methodName[]; -constexpr const char SemanticHighlightNotification::methodName[]; constexpr const char PrepareRenameRequest::methodName[]; HoverContent LanguageServerProtocol::Hover::content() const @@ -369,63 +368,6 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) emplace(nullptr); } -Utils::optional> SemanticHighlightingInformation::tokens() const -{ - QList resultTokens; - - const QByteArray tokensByteArray = QByteArray::fromBase64( - typedValue(tokensKey).toLocal8Bit()); - constexpr int tokensByteSize = 8; - int index = 0; - while (index + tokensByteSize <= tokensByteArray.size()) { - resultTokens << SemanticHighlightToken(tokensByteArray.mid(index, tokensByteSize)); - index += tokensByteSize; - } - return Utils::make_optional(resultTokens); -} - -void SemanticHighlightingInformation::setTokens(const QList &tokens) -{ - QByteArray byteArray; - byteArray.reserve(8 * tokens.size()); - for (const SemanticHighlightToken &token : tokens) - token.appendToByteArray(byteArray); - insert(tokensKey, QString::fromLocal8Bit(byteArray.toBase64())); -} - -SemanticHighlightToken::SemanticHighlightToken(const QByteArray &token) -{ - QTC_ASSERT(token.size() == 8, return ); - character = ( quint32(token.at(0)) << 24 - | quint32(token.at(1)) << 16 - | quint32(token.at(2)) << 8 - | quint32(token.at(3))); - - length = quint16(token.at(4) << 8 | token.at(5)); - - scope = quint16(token.at(6) << 8 | token.at(7)); -} - -void SemanticHighlightToken::appendToByteArray(QByteArray &byteArray) const -{ - byteArray.append(char((character & 0xff000000) >> 24)); - byteArray.append(char((character & 0x00ff0000) >> 16)); - byteArray.append(char((character & 0x0000ff00) >> 8)); - byteArray.append(char((character & 0x000000ff))); - byteArray.append(char((length & 0xff00) >> 8)); - byteArray.append(char((length & 0x00ff))); - byteArray.append(char((scope & 0xff00) >> 8)); - byteArray.append(char((scope & 0x00ff))); -} - -Utils::variant -SemanticHighlightingParams::textDocument() const -{ - VersionedTextDocumentIdentifier textDocument = fromJsonValue( - value(textDocumentKey)); - return textDocument.isValid() ? textDocument : TextDocumentIdentifier(textDocument); -} - PrepareRenameResult::PrepareRenameResult() : Utils::variant(nullptr) {} @@ -457,10 +399,6 @@ PrepareRenameResult::PrepareRenameResult(const QJsonValue &val) } } -SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighlightingParams ¶ms) - : Notification(methodName, params) -{} - Utils::optional CodeLens::data() const { return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt; diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index ade9507d0b6..b82fccdaf10 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -846,61 +846,4 @@ public: constexpr static const char methodName[] = "textDocument/rename"; }; -class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightToken -{ -public: - // Just accepts token with 8 bytes - explicit SemanticHighlightToken(const QByteArray &token); - SemanticHighlightToken() = default; - - void appendToByteArray(QByteArray &byteArray) const; - - quint32 character = 0; - quint16 length = 0; - quint16 scope = 0; -}; - -class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingInformation : public JsonObject -{ -public: - using JsonObject::JsonObject; - - int line() const { return typedValue(lineKey); } - void setLine(int line) { insert(lineKey, line); } - - Utils::optional> tokens() const; - void setTokens(const QList &tokens); - void clearTokens() { remove(tokensKey); } - - bool isValid() const override { return contains(lineKey); } -}; - -class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingParams : public JsonObject -{ -public: - using JsonObject::JsonObject; - - Utils::variant textDocument() const; - void setTextDocument(const TextDocumentIdentifier &textDocument) - { insert(textDocumentKey, textDocument); } - void setTextDocument(const VersionedTextDocumentIdentifier &textDocument) - { insert(textDocumentKey, textDocument); } - - QList lines() const - { return array(linesKey); } - void setLines(const QList &lines) - { insertArray(linesKey, lines); } - - bool isValid() const override { return contains(textDocumentKey) && contains(linesKey); } -}; - -class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification - : public Notification -{ -public: - explicit SemanticHighlightNotification(const SemanticHighlightingParams ¶ms); - using Notification::Notification; - constexpr static const char methodName[] = "textDocument/semanticHighlighting"; -}; - } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp index ba8a6836ac1..4a15153bd77 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -306,50 +306,6 @@ bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileN }); } -Utils::optional>> ServerCapabilities::SemanticHighlightingServerCapabilities::scopes() const -{ - QList> scopes; - if (!contains(scopesKey)) - return Utils::nullopt; - for (const QJsonValue jsonScopeValue : value(scopesKey).toArray()) { - if (!jsonScopeValue.isArray()) - return {}; - QList scope; - for (const QJsonValue value : jsonScopeValue.toArray()) { - if (!value.isString()) - return {}; - scope.append(value.toString()); - } - scopes.append(scope); - } - return Utils::make_optional(scopes); -} - -void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes( - const QList> &scopes) -{ - QJsonArray jsonScopes; - for (const QList &scope : scopes) { - QJsonArray jsonScope; - for (const QString &value : scope) - jsonScope.append(value); - jsonScopes.append(jsonScope); - } - insert(scopesKey, jsonScopes); -} - -bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid() const -{ - return contains(scopesKey) && value(scopesKey).isArray() - && Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - return array.isArray() && Utils::allOf(array.toArray(), &QJsonValue::isString); -#else - return array.isArray() && Utils::allOf(array.toArray(), &QJsonValueRef::isString); -#endif - }); -} - bool ServerCapabilities::ExecuteCommandOptions::isValid() const { return WorkDoneProgressOptions::isValid() && contains(commandsKey); diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h index e1c847ccaaa..7cc1b708fcd 100644 --- a/src/libs/languageserverprotocol/servercapabilities.h +++ b/src/libs/languageserverprotocol/servercapabilities.h @@ -263,17 +263,6 @@ public: void clearId() { remove(idKey); } }; - class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingServerCapabilities : public JsonObject - { - public: - using JsonObject::JsonObject; - - Utils::optional>> scopes() const; - void setScopes(const QList> &scopes); - - bool isValid() const override; - }; - // Defines how text documents are synced. Is either a detailed structure defining each // notification or for backwards compatibility the TextDocumentSyncKind number. using TextDocumentSync = Utils::variant; @@ -463,12 +452,6 @@ public: Utils::optional experimental() const { return optionalValue(experimentalKey); } void setExperimental(const JsonObject &experimental) { insert(experimentalKey, experimental); } void clearExperimental() { remove(experimentalKey); } - - Utils::optional semanticHighlighting() const - { return optionalValue(semanticHighlightingKey); } - void setSemanticHighlighting(const SemanticHighlightingServerCapabilities &semanticHighlighting) - { insert(semanticHighlightingKey, semanticHighlighting); } - void clearSemanticHighlighting() { remove(semanticHighlightingKey); } }; } // namespace LanguageClient diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 97283fc549c..2fa2fdec0bf 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -102,10 +102,6 @@ Client::Client(BaseClientInterface *clientInterface) connect(clientInterface, &BaseClientInterface::messageReceived, this, &Client::handleMessage); connect(clientInterface, &BaseClientInterface::error, this, &Client::setError); connect(clientInterface, &BaseClientInterface::finished, this, &Client::finished); - connect(TextEditor::TextEditorSettings::instance(), - &TextEditor::TextEditorSettings::fontSettingsChanged, - this, - &Client::rehighlight); m_tokenSupport.setTokenTypesMap(SemanticTokens::defaultTokenTypesMap()); m_tokenSupport.setTokenModifiersMap(SemanticTokens::defaultTokenModifiersMap()); @@ -142,13 +138,6 @@ Client::~Client() widget->removeHoverHandler(&m_hoverHandler); } } - for (auto it = m_highlights.cbegin(); it != m_highlights.cend(); ++it) { - const DocumentUri &uri = it.key(); - if (TextDocument *doc = TextDocument::textDocumentForFilePath(uri.toFilePath())) { - if (TextEditor::SyntaxHighlighter *highlighter = doc->syntaxHighlighter()) - highlighter->clearAllExtraFormats(); - } - } for (IAssistProcessor *processor : qAsConst(m_runningAssistProcessors)) processor->setAsyncProposalAvailable(nullptr); qDeleteAll(m_documentHighlightsTimer); @@ -199,10 +188,6 @@ static ClientCapabilities generateClientCapabilities() symbolCapabilities.setHierarchicalDocumentSymbolSupport(true); documentCapabilities.setDocumentSymbol(symbolCapabilities); - TextDocumentClientCapabilities::SemanticHighlightingCapabilities semanticHighlight; - semanticHighlight.setSemanticHighlighting(true); - documentCapabilities.setSemanticHighlightingCapabilities(semanticHighlight); - TextDocumentClientCapabilities::CompletionCapabilities completionCapabilities; completionCapabilities.setDynamicRegistration(true); TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemKindCapabilities @@ -449,7 +434,6 @@ void Client::closeDocument(TextEditor::TextDocument *document) { deactivateDocument(document); const DocumentUri &uri = DocumentUri::fromFilePath(document->filePath()); - m_highlights[uri].clear(); m_postponedDocuments.remove(document); if (m_openedDocument.remove(document) != 0) { handleDocumentClosed(document); @@ -580,7 +564,6 @@ void Client::activateDocument(TextEditor::TextDocument *document) const FilePath &filePath = document->filePath(); auto uri = DocumentUri::fromFilePath(filePath); m_diagnosticManager.showDiagnostics(uri, m_documentVersions.value(filePath)); - SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities()); m_tokenSupport.updateSemanticTokens(document); // only replace the assist provider if the language server support it updateCompletionProvider(document); @@ -607,10 +590,7 @@ void Client::deactivateDocument(TextEditor::TextDocument *document) m_diagnosticManager.hideDiagnostics(document); resetAssistProviders(document); document->setFormatter(nullptr); - if (m_serverCapabilities.semanticHighlighting().has_value()) { - if (TextEditor::SyntaxHighlighter *highlighter = document->syntaxHighlighter()) - highlighter->clearAllExtraFormats(); - } + m_tokenSupport.clearHighlight(document); for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document)) { if (auto textEditor = qobject_cast(editor)) { TextEditor::TextEditorWidget *widget = textEditor->editorWidget(); @@ -1249,7 +1229,6 @@ void Client::sendPostponedDocumentUpdates(Schedule semanticTokensSchedule) TextEditor::TextDocument * const document = elem.first; const FilePath &filePath = document->filePath(); const auto uri = DocumentUri::fromFilePath(filePath); - m_highlights[uri].clear(); VersionedTextDocumentIdentifier docId(uri); docId.setVersion(m_documentVersions[filePath]); DidChangeTextDocumentParams params; @@ -1327,12 +1306,6 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon log(params); else log(invalidParamsErrorMessage(params)); - } else if (method == SemanticHighlightNotification::methodName) { - auto params = dynamic_cast(content)->params().value_or(SemanticHighlightingParams()); - if (params.isValid()) - handleSemanticHighlight(params); - else - log(invalidParamsErrorMessage(params)); } else if (method == ShowMessageNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(ShowMessageParams()); if (params.isValid()) @@ -1457,48 +1430,6 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms) } } -void Client::handleSemanticHighlight(const SemanticHighlightingParams ¶ms) -{ - DocumentUri uri; - LanguageClientValue version; - auto textDocument = params.textDocument(); - - if (Utils::holds_alternative(textDocument)) { - uri = Utils::get(textDocument).uri(); - version = Utils::get(textDocument).version(); - } else { - uri = Utils::get(textDocument).uri(); - } - - m_highlights[uri].clear(); - TextEditor::TextDocument *doc = TextEditor::TextDocument::textDocumentForFilePath( - uri.toFilePath()); - - if (!doc || LanguageClientManager::clientForDocument(doc) != this - || (!version.isNull() && m_documentVersions.value(uri.toFilePath()) != version.value())) { - return; - } - - const TextEditor::HighlightingResults results = SemanticHighligtingSupport::generateResults( - params.lines()); - - m_highlights[uri] = results; - - SemanticHighligtingSupport::applyHighlight(doc, results, capabilities()); -} - -void Client::rehighlight() -{ - using namespace TextEditor; - m_tokenSupport.rehighlight(); - for (auto it = m_highlights.begin(), end = m_highlights.end(); it != end; ++it) { - if (TextDocument *doc = TextDocument::textDocumentForFilePath(it.key().toFilePath())) { - if (LanguageClientManager::clientForDocument(doc) == this) - SemanticHighligtingSupport::applyHighlight(doc, it.value(), capabilities()); - } - } -} - bool Client::documentUpdatePostponed(const Utils::FilePath &fileName) const { return Utils::contains(m_documentsToUpdate, [fileName](const auto &elem) { diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index a89891828b0..dc9a1516947 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -226,8 +226,6 @@ private: void handleMethod(const QString &method, const LanguageServerProtocol::MessageId &id, const LanguageServerProtocol::IContent *content); - void handleSemanticHighlight(const LanguageServerProtocol::SemanticHighlightingParams ¶ms); - void initializeCallback(const LanguageServerProtocol::InitializeRequest::Response &initResponse); void shutDownCallback(const LanguageServerProtocol::ShutdownRequest::Response &shutdownResponse); bool sendWorkspceFolderChanges() const; @@ -247,7 +245,6 @@ private: void requestDocumentHighlights(TextEditor::TextEditorWidget *widget); LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests(TextEditor::TextDocument *document) const; void handleSemanticTokens(const LanguageServerProtocol::SemanticTokens &tokens); - void rehighlight(); virtual void handleDocumentClosed(TextEditor::TextDocument *) {} virtual void handleDocumentOpened(TextEditor::TextDocument *) {} diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 0e5a80013b8..4e306785821 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -63,7 +63,6 @@ LanguageClientManager::LanguageClientManager(QObject *parent) using namespace Core; using namespace ProjectExplorer; JsonRpcMessageHandler::registerMessageProvider(); - JsonRpcMessageHandler::registerMessageProvider(); JsonRpcMessageHandler::registerMessageProvider(); JsonRpcMessageHandler::registerMessageProvider(); JsonRpcMessageHandler::registerMessageProvider(); diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index 260cabd7e49..4549dd8e484 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -29,6 +29,7 @@ #include "languageclientmanager.h" #include +#include #include #include #include @@ -42,138 +43,6 @@ namespace LanguageClient { static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg); -namespace SemanticHighligtingSupport { - -static const QList> highlightScopes(const ServerCapabilities &capabilities) -{ - return capabilities.semanticHighlighting() - .value_or(ServerCapabilities::SemanticHighlightingServerCapabilities()) - .scopes().value_or(QList>()); -} - -static Utils::optional styleForScopes(const QList &scopes) -{ - // missing "Minimal Scope Coverage" scopes - - // entity.other.inherited-class - // entity.name.section - // entity.name.tag - // entity.other.attribute-name - // variable.language - // variable.parameter - // variable.function - // constant.numeric - // constant.language - // constant.character.escape - // support - // storage.modifier - // keyword.control - // keyword.operator - // keyword.declaration - // invalid - // invalid.deprecated - - static const QMap styleForScopes = { - {"entity.name", C_TYPE}, - {"entity.name.function", C_FUNCTION}, - {"entity.name.function.method.static", C_GLOBAL}, - {"entity.name.function.preprocessor", C_PREPROCESSOR}, - {"entity.name.label", C_LABEL}, - {"keyword", C_KEYWORD}, - {"storage.type", C_KEYWORD}, - {"constant.numeric", C_NUMBER}, - {"string", C_STRING}, - {"comment", C_COMMENT}, - {"comment.block.documentation", C_DOXYGEN_COMMENT}, - {"variable.function", C_FUNCTION}, - {"variable.other", C_LOCAL}, - {"variable.other.member", C_FIELD}, - {"variable.other.field", C_FIELD}, - {"variable.other.field.static", C_GLOBAL}, - {"variable.parameter", C_PARAMETER}, - }; - - for (QString scope : scopes) { - while (!scope.isEmpty()) { - auto style = styleForScopes.find(scope); - if (style != styleForScopes.end()) - return style.value(); - const int index = scope.lastIndexOf('.'); - if (index <= 0) - break; - scope = scope.left(index); - } - } - return Utils::nullopt; -} - -static QHash scopesToFormatHash(QList> scopes, - const FontSettings &fontSettings) -{ - QHash scopesToFormat; - for (int i = 0; i < scopes.size(); ++i) { - if (Utils::optional style = styleForScopes(scopes[i])) - scopesToFormat[i] = fontSettings.toTextCharFormat(style.value()); - } - return scopesToFormat; -} - -HighlightingResult tokenToHighlightingResult(int line, const SemanticHighlightToken &token) -{ - return HighlightingResult(unsigned(line) + 1, - unsigned(token.character) + 1, - token.length, - int(token.scope)); -} - -HighlightingResults generateResults(const QList &lines) -{ - HighlightingResults results; - - for (const SemanticHighlightingInformation &info : lines) { - const int line = info.line(); - for (const SemanticHighlightToken &token : - info.tokens().value_or(QList())) { - results << tokenToHighlightingResult(line, token); - } - } - - return results; -} - -void applyHighlight(TextDocument *doc, - const HighlightingResults &results, - const ServerCapabilities &capabilities) -{ - if (!doc->syntaxHighlighter()) - return; - if (LOGLSPHIGHLIGHT().isDebugEnabled()) { - auto scopes = highlightScopes(capabilities); - qCDebug(LOGLSPHIGHLIGHT) << "semantic highlight for" << doc->filePath(); - for (auto result : results) { - auto b = doc->document()->findBlockByNumber(int(result.line - 1)); - const QString &text = b.text().mid(int(result.column - 1), int(result.length)); - auto resultScupes = scopes[result.kind]; - auto style = styleForScopes(resultScupes).value_or(C_TEXT); - qCDebug(LOGLSPHIGHLIGHT) << result.line - 1 << '\t' - << result.column - 1 << '\t' - << result.length << '\t' - << TextEditor::Constants::nameForStyle(style) << '\t' - << text - << resultScupes; - } - } - - if (capabilities.semanticHighlighting().has_value()) { - SemanticHighlighter::setExtraAdditionalFormats( - doc->syntaxHighlighter(), - results, - scopesToFormatHash(highlightScopes(capabilities), doc->fontSettings())); - } -} - -} // namespace SemanticHighligtingSupport - constexpr int tokenTypeBitOffset = 16; SemanticTokenSupport::SemanticTokenSupport(Client *client) @@ -258,6 +127,14 @@ void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument) reloadSemanticTokens(textDocument); } +void SemanticTokenSupport::clearHighlight(TextEditor::TextDocument *doc) +{ + if (m_tokens.contains(doc->filePath())){ + if (TextEditor::SyntaxHighlighter *highlighter = doc->syntaxHighlighter()) + highlighter->clearAllExtraFormats(); + } +} + void SemanticTokenSupport::rehighlight() { for (const Utils::FilePath &filePath : m_tokens.keys()) diff --git a/src/plugins/languageclient/semantichighlightsupport.h b/src/plugins/languageclient/semantichighlightsupport.h index 1f205fe7813..724e85f837e 100644 --- a/src/plugins/languageclient/semantichighlightsupport.h +++ b/src/plugins/languageclient/semantichighlightsupport.h @@ -58,17 +58,6 @@ inline bool operator==(const ExpandedSemanticToken &t1, const ExpandedSemanticTo using SemanticTokensHandler = std::function &, int, bool)>; -namespace SemanticHighligtingSupport { - -TextEditor::HighlightingResults generateResults( - const QList &lines); - -void applyHighlight(TextEditor::TextDocument *doc, - const TextEditor::HighlightingResults &results, - const LanguageServerProtocol::ServerCapabilities &capabilities); - -} // namespace SemanticHighligtingSupport - class SemanticTokenSupport : public QObject { public: @@ -77,6 +66,7 @@ public: void refresh(); void reloadSemanticTokens(TextEditor::TextDocument *doc); void updateSemanticTokens(TextEditor::TextDocument *doc); + void clearHighlight(TextEditor::TextDocument *doc); void rehighlight(); void setLegend(const LanguageServerProtocol::SemanticTokensLegend &legend);