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;
 | 
			
		||||
    }
 | 
			
		||||
    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();
 | 
			
		||||
 | 
			
		||||
@ -60,34 +60,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.
 | 
			
		||||
@ -157,11 +129,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.
 | 
			
		||||
@ -174,10 +147,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
 | 
			
		||||
@ -218,8 +193,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) {
 | 
			
		||||
@ -228,8 +205,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;
 | 
			
		||||
@ -258,7 +237,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;
 | 
			
		||||
 | 
			
		||||
@ -36,17 +36,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 {
 | 
			
		||||
@ -89,7 +78,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;
 | 
			
		||||
@ -119,5 +107,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);
 | 
			
		||||
 | 
			
		||||
@ -487,7 +487,6 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    idx::Init();
 | 
			
		||||
    highlight->Init();
 | 
			
		||||
 | 
			
		||||
    // Open up / load the project.
 | 
			
		||||
    project->Load(project_path);
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,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);
 | 
			
		||||
 | 
			
		||||
@ -368,8 +368,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.";
 | 
			
		||||
@ -379,7 +378,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;
 | 
			
		||||
  }
 | 
			
		||||
@ -399,8 +398,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]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -470,7 +468,6 @@ void LaunchStdout() {
 | 
			
		||||
 | 
			
		||||
void MainLoop() {
 | 
			
		||||
  Project project;
 | 
			
		||||
  SemanticHighlight highlight;
 | 
			
		||||
  WorkingFiles working_files;
 | 
			
		||||
  VFS vfs;
 | 
			
		||||
 | 
			
		||||
@ -502,13 +499,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();
 | 
			
		||||
@ -532,15 +528,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