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"
This commit is contained in:
Felipe Lema 2021-05-03 12:51:04 -04:00
parent 661870a502
commit 84a00f6371
5 changed files with 52 additions and 5 deletions

View File

@ -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);

View File

@ -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<TextEdit> 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 &);

View File

@ -135,6 +135,7 @@ struct ServerCap {
std::vector<const char *> tokenTypes = SEMANTIC_TOKENS;
std::vector<const char *> 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 {

View File

@ -56,9 +56,34 @@ struct ScanLineEvent {
};
}
constexpr Position documentBegin{0,0};
constexpr Position documentEnd{
std::numeric_limits<decltype(Position::line)>::max(),
std::numeric_limits<decltype(Position::character)>::max()};
void MessageHandler::textDocument_semanticTokensFull(
SemanticTokensParams &param, 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 &param, 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 &param, ReplyOnce &reply){
lsRange fullRange{documentBegin, documentEnd};
SemanticTokensRangeParams fullRangeParameters{param.textDocument, fullRange};
textDocument_semanticTokensRange(fullRangeParameters, reply);
}
} // namespace ccls

View File

@ -42,8 +42,9 @@ struct QueryFile {
int id = -1;
std::optional<Def> def;
// `extent` is valid => declaration; invalid => regular reference
llvm::DenseMap<ExtentRef, int> symbol2refcnt;
//! `extent` is valid => declaration; invalid => regular reference
using SymbolToRefCount=llvm::DenseMap<ExtentRef, int>;
SymbolToRefCount symbol2refcnt;
};
template <typename Q, typename QDef> struct QueryEntity {