mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 06:15:20 +00:00 
			
		
		
		
	diagnostics; use custom DenseMapInfo
This commit is contained in:
		
							parent
							
								
									68fba7989d
								
							
						
					
					
						commit
						fa8b032301
					
				@ -188,17 +188,15 @@ bool Parse(CompilerInstance &Clang) {
 | 
				
			|||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CompletionPreloadMain(CompletionManager *completion_manager) {
 | 
					void CompletionPreloadMain(CompletionManager *manager) {
 | 
				
			||||||
  while (true) {
 | 
					  while (true) {
 | 
				
			||||||
    // Fetching the completion request blocks until we have a request.
 | 
					    // Fetching the completion request blocks until we have a request.
 | 
				
			||||||
    auto request = completion_manager->preload_requests_.Dequeue();
 | 
					    auto request = manager->preload_requests_.Dequeue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If we don't get a session then that means we don't care about the file
 | 
					    // If we don't get a session then that means we don't care about the file
 | 
				
			||||||
    // anymore - abandon the request.
 | 
					    // anymore - abandon the request.
 | 
				
			||||||
    std::shared_ptr<CompletionSession> session =
 | 
					    std::shared_ptr<CompletionSession> session = manager->TryGetSession(
 | 
				
			||||||
        completion_manager->TryGetSession(request.path,
 | 
					        request.path, false /*mark_as_completion*/, false /*create_if_needed*/);
 | 
				
			||||||
                                          false /*mark_as_completion*/,
 | 
					 | 
				
			||||||
                                          false /*create_if_needed*/);
 | 
					 | 
				
			||||||
    if (!session)
 | 
					    if (!session)
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -210,6 +208,11 @@ void CompletionPreloadMain(CompletionManager *completion_manager) {
 | 
				
			|||||||
    if (std::unique_ptr<CompilerInvocation> CI =
 | 
					    if (std::unique_ptr<CompilerInvocation> CI =
 | 
				
			||||||
            BuildCompilerInvocation(args, session->FS))
 | 
					            BuildCompilerInvocation(args, session->FS))
 | 
				
			||||||
      session->BuildPreamble(*CI);
 | 
					      session->BuildPreamble(*CI);
 | 
				
			||||||
 | 
					    if (g_config->diagnostics.onSave) {
 | 
				
			||||||
 | 
					      lsTextDocumentIdentifier document;
 | 
				
			||||||
 | 
					      document.uri = lsDocumentUri::FromPath(request.path);
 | 
				
			||||||
 | 
					      manager->diagnostic_request_.PushBack({document}, true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -405,7 +408,7 @@ void CompletionManager::DiagnosticsUpdate(
 | 
				
			|||||||
void CompletionManager::NotifyView(const std::string &path) {
 | 
					void CompletionManager::NotifyView(const std::string &path) {
 | 
				
			||||||
  // Only reparse the file if we create a new CompletionSession.
 | 
					  // Only reparse the file if we create a new CompletionSession.
 | 
				
			||||||
  if (EnsureCompletionOrCreatePreloadSession(path))
 | 
					  if (EnsureCompletionOrCreatePreloadSession(path))
 | 
				
			||||||
    preload_requests_.PushBack(PreloadRequest(path), true);
 | 
					    preload_requests_.PushBack(PreloadRequest{path}, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CompletionManager::NotifySave(const std::string &filename) {
 | 
					void CompletionManager::NotifySave(const std::string &filename) {
 | 
				
			||||||
@ -414,7 +417,7 @@ void CompletionManager::NotifySave(const std::string &filename) {
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  EnsureCompletionOrCreatePreloadSession(filename);
 | 
					  EnsureCompletionOrCreatePreloadSession(filename);
 | 
				
			||||||
  preload_requests_.PushBack(PreloadRequest(filename), true);
 | 
					  preload_requests_.PushBack(PreloadRequest{filename}, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CompletionManager::NotifyClose(const std::string &filename) {
 | 
					void CompletionManager::NotifyClose(const std::string &filename) {
 | 
				
			||||||
 | 
				
			|||||||
@ -74,10 +74,6 @@ struct CompletionManager {
 | 
				
			|||||||
  using OnDropped = std::function<void(lsRequestId request_id)>;
 | 
					  using OnDropped = std::function<void(lsRequestId request_id)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct PreloadRequest {
 | 
					  struct PreloadRequest {
 | 
				
			||||||
    PreloadRequest(const std::string &path)
 | 
					 | 
				
			||||||
        : request_time(std::chrono::high_resolution_clock::now()), path(path) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::chrono::time_point<std::chrono::high_resolution_clock> request_time;
 | 
					 | 
				
			||||||
    std::string path;
 | 
					    std::string path;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  struct CompletionRequest {
 | 
					  struct CompletionRequest {
 | 
				
			||||||
 | 
				
			|||||||
@ -37,8 +37,6 @@ struct Handler_TextDocumentDidSave
 | 
				
			|||||||
    Project::Entry entry = project->FindCompilationEntryForFile(path);
 | 
					    Project::Entry entry = project->FindCompilationEntryForFile(path);
 | 
				
			||||||
    pipeline::Index(entry.filename, entry.args, IndexMode::Normal);
 | 
					    pipeline::Index(entry.filename, entry.args, IndexMode::Normal);
 | 
				
			||||||
    clang_complete->NotifySave(path);
 | 
					    clang_complete->NotifySave(path);
 | 
				
			||||||
    if (g_config->diagnostics.onSave)
 | 
					 | 
				
			||||||
      clang_complete->DiagnosticsUpdate(params.textDocument);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave);
 | 
					REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								src/query.cc
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								src/query.cc
									
									
									
									
									
								
							@ -238,36 +238,37 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
 | 
				
			|||||||
        .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta;
 | 
					        .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto UpdateUses = [&](Usr usr, SymbolKind kind,
 | 
					  auto UpdateUses =
 | 
				
			||||||
                        llvm::DenseMap<WrappedUsr, int> &entity_usr,
 | 
					      [&](Usr usr, SymbolKind kind,
 | 
				
			||||||
                        auto &entities, auto &p, bool hint_implicit) {
 | 
					          llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
 | 
				
			||||||
    auto R = entity_usr.try_emplace({usr}, entity_usr.size());
 | 
					          auto &entities, auto &p, bool hint_implicit) {
 | 
				
			||||||
    if (R.second)
 | 
					        auto R = entity_usr.try_emplace(usr, entity_usr.size());
 | 
				
			||||||
      vars.emplace_back().usr = usr;
 | 
					        if (R.second)
 | 
				
			||||||
    auto &entity = entities[R.first->second];
 | 
					          vars.emplace_back().usr = usr;
 | 
				
			||||||
    for (Use &use : p.first) {
 | 
					        auto &entity = entities[R.first->second];
 | 
				
			||||||
      if (hint_implicit && use.role & Role::Implicit) {
 | 
					        for (Use &use : p.first) {
 | 
				
			||||||
        // Make ranges of implicit function calls larger (spanning one more
 | 
					          if (hint_implicit && use.role & Role::Implicit) {
 | 
				
			||||||
        // column to the left/right). This is hacky but useful. e.g.
 | 
					            // Make ranges of implicit function calls larger (spanning one more
 | 
				
			||||||
        // textDocument/definition on the space/semicolon in `A a;` or ` 42;`
 | 
					            // column to the left/right). This is hacky but useful. e.g.
 | 
				
			||||||
        // will take you to the constructor.
 | 
					            // textDocument/definition on the space/semicolon in `A a;` or `
 | 
				
			||||||
        if (use.range.start.column > 0)
 | 
					            // 42;` will take you to the constructor.
 | 
				
			||||||
          use.range.start.column--;
 | 
					            if (use.range.start.column > 0)
 | 
				
			||||||
        use.range.end.column++;
 | 
					              use.range.start.column--;
 | 
				
			||||||
      }
 | 
					            use.range.end.column++;
 | 
				
			||||||
      Ref(prev_lid2file_id, usr, kind, use, -1);
 | 
					          }
 | 
				
			||||||
    }
 | 
					          Ref(prev_lid2file_id, usr, kind, use, -1);
 | 
				
			||||||
    RemoveRange(entity.uses, p.first);
 | 
					        }
 | 
				
			||||||
    for (Use &use : p.second) {
 | 
					        RemoveRange(entity.uses, p.first);
 | 
				
			||||||
      if (hint_implicit && use.role & Role::Implicit) {
 | 
					        for (Use &use : p.second) {
 | 
				
			||||||
        if (use.range.start.column > 0)
 | 
					          if (hint_implicit && use.role & Role::Implicit) {
 | 
				
			||||||
          use.range.start.column--;
 | 
					            if (use.range.start.column > 0)
 | 
				
			||||||
        use.range.end.column++;
 | 
					              use.range.start.column--;
 | 
				
			||||||
      }
 | 
					            use.range.end.column++;
 | 
				
			||||||
      Ref(lid2file_id, usr, kind, use, 1);
 | 
					          }
 | 
				
			||||||
    }
 | 
					          Ref(lid2file_id, usr, kind, use, 1);
 | 
				
			||||||
    AddRange(entity.uses, p.second);
 | 
					        }
 | 
				
			||||||
  };
 | 
					        AddRange(entity.uses, p.second);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (u->files_removed)
 | 
					  if (u->files_removed)
 | 
				
			||||||
    files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def =
 | 
					    files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def =
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										27
									
								
								src/query.h
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/query.h
									
									
									
									
									
								
							@ -136,14 +136,11 @@ struct IndexUpdate {
 | 
				
			|||||||
  UseUpdate vars_uses;
 | 
					  UseUpdate vars_uses;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct WrappedUsr {
 | 
					struct DenseMapInfoForUsr {
 | 
				
			||||||
  Usr usr;
 | 
					  static inline Usr getEmptyKey() { return 0; }
 | 
				
			||||||
};
 | 
					  static inline Usr getTombstoneKey() { return ~0ULL; }
 | 
				
			||||||
template <> struct llvm::DenseMapInfo<WrappedUsr> {
 | 
					  static unsigned getHashValue(Usr w) { return w; }
 | 
				
			||||||
  static inline WrappedUsr getEmptyKey() { return {0}; }
 | 
					  static bool isEqual(Usr l, Usr r) { return l == r; }
 | 
				
			||||||
  static inline WrappedUsr getTombstoneKey() { return {~0ULL}; }
 | 
					 | 
				
			||||||
  static unsigned getHashValue(WrappedUsr w) { return w.usr; }
 | 
					 | 
				
			||||||
  static bool isEqual(WrappedUsr l, WrappedUsr r) { return l.usr == r.usr; }
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Lid2file_id = std::unordered_map<int, int>;
 | 
					using Lid2file_id = std::unordered_map<int, int>;
 | 
				
			||||||
@ -153,7 +150,7 @@ using Lid2file_id = std::unordered_map<int, int>;
 | 
				
			|||||||
struct DB {
 | 
					struct DB {
 | 
				
			||||||
  std::vector<QueryFile> files;
 | 
					  std::vector<QueryFile> files;
 | 
				
			||||||
  llvm::StringMap<int> name2file_id;
 | 
					  llvm::StringMap<int> name2file_id;
 | 
				
			||||||
  llvm::DenseMap<WrappedUsr, int> func_usr, type_usr, var_usr;
 | 
					  llvm::DenseMap<Usr, int, DenseMapInfoForUsr> func_usr, type_usr, var_usr;
 | 
				
			||||||
  std::vector<QueryFunc> funcs;
 | 
					  std::vector<QueryFunc> funcs;
 | 
				
			||||||
  std::vector<QueryType> types;
 | 
					  std::vector<QueryType> types;
 | 
				
			||||||
  std::vector<QueryVar> vars;
 | 
					  std::vector<QueryVar> vars;
 | 
				
			||||||
@ -173,13 +170,13 @@ struct DB {
 | 
				
			|||||||
              std::vector<std::pair<Usr, QueryVar::Def>> &&us);
 | 
					              std::vector<std::pair<Usr, QueryVar::Def>> &&us);
 | 
				
			||||||
  std::string_view GetSymbolName(SymbolIdx sym, bool qualified);
 | 
					  std::string_view GetSymbolName(SymbolIdx sym, bool qualified);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool HasFunc(Usr usr) const { return func_usr.count({usr}); }
 | 
					  bool HasFunc(Usr usr) const { return func_usr.count(usr); }
 | 
				
			||||||
  bool HasType(Usr usr) const { return type_usr.count({usr}); }
 | 
					  bool HasType(Usr usr) const { return type_usr.count(usr); }
 | 
				
			||||||
  bool HasVar(Usr usr) const { return var_usr.count({usr}); }
 | 
					  bool HasVar(Usr usr) const { return var_usr.count(usr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryFunc &Func(Usr usr) { return funcs[func_usr[{usr}]]; }
 | 
					  QueryFunc &Func(Usr usr) { return funcs[func_usr[usr]]; }
 | 
				
			||||||
  QueryType &Type(Usr usr) { return types[type_usr[{usr}]]; }
 | 
					  QueryType &Type(Usr usr) { return types[type_usr[usr]]; }
 | 
				
			||||||
  QueryVar &Var(Usr usr) { return vars[var_usr[{usr}]]; }
 | 
					  QueryVar &Var(Usr usr) { return vars[var_usr[usr]]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; }
 | 
					  QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; }
 | 
				
			||||||
  QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); }
 | 
					  QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); }
 | 
				
			||||||
 | 
				
			|||||||
@ -18,9 +18,9 @@ int ComputeRangeSize(const Range &range) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename Q>
 | 
					template <typename Q>
 | 
				
			||||||
std::vector<Use> GetDeclarations(llvm::DenseMap<WrappedUsr, int> &entity_usr,
 | 
					std::vector<Use>
 | 
				
			||||||
                                 std::vector<Q> &entities,
 | 
					GetDeclarations(llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
 | 
				
			||||||
                                 const std::vector<Usr> &usrs) {
 | 
					                std::vector<Q> &entities, const std::vector<Usr> &usrs) {
 | 
				
			||||||
  std::vector<Use> ret;
 | 
					  std::vector<Use> ret;
 | 
				
			||||||
  ret.reserve(usrs.size());
 | 
					  ret.reserve(usrs.size());
 | 
				
			||||||
  for (Usr usr : usrs) {
 | 
					  for (Usr usr : usrs) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user