$ccls/publishSemanticHighlighting: use pair<int,int> in place of lsRange

This commit is contained in:
Fangrui Song 2018-07-08 19:56:33 -07:00
parent 0a304096df
commit 7d1d4b410b
3 changed files with 153 additions and 120 deletions

View File

@ -534,11 +534,13 @@ public:
off |= 1u << 31;
Loc = SourceLocation::getFromRawEncoding(off);
}
#else
FileID LocFID;
#endif
SourceLocation Spell = SM.getSpellingLoc(Loc);
Loc = SM.getFileLoc(Loc);
Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc));
FileID LocFID = SM.getFileID(Loc);
LocFID = SM.getFileID(Loc);
const FileEntry *FE = SM.getFileEntryForID(LocFID);
if (!FE) {
// TODO

View File

@ -1,9 +1,9 @@
#include "message_handler.h"
#include "log.hh"
#include "pipeline.hh"
#include "project.h"
#include "query_utils.h"
#include "pipeline.hh"
using namespace ccls;
using namespace clang;
@ -45,13 +45,11 @@ struct ScanLineEvent {
} // namespace
SemanticHighlightSymbolCache::Entry::Entry(
SemanticHighlightSymbolCache* all_caches,
const std::string& path)
SemanticHighlightSymbolCache *all_caches, const std::string &path)
: all_caches_(all_caches), path(path) {}
std::optional<int> SemanticHighlightSymbolCache::Entry::TryGetStableId(
SymbolKind kind,
const std::string& detailed_name) {
SymbolKind kind, const std::string &detailed_name) {
TNameToId *map = GetMapForSymbol_(kind);
auto it = map->find(detailed_name);
if (it != map->end())
@ -61,8 +59,7 @@ std::optional<int> SemanticHighlightSymbolCache::Entry::TryGetStableId(
}
int SemanticHighlightSymbolCache::Entry::GetStableId(
SymbolKind kind,
const std::string& detailed_name) {
SymbolKind kind, const std::string &detailed_name) {
std::optional<int> id = TryGetStableId(kind, detailed_name);
if (id)
return *id;
@ -126,12 +123,9 @@ MessageHandler::MessageHandler() {
// static
std::vector<MessageHandler *> *MessageHandler::message_handlers = nullptr;
bool FindFileOrFail(DB* db,
Project* project,
std::optional<lsRequestId> id,
bool FindFileOrFail(DB *db, Project *project, std::optional<lsRequestId> id,
const std::string &absolute_path,
QueryFile** out_query_file,
int* out_file_id) {
QueryFile **out_query_file, int *out_file_id) {
*out_query_file = nullptr;
auto it = db->name2file_id.find(LowerPathIfInsensitive(absolute_path));
@ -189,8 +183,7 @@ void EmitSkippedRanges(WorkingFile *working_file,
void EmitSemanticHighlighting(DB *db,
SemanticHighlightSymbolCache *semantic_cache,
WorkingFile* wfile,
QueryFile* file) {
WorkingFile *wfile, QueryFile *file) {
assert(file->def);
if (wfile->buffer_content.size() > g_config->largeFileSize ||
!semantic_cache->match_->IsMatch(file->def->path))
@ -287,7 +280,7 @@ void EmitSemanticHighlighting(DB* db,
if (loc) {
auto it = grouped_symbols.find(sym);
if (it != grouped_symbols.end()) {
it->second.ranges.push_back(*loc);
it->second.lsRanges.push_back(*loc);
} else {
Out_CclsPublishSemanticHighlighting::Symbol symbol;
symbol.stableId = semantic_cache_for_file->GetStableId(
@ -295,7 +288,7 @@ void EmitSemanticHighlighting(DB* db,
symbol.parentKind = parent_kind;
symbol.kind = kind;
symbol.storage = storage;
symbol.ranges.push_back(*loc);
symbol.lsRanges.push_back(*loc);
grouped_symbols[sym] = symbol;
}
}
@ -306,7 +299,7 @@ void EmitSemanticHighlighting(DB* db,
int id = 0;
for (auto &entry : grouped_symbols) {
Out_CclsPublishSemanticHighlighting::Symbol &symbol = entry.second;
for (auto& loc : symbol.ranges) {
for (auto &loc : symbol.lsRanges) {
// For ranges sharing the same start point, the one with leftmost end
// point comes first.
events.push_back({loc.start, loc.end, id, &symbol});
@ -316,7 +309,7 @@ void EmitSemanticHighlighting(DB* db,
events.push_back({loc.end, loc.end, ~id, &symbol});
id++;
}
symbol.ranges.clear();
symbol.lsRanges.clear();
}
std::sort(events.begin(), events.end());
@ -332,19 +325,54 @@ void EmitSemanticHighlighting(DB* db,
// Attribute range [events[i-1].pos, events[i].pos) to events[top-1].symbol
// .
if (top && !(events[i - 1].pos == events[i].pos))
events[top - 1].symbol->ranges.push_back(
lsRange{events[i - 1].pos, events[i].pos});
events[top - 1].symbol->lsRanges.push_back(
{events[i - 1].pos, events[i].pos});
if (events[i].id >= 0)
events[top++] = events[i];
else
deleted[~events[i].id] = 1;
}
// Publish.
Out_CclsPublishSemanticHighlighting out;
out.params.uri = lsDocumentUri::FromPath(wfile->filename);
// Transform lsRange into pair<int, int> (offset pairs)
{
std::vector<std::pair<lsRange, Out_CclsPublishSemanticHighlighting::Symbol *>>
scratch;
for (auto &entry : grouped_symbols)
for (auto &range : entry.second.lsRanges)
scratch.emplace_back(range, &entry.second);
std::sort(scratch.begin(), scratch.end(),
[](auto &l, auto &r) { return l.first.start < r.first.start; });
const auto &buf = wfile->buffer_content;
int l = 0, c = 0, i = 0;
auto mov = [&](int line, int col) {
if (l < line)
c = 0;
for (; l < line && i < buf.size(); i++)
if (buf[i] == '\n')
l++;
if (l < line) return true;
for (; c < col && i < buf.size(); c++)
if (uint8_t(buf[i++]) >= 128)
// Skip 0b10xxxxxx
while (i < buf.size() && uint8_t(buf[i]) >= 128 && uint8_t(buf[i]) < 192)
i++;
return c < col;
};
for (auto &entry : scratch) {
lsRange &r = entry.first;
if (mov(r.start.line, r.start.character))
continue;
int beg = i;
if (mov(r.end.line, r.end.character))
continue;
entry.second->ranges.emplace_back(beg, i);
}
}
for (auto &entry : grouped_symbols)
if (entry.second.ranges.size())
out.params.symbols.push_back(entry.second);
out.params.symbols.push_back(std::move(entry.second));
pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out);
}

View File

@ -64,7 +64,10 @@ struct Out_CclsPublishSemanticHighlighting
lsSymbolKind parentKind;
lsSymbolKind kind;
clang::StorageClass storage;
std::vector<lsRange> ranges;
std::vector<std::pair<int, int>> ranges;
// `lsRanges` is used to compute `ranges`.
std::vector<lsRange> lsRanges;
};
struct Params {
lsDocumentUri uri;