From cff6c4714cf37ff3f90e4f41c797177bb27a427f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 24 Sep 2018 10:56:29 -0700 Subject: [PATCH] Simplify semantic highlighting; improve hover of auto && --- src/indexer.cc | 3 +- src/message_handler.cc | 51 ++++++++-------------------- src/message_handler.h | 16 ++------- src/messages/initialize.cc | 1 - src/messages/textDocument_didOpen.cc | 2 +- src/pipeline.cc | 23 ++++++------- 6 files changed, 31 insertions(+), 65 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 66441d66..9d7296ff 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -509,7 +509,8 @@ public: binding = true; } auto BT = GetBaseType(T, false); - if (!BT.isNull() && (binding || BT->getAs())) { + if (!BT.isNull() && + (binding || BT.getUnqualifiedType()->getAs())) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP = GetDefaultPolicy(); diff --git a/src/message_handler.cc b/src/message_handler.cc index f5ebd8d3..a8fabe21 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -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(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; diff --git a/src/message_handler.h b/src/message_handler.h index 8c9e5b5f..7d139aa3 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -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 func2id, type2id, var2id; - uint32_t next_id = 0; - std::unique_ptr match_; - - void Init(); - int GetStableId(SymbolKind kind, Usr usr); -}; - struct Out_CclsPublishSemanticHighlighting : public lsOutMessage { 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 id, void EmitSkippedRanges(WorkingFile *working_file, const std::vector &skipped_ranges); -void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, - WorkingFile *working_file, QueryFile *file); +void EmitSemanticHighlighting(DB *db, WorkingFile *working_file, + QueryFile *file); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index ca8f7006..03151efb 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -475,7 +475,6 @@ struct Handler_Initialize : BaseMessageHandler { } idx::Init(); - highlight->Init(); // Open up / load the project. project->Load(project_path); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 26872d1a..794e82f9 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -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); diff --git a/src/pipeline.cc b/src/pipeline.cc index b7b44166..fab84338 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -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> 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; } }