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