From 84a00f637126afee0fe09e8e23fd6773055293ee Mon Sep 17 00:00:00 2001 From: Felipe Lema <1232306+FelipeLema@users.noreply.github.com> Date: Mon, 3 May 2021 12:51:04 -0400 Subject: [PATCH] textDocument/semanticTokens/range - add overhead code for new method - move code from "semantic tokens for full document" to "semantic tokens for range in document" - add range delimitation to function - make "full document" use "range that covers all document" --- src/message_handler.cc | 1 + src/message_handler.hh | 6 ++++ src/messages/initialize.cc | 3 +- src/messages/textDocument_semanticToken.cc | 42 ++++++++++++++++++++-- src/query.hh | 5 +-- 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/message_handler.cc b/src/message_handler.cc index 2f86fb71..6546722a 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -189,6 +189,7 @@ MessageHandler::MessageHandler() { bind("textDocument/signatureHelp", &MessageHandler::textDocument_signatureHelp); bind("textDocument/typeDefinition", &MessageHandler::textDocument_typeDefinition); bind("textDocument/semanticTokens/full", &MessageHandler::textDocument_semanticTokensFull); + bind("textDocument/semanticTokens/range", &MessageHandler::textDocument_semanticTokensRange); bind("workspace/didChangeConfiguration", &MessageHandler::workspace_didChangeConfiguration); bind("workspace/didChangeWatchedFiles", &MessageHandler::workspace_didChangeWatchedFiles); bind("workspace/didChangeWorkspaceFolders", &MessageHandler::workspace_didChangeWorkspaceFolders); diff --git a/src/message_handler.hh b/src/message_handler.hh index 27c684e9..f4149b61 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -52,6 +52,11 @@ struct SemanticTokensParams { TextDocumentIdentifier textDocument; }; REFLECT_STRUCT(SemanticTokensParams, textDocument); +struct SemanticTokensRangeParams { + TextDocumentIdentifier textDocument; + lsRange range; +}; +REFLECT_STRUCT(SemanticTokensRangeParams, textDocument, range); struct TextDocumentEdit { VersionedTextDocumentIdentifier textDocument; std::vector edits; @@ -292,6 +297,7 @@ private: void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &); void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &); void textDocument_semanticTokensFull(SemanticTokensParams &, ReplyOnce &); + void textDocument_semanticTokensRange(SemanticTokensRangeParams &, ReplyOnce &); void workspace_didChangeConfiguration(EmptyParam &); void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &); void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cee98460..5ad5ef47 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -135,6 +135,7 @@ struct ServerCap { std::vector tokenTypes = SEMANTIC_TOKENS; std::vector tokenModifiers = SEMANTIC_MODIFIERS; } legend; + bool range = true; bool full = true; } semanticTokensProvider; }; @@ -158,7 +159,7 @@ REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider, documentOnTypeFormattingProvider, renameProvider, documentLinkProvider, foldingRangeProvider, executeCommandProvider, workspace, semanticTokensProvider); -REFLECT_STRUCT(ServerCap::SemanticTokenProvider, legend, full); +REFLECT_STRUCT(ServerCap::SemanticTokenProvider, legend, range, full); REFLECT_STRUCT(ServerCap::SemanticTokenProvider::SemanticTokensLegend, tokenTypes, tokenModifiers); struct DynamicReg { diff --git a/src/messages/textDocument_semanticToken.cc b/src/messages/textDocument_semanticToken.cc index c51f9013..f0034e41 100644 --- a/src/messages/textDocument_semanticToken.cc +++ b/src/messages/textDocument_semanticToken.cc @@ -56,9 +56,34 @@ struct ScanLineEvent { }; } +constexpr Position documentBegin{0,0}; +constexpr Position documentEnd{ + std::numeric_limits::max(), + std::numeric_limits::max()}; -void MessageHandler::textDocument_semanticTokensFull( - SemanticTokensParams ¶m, ReplyOnce &reply) { +inline std::ostream &operator<<(std::ostream &s, const Position pos) { + s + << "{line: " << pos.line + << ", end: " << pos.character; + return s; +} +inline std::ostream &operator<<(std::ostream &s, const lsRange &range) { + s + << "lsRange(start:" << range.start + << ", end:" << range.end + << ")"; + return s; +} + +void MessageHandler::textDocument_semanticTokensRange( + SemanticTokensRangeParams ¶m, ReplyOnce &reply) { + if(param.range.start == documentBegin && param.range.end == documentEnd) + LOG_S(INFO) + << "SemanticToken for all document"; + else + LOG_S(INFO) + << "SemanticToken for range " + << param.range.start; std::string path = param.textDocument.uri.getPath(); WorkingFile *wfile = wfiles->getFile(path); if (!wfile) { @@ -88,6 +113,13 @@ void MessageHandler::textDocument_semanticTokensFull( for (auto [sym, refcnt] : queryFile->symbol2refcnt) { if (refcnt <= 0) continue; + // skip symbols that don't start within range + if( sym.range.start.line < param.range.start.line + || sym.range.end.line > param.range.end.line + // range is within lines here below, let's test if within specified characters/columns + || sym.range.start.column < param.range.start.character + || sym.range.end.column > param.range.end.character) + continue; std::string_view detailed_name; SymbolKind parent_kind = SymbolKind::Unknown; SymbolKind kind = SymbolKind::Unknown; @@ -258,4 +290,10 @@ void MessageHandler::textDocument_semanticTokensFull( reply(result); } +void MessageHandler::textDocument_semanticTokensFull( + SemanticTokensParams ¶m, ReplyOnce &reply){ + lsRange fullRange{documentBegin, documentEnd}; + SemanticTokensRangeParams fullRangeParameters{param.textDocument, fullRange}; + textDocument_semanticTokensRange(fullRangeParameters, reply); +} } // namespace ccls diff --git a/src/query.hh b/src/query.hh index dee5ff52..37dbd9c3 100644 --- a/src/query.hh +++ b/src/query.hh @@ -42,8 +42,9 @@ struct QueryFile { int id = -1; std::optional def; - // `extent` is valid => declaration; invalid => regular reference - llvm::DenseMap symbol2refcnt; + //! `extent` is valid => declaration; invalid => regular reference + using SymbolToRefCount=llvm::DenseMap; + SymbolToRefCount symbol2refcnt; }; template struct QueryEntity {