Simplify semantic highlighting; improve hover of auto &&

This commit is contained in:
Fangrui Song 2018-09-24 10:56:29 -07:00
parent d425e15cdb
commit 058ac08621
6 changed files with 31 additions and 65 deletions

View File

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

View File

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

View File

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

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

View File

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

View File

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