mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-03 22:04:24 +00:00 
			
		
		
		
	Simplify semantic highlighting; improve hover of auto &&
This commit is contained in:
		
							parent
							
								
									0eb9428a32
								
							
						
					
					
						commit
						41fcc0272c
					
				@ -524,7 +524,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();
 | 
				
			||||||
 | 
				
			|||||||
@ -60,34 +60,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.
 | 
				
			||||||
@ -157,11 +129,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.
 | 
				
			||||||
@ -174,10 +147,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
 | 
				
			||||||
@ -218,8 +193,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) {
 | 
				
			||||||
@ -228,8 +205,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;
 | 
				
			||||||
@ -258,7 +237,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;
 | 
				
			||||||
 | 
				
			|||||||
@ -36,17 +36,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 {
 | 
				
			||||||
@ -89,7 +78,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;
 | 
				
			||||||
@ -119,5 +107,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);
 | 
				
			||||||
 | 
				
			|||||||
@ -487,7 +487,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);
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,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);
 | 
				
			||||||
 | 
				
			|||||||
@ -368,8 +368,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.";
 | 
				
			||||||
@ -379,7 +378,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;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -399,8 +398,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]);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -470,7 +468,6 @@ void LaunchStdout() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void MainLoop() {
 | 
					void MainLoop() {
 | 
				
			||||||
  Project project;
 | 
					  Project project;
 | 
				
			||||||
  SemanticHighlight highlight;
 | 
					 | 
				
			||||||
  WorkingFiles working_files;
 | 
					  WorkingFiles working_files;
 | 
				
			||||||
  VFS vfs;
 | 
					  VFS vfs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -502,13 +499,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();
 | 
				
			||||||
@ -532,15 +528,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