mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Simplify semantic highlighting; improve hover of auto &&
This commit is contained in:
parent
d425e15cdb
commit
058ac08621
@ -509,7 +509,8 @@ public:
|
||||
binding = true;
|
||||
}
|
||||
auto BT = GetBaseType(T, false);
|
||||
if (!BT.isNull() && (binding || BT->getAs<AutoType>())) {
|
||||
if (!BT.isNull() &&
|
||||
(binding || BT.getUnqualifiedType()->getAs<AutoType>())) {
|
||||
SmallString<256> Str;
|
||||
llvm::raw_svector_ostream OS(Str);
|
||||
PrintingPolicy PP = GetDefaultPolicy();
|
||||
|
@ -48,34 +48,6 @@ struct ScanLineEvent {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
int SemanticHighlight::GetStableId(SymbolKind kind, Usr usr) {
|
||||
decltype(func2id) *map;
|
||||
switch (kind) {
|
||||
case SymbolKind::Func:
|
||||
map = &func2id;
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
map = &type2id;
|
||||
break;
|
||||
case SymbolKind::Var:
|
||||
map = &var2id;
|
||||
break;
|
||||
case SymbolKind::File:
|
||||
case SymbolKind::Invalid:
|
||||
llvm_unreachable("");
|
||||
}
|
||||
|
||||
auto it = map->try_emplace(usr, next_id);
|
||||
if (it.second)
|
||||
next_id++;
|
||||
return it.first->second;
|
||||
}
|
||||
|
||||
void SemanticHighlight::Init() {
|
||||
match_ = std::make_unique<GroupMatch>(g_config->highlight.whitelist,
|
||||
g_config->highlight.blacklist);
|
||||
}
|
||||
|
||||
MessageHandler::MessageHandler() {
|
||||
// Dynamically allocate |message_handlers|, otherwise there will be static
|
||||
// initialization order races.
|
||||
@ -145,11 +117,12 @@ void EmitSkippedRanges(WorkingFile *working_file,
|
||||
pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out);
|
||||
}
|
||||
|
||||
void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
WorkingFile *wfile, QueryFile *file) {
|
||||
void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) {
|
||||
static GroupMatch match(g_config->highlight.whitelist,
|
||||
g_config->highlight.blacklist);
|
||||
assert(file->def);
|
||||
if (wfile->buffer_content.size() > g_config->largeFileSize ||
|
||||
!highlight->match_->IsMatch(file->def->path))
|
||||
!match.IsMatch(file->def->path))
|
||||
return;
|
||||
|
||||
// Group symbols together.
|
||||
@ -162,10 +135,12 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
|
||||
lsSymbolKind kind = lsSymbolKind::Unknown;
|
||||
uint8_t storage = SC_None;
|
||||
int idx;
|
||||
// This switch statement also filters out symbols that are not highlighted.
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func: {
|
||||
const QueryFunc &func = db->GetFunc(sym);
|
||||
idx = db->func_usr[sym.usr];
|
||||
const QueryFunc &func = db->funcs[idx];
|
||||
const QueryFunc::Def *def = func.AnyDef();
|
||||
if (!def)
|
||||
continue; // applies to for loop
|
||||
@ -206,8 +181,10 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
sym.range.end.column = start_col + concise_name.size();
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Type:
|
||||
for (auto &def : db->GetType(sym).def) {
|
||||
case SymbolKind::Type: {
|
||||
idx = db->type_usr[sym.usr];
|
||||
const QueryType &type = db->types[idx];
|
||||
for (auto &def : type.def) {
|
||||
kind = def.kind;
|
||||
detailed_name = def.detailed_name;
|
||||
if (def.spell) {
|
||||
@ -216,8 +193,10 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
const QueryVar &var = db->GetVar(sym);
|
||||
idx = db->var_usr[sym.usr];
|
||||
const QueryVar &var = db->vars[idx];
|
||||
for (auto &def : var.def) {
|
||||
kind = def.kind;
|
||||
storage = def.storage;
|
||||
@ -246,7 +225,7 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
it->second.lsRanges.push_back(*loc);
|
||||
} else {
|
||||
Out_CclsPublishSemanticHighlighting::Symbol symbol;
|
||||
symbol.stableId = highlight->GetStableId(sym.kind, sym.usr);
|
||||
symbol.stableId = idx;
|
||||
symbol.parentKind = parent_kind;
|
||||
symbol.kind = kind;
|
||||
symbol.storage = storage;
|
||||
|
@ -24,17 +24,6 @@ struct DB;
|
||||
struct WorkingFile;
|
||||
struct WorkingFiles;
|
||||
|
||||
// Caches symbols for a single file for semantic highlighting to provide
|
||||
// relatively stable ids. Only supports xxx files at a time.
|
||||
struct SemanticHighlight {
|
||||
llvm::DenseMap<Usr, int, DenseMapInfoForUsr> func2id, type2id, var2id;
|
||||
uint32_t next_id = 0;
|
||||
std::unique_ptr<GroupMatch> match_;
|
||||
|
||||
void Init();
|
||||
int GetStableId(SymbolKind kind, Usr usr);
|
||||
};
|
||||
|
||||
struct Out_CclsPublishSemanticHighlighting
|
||||
: public lsOutMessage<Out_CclsPublishSemanticHighlighting> {
|
||||
struct Symbol {
|
||||
@ -77,7 +66,6 @@ struct MessageHandler {
|
||||
DB *db = nullptr;
|
||||
Project *project = nullptr;
|
||||
VFS *vfs = nullptr;
|
||||
SemanticHighlight *highlight = nullptr;
|
||||
WorkingFiles *working_files = nullptr;
|
||||
CompletionManager *clang_complete = nullptr;
|
||||
IncludeComplete *include_complete = nullptr;
|
||||
@ -107,5 +95,5 @@ bool FindFileOrFail(DB *db, Project *project, std::optional<lsRequestId> id,
|
||||
void EmitSkippedRanges(WorkingFile *working_file,
|
||||
const std::vector<Range> &skipped_ranges);
|
||||
|
||||
void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight,
|
||||
WorkingFile *working_file, QueryFile *file);
|
||||
void EmitSemanticHighlighting(DB *db, WorkingFile *working_file,
|
||||
QueryFile *file);
|
||||
|
@ -475,7 +475,6 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
|
||||
}
|
||||
|
||||
idx::Init();
|
||||
highlight->Init();
|
||||
|
||||
// Open up / load the project.
|
||||
project->Load(project_path);
|
||||
|
@ -47,7 +47,7 @@ struct Handler_TextDocumentDidOpen
|
||||
FindFileOrFail(db, project, std::nullopt, path, &file);
|
||||
if (file && file->def) {
|
||||
EmitSkippedRanges(working_file, file->def->skipped_ranges);
|
||||
EmitSemanticHighlighting(db, highlight, working_file, file);
|
||||
EmitSemanticHighlighting(db, working_file, file);
|
||||
}
|
||||
|
||||
include_complete->AddFile(working_file->filename);
|
||||
|
@ -356,8 +356,7 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project,
|
||||
indexer_waiter->Wait(index_request);
|
||||
}
|
||||
|
||||
void Main_OnIndexed(DB *db, SemanticHighlight *highlight,
|
||||
WorkingFiles *working_files, IndexUpdate *update) {
|
||||
void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) {
|
||||
if (update->refresh) {
|
||||
LOG_S(INFO)
|
||||
<< "loaded project. Refresh semantic highlight for all working file.";
|
||||
@ -367,7 +366,7 @@ void Main_OnIndexed(DB *db, SemanticHighlight *highlight,
|
||||
if (db->name2file_id.find(filename) == db->name2file_id.end())
|
||||
continue;
|
||||
QueryFile *file = &db->files[db->name2file_id[filename]];
|
||||
EmitSemanticHighlighting(db, highlight, f.get(), file);
|
||||
EmitSemanticHighlighting(db, f.get(), file);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -387,8 +386,7 @@ void Main_OnIndexed(DB *db, SemanticHighlight *highlight,
|
||||
wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content
|
||||
: def_u.second);
|
||||
EmitSkippedRanges(wfile, def_u.first.skipped_ranges);
|
||||
EmitSemanticHighlighting(db, highlight, wfile,
|
||||
&db->files[update->file_id]);
|
||||
EmitSemanticHighlighting(db, wfile, &db->files[update->file_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,7 +456,6 @@ void LaunchStdout() {
|
||||
|
||||
void MainLoop() {
|
||||
Project project;
|
||||
SemanticHighlight highlight;
|
||||
WorkingFiles working_files;
|
||||
VFS vfs;
|
||||
|
||||
@ -490,13 +487,12 @@ void MainLoop() {
|
||||
handler->db = &db;
|
||||
handler->project = &project;
|
||||
handler->vfs = &vfs;
|
||||
handler->highlight = &highlight;
|
||||
handler->working_files = &working_files;
|
||||
handler->clang_complete = &clang_complete;
|
||||
handler->include_complete = &include_complete;
|
||||
}
|
||||
|
||||
bool last_indexed = false;
|
||||
bool has_indexed = false;
|
||||
while (true) {
|
||||
std::vector<std::unique_ptr<InMessage>> messages = on_request->DequeueAll();
|
||||
bool did_work = messages.size();
|
||||
@ -520,15 +516,18 @@ void MainLoop() {
|
||||
break;
|
||||
did_work = true;
|
||||
indexed = true;
|
||||
Main_OnIndexed(&db, &highlight, &working_files, &*update);
|
||||
Main_OnIndexed(&db, &working_files, &*update);
|
||||
}
|
||||
|
||||
if (!did_work) {
|
||||
if (last_indexed)
|
||||
if (did_work)
|
||||
has_indexed |= indexed;
|
||||
else {
|
||||
if (has_indexed) {
|
||||
FreeUnusedMemory();
|
||||
has_indexed = false;
|
||||
}
|
||||
main_waiter->Wait(on_indexed, on_request);
|
||||
}
|
||||
last_indexed = indexed;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user