handle TODOs, imprve readbility

This commit is contained in:
Felipe Lema 2021-04-12 14:33:19 -04:00
parent ca51f9eb4a
commit 554833abf2

View File

@ -23,7 +23,8 @@ struct SemanticTokens {
REFLECT_STRUCT(SemanticTokens, data); REFLECT_STRUCT(SemanticTokens, data);
struct CclsSemanticHighlightSymbol { struct CclsSemanticHighlightSymbol {
int id = 0; using Id=int;
Id id = 0;
SymbolKind parentKind; SymbolKind parentKind;
SymbolKind kind; SymbolKind kind;
uint8_t storage; uint8_t storage;
@ -33,7 +34,8 @@ struct CclsSemanticHighlightSymbol {
struct ScanLineEvent { struct ScanLineEvent {
Position pos; Position pos;
Position end_pos; // Second key when there is a tie for insertion events. Position end_pos; // Second key when there is a tie for insertion events.
int id; using Id=int;
Id id;
CclsSemanticHighlightSymbol *symbol; CclsSemanticHighlightSymbol *symbol;
Role role; Role role;
bool operator<(const ScanLineEvent &o) const { bool operator<(const ScanLineEvent &o) const {
@ -63,9 +65,9 @@ void MessageHandler::textDocument_semanticTokensFull(
return; return;
} }
QueryFile *file = findFile(path); auto [queryFile,wFile] = findOrFail(path, reply);
if (!file) { if (!queryFile) {
reply.notOpened(path); //TODO // `findOrFail` already set the reply message
return; return;
} }
@ -75,21 +77,21 @@ void MessageHandler::textDocument_semanticTokensFull(
g_config->highlight.blacklist); g_config->highlight.blacklist);
assert(file->def); assert(file->def);
if (wfile->buffer_content.size() > g_config->highlight.largeFileSize || if (wfile->buffer_content.size() > g_config->highlight.largeFileSize ||
!match.matches(file->def->path)) { !match.matches(queryFile->def->path)) {
reply.notOpened(path); //TODO LOG_V(INFO) << "Not SemTokenizing " << path << "because of allowlist/denylist";
return; //TODO? return;
} }
// Group symbols together. // Group symbols together.
std::unordered_map<SymbolIdx, CclsSemanticHighlightSymbol> grouped_symbols; std::unordered_map<SymbolIdx, CclsSemanticHighlightSymbol> grouped_symbols;
for (auto [sym, refcnt] : file->symbol2refcnt) { for (auto [sym, refcnt] : queryFile->symbol2refcnt) {
if (refcnt <= 0) //TODO: unused? if (refcnt <= 0)
continue; continue;
std::string_view detailed_name; std::string_view detailed_name;
SymbolKind parent_kind = SymbolKind::Unknown; SymbolKind parent_kind = SymbolKind::Unknown;
SymbolKind kind = SymbolKind::Unknown; SymbolKind kind = SymbolKind::Unknown;
uint8_t storage = SC_None; uint8_t storage = SC_None;
int idx; DB::UsrIndex idx;
// This switch statement also filters out symbols that are not highlighted. // This switch statement also filters out symbols that are not highlighted.
switch (sym.kind) { switch (sym.kind) {
case Kind::Func: { case Kind::Func: {
@ -100,7 +102,7 @@ void MessageHandler::textDocument_semanticTokensFull(
continue; // applies to for loop continue; // applies to for loop
// Don't highlight overloadable operators or implicit lambda -> // Don't highlight overloadable operators or implicit lambda ->
// std::function constructor. // std::function constructor.
std::string_view short_name = def->name(false); const auto short_name = def->name(false);
if (short_name.compare(0, 8, "operator") == 0) if (short_name.compare(0, 8, "operator") == 0)
continue; // applies to for loop continue; // applies to for loop
kind = def->kind; kind = def->kind;
@ -112,14 +114,14 @@ void MessageHandler::textDocument_semanticTokensFull(
// If not, do not publish the semantic highlight. // If not, do not publish the semantic highlight.
// E.g. copy-initialization of constructors should not be highlighted // E.g. copy-initialization of constructors should not be highlighted
// but we still want to keep the range for jumping to definition. // but we still want to keep the range for jumping to definition.
std::string_view concise_name = const auto concise_name =
detailed_name.substr(0, detailed_name.find('<')); detailed_name.substr(0, detailed_name.find('<'));
uint16_t start_line = sym.range.start.line; const auto start_line_idx = sym.range.start.line;
int16_t start_col = sym.range.start.column; const auto start_col = sym.range.start.column;
if (start_line >= wfile->index_lines.size()) if (start_line_idx >= wfile->index_lines.size()) // out-of-range ?
continue; continue;
std::string_view line = wfile->index_lines[start_line]; const auto line = wfile->index_lines[start_line_idx];
sym.range.end.line = start_line; sym.range.end.line = start_line_idx;
if (!(start_col + concise_name.size() <= line.size() && if (!(start_col + concise_name.size() <= line.size() &&
line.compare(start_col, concise_name.size(), concise_name) == 0)) line.compare(start_col, concise_name.size(), concise_name) == 0))
continue; continue;
@ -157,10 +159,10 @@ void MessageHandler::textDocument_semanticTokensFull(
continue; // applies to for loop continue; // applies to for loop
} }
if (std::optional<lsRange> loc = getLsRange(wfile, sym.range)) { if (auto maybe_loc = getLsRange(wfile, sym.range)) {
auto it = grouped_symbols.find(sym); auto it = grouped_symbols.find(sym);
if (it != grouped_symbols.end()) { if (it != grouped_symbols.end()) {
it->second.lsRangeAndRoles.push_back({*loc, sym.role}); it->second.lsRangeAndRoles.push_back({*maybe_loc, sym.role});
} else { } else {
CclsSemanticHighlightSymbol symbol; CclsSemanticHighlightSymbol symbol;
symbol.id = idx; symbol.id = idx;
@ -175,7 +177,7 @@ void MessageHandler::textDocument_semanticTokensFull(
// Make ranges non-overlapping using a scan line algorithm. // Make ranges non-overlapping using a scan line algorithm.
std::vector<ScanLineEvent> events; std::vector<ScanLineEvent> events;
int id = 0; ScanLineEvent::Id id = 0;
for (auto &entry : grouped_symbols) { for (auto &entry : grouped_symbols) {
CclsSemanticHighlightSymbol &symbol = entry.second; CclsSemanticHighlightSymbol &symbol = entry.second;
for (auto &loc : symbol.lsRangeAndRoles) { for (auto &loc : symbol.lsRangeAndRoles) {
@ -213,44 +215,44 @@ void MessageHandler::textDocument_semanticTokensFull(
} }
// Transform lsRange into pair<int, int> (offset pairs) // Transform lsRange into pair<int, int> (offset pairs)
std::vector<std::pair<std::pair<lsRange, Role>, CclsSemanticHighlightSymbol *>> scratch; std::vector<std::pair<std::pair<lsRange, Role>, CclsSemanticHighlightSymbol *>> scratch;
for (auto &entry : grouped_symbols) { for (auto &entry : grouped_symbols) {
for (auto &range : entry.second.lsRangeAndRoles) for (auto &range : entry.second.lsRangeAndRoles)
scratch.emplace_back(range, &entry.second); scratch.emplace_back(range, &entry.second);
entry.second.lsRangeAndRoles.clear(); entry.second.lsRangeAndRoles.clear();
}
std::sort(scratch.begin(), scratch.end(),
[](auto &l, auto &r) { return l.first.first.start < r.first.first.start; });
int line = 0;
int column = 0;
for (auto &entry : scratch) {
lsRange &r = entry.first.first;
if (r.start.line != line) {
column = 0;
} }
std::sort(scratch.begin(), scratch.end(), result.data.push_back(r.start.line - line); line = r.start.line;
[](auto &l, auto &r) { return l.first.first.start < r.first.first.start; }); result.data.push_back(r.start.character - column); column = r.start.character;
int line = 0; result.data.push_back(r.end.character - r.start.character);
int column = 0; uint8_t kindId;
for (auto &entry : scratch) { int modifiers = entry.second->storage == SC_Static ? 4 : 0;
lsRange &r = entry.first.first; if (entry.first.second & Role::Declaration) {
if (r.start.line != line) { modifiers |= 1;
column = 0;
}
result.data.push_back(r.start.line - line); line = r.start.line;
result.data.push_back(r.start.character - column); column = r.start.character;
result.data.push_back(r.end.character - r.start.character);
uint8_t kindId;
int modifiers = entry.second->storage == SC_Static ? 4 : 0;
if (entry.first.second & Role::Declaration) {
modifiers |= 1;
}
if (entry.first.second & Role::Definition) {
modifiers |= 2;
}
if (entry.second->kind == SymbolKind::StaticMethod) {
kindId = (uint8_t) SymbolKind::Method;
modifiers = 4;
} else {
kindId = (uint8_t) entry.second->kind;
if (kindId > (uint8_t) SymbolKind::StaticMethod)
kindId--;
if (kindId >= 252) kindId = 27 + kindId - 252;
}
result.data.push_back(kindId);
result.data.push_back(modifiers);
} }
if (entry.first.second & Role::Definition) {
modifiers |= 2;
}
if (entry.second->kind == SymbolKind::StaticMethod) {
kindId = (uint8_t) SymbolKind::Method;
modifiers = 4;
} else {
kindId = (uint8_t) entry.second->kind;
if (kindId > (uint8_t) SymbolKind::StaticMethod)
kindId--;
if (kindId >= 252) kindId = 27 + kindId - 252;
}
result.data.push_back(kindId);
result.data.push_back(modifiers);
}
reply(result); reply(result);
} }