mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 14:17:07 +00:00 
			
		
		
		
	Improve extent of definition/declaration; uniquify typeDefinition
This commit is contained in:
		
							parent
							
								
									87ea7d244d
								
							
						
					
					
						commit
						119a05597d
					
				@ -40,47 +40,56 @@ std::string PathFromFileEntry(const FileEntry &file) {
 | 
				
			|||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Position Decomposed2LineAndCol(const SourceManager &SM,
 | 
				
			||||||
 | 
					                               std::pair<FileID, unsigned> I) {
 | 
				
			||||||
 | 
					  int l = SM.getLineNumber(I.first, I.second) - 1,
 | 
				
			||||||
 | 
					      c = SM.getColumnNumber(I.first, I.second) - 1;
 | 
				
			||||||
 | 
					  return {(int16_t)std::min(l, INT16_MAX), (int16_t)std::min(c, INT16_MAX)};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts,
 | 
					Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts,
 | 
				
			||||||
                          CharSourceRange R,
 | 
					                          CharSourceRange R,
 | 
				
			||||||
                          llvm::sys::fs::UniqueID *UniqueID) {
 | 
					                          llvm::sys::fs::UniqueID *UniqueID) {
 | 
				
			||||||
  SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd();
 | 
					  SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd();
 | 
				
			||||||
  std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
 | 
					  std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc),
 | 
				
			||||||
  std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
 | 
					                              EInfo = SM.getDecomposedLoc(ELoc);
 | 
				
			||||||
  if (R.isTokenRange())
 | 
					  if (R.isTokenRange())
 | 
				
			||||||
    EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts);
 | 
					    EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts);
 | 
				
			||||||
  unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1,
 | 
					 | 
				
			||||||
           c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1,
 | 
					 | 
				
			||||||
           l1 = SM.getLineNumber(EInfo.first, EInfo.second) - 1,
 | 
					 | 
				
			||||||
           c1 = SM.getColumnNumber(EInfo.first, EInfo.second) - 1;
 | 
					 | 
				
			||||||
  if (l0 > INT16_MAX)
 | 
					 | 
				
			||||||
    l0 = 0;
 | 
					 | 
				
			||||||
  if (c0 > INT16_MAX)
 | 
					 | 
				
			||||||
    c0 = 0;
 | 
					 | 
				
			||||||
  if (l1 > INT16_MAX)
 | 
					 | 
				
			||||||
    l1 = 0;
 | 
					 | 
				
			||||||
  if (c1 > INT16_MAX)
 | 
					 | 
				
			||||||
    c1 = 0;
 | 
					 | 
				
			||||||
  if (UniqueID) {
 | 
					  if (UniqueID) {
 | 
				
			||||||
    if (const FileEntry *F = SM.getFileEntryForID(BInfo.first))
 | 
					    if (const FileEntry *F = SM.getFileEntryForID(BInfo.first))
 | 
				
			||||||
      *UniqueID = F->getUniqueID();
 | 
					      *UniqueID = F->getUniqueID();
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      *UniqueID = llvm::sys::fs::UniqueID(0, 0);
 | 
					      *UniqueID = llvm::sys::fs::UniqueID(0, 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}};
 | 
					  return {Decomposed2LineAndCol(SM, BInfo), Decomposed2LineAndCol(SM, EInfo)};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts,
 | 
					Range FromCharRange(const SourceManager &SM, const LangOptions &Lang,
 | 
				
			||||||
                    SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
 | 
					                    SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
 | 
				
			||||||
  return FromCharSourceRange(SM, LangOpts, CharSourceRange::getCharRange(R),
 | 
					  return FromCharSourceRange(SM, Lang, CharSourceRange::getCharRange(R),
 | 
				
			||||||
                             UniqueID);
 | 
					                             UniqueID);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts,
 | 
					Range FromTokenRange(const SourceManager &SM, const LangOptions &Lang,
 | 
				
			||||||
                     SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
 | 
					                     SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
 | 
				
			||||||
  return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R),
 | 
					  return FromCharSourceRange(SM, Lang, CharSourceRange::getTokenRange(R),
 | 
				
			||||||
                             UniqueID);
 | 
					                             UniqueID);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang,
 | 
				
			||||||
 | 
					                              SourceRange R, const FileEntry *FE, Range range) {
 | 
				
			||||||
 | 
					  auto I = SM.getDecomposedLoc(SM.getExpansionLoc(R.getBegin()));
 | 
				
			||||||
 | 
					  if (SM.getFileEntryForID(I.first) == FE)
 | 
				
			||||||
 | 
					    range.start = Decomposed2LineAndCol(SM, I);
 | 
				
			||||||
 | 
					  SourceLocation L = SM.getExpansionLoc(R.getEnd());
 | 
				
			||||||
 | 
					  I = SM.getDecomposedLoc(L);
 | 
				
			||||||
 | 
					  if (SM.getFileEntryForID(I.first) == FE) {
 | 
				
			||||||
 | 
					    I.second += Lexer::MeasureTokenLength(L, SM, Lang);
 | 
				
			||||||
 | 
					    range.end = Decomposed2LineAndCol(SM, I);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return range;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<CompilerInvocation>
 | 
					std::unique_ptr<CompilerInvocation>
 | 
				
			||||||
BuildCompilerInvocation(std::vector<const char *> args,
 | 
					BuildCompilerInvocation(std::vector<const char *> args,
 | 
				
			||||||
                        IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
 | 
					                        IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,11 @@ Range FromTokenRange(const clang::SourceManager &SM,
 | 
				
			|||||||
                     const clang::LangOptions &LangOpts, clang::SourceRange R,
 | 
					                     const clang::LangOptions &LangOpts, clang::SourceRange R,
 | 
				
			||||||
                     llvm::sys::fs::UniqueID *UniqueID = nullptr);
 | 
					                     llvm::sys::fs::UniqueID *UniqueID = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Range FromTokenRangeDefaulted(const clang::SourceManager &SM,
 | 
				
			||||||
 | 
					                              const clang::LangOptions &Lang,
 | 
				
			||||||
 | 
					                              clang::SourceRange R, const clang::FileEntry *FE,
 | 
				
			||||||
 | 
					                              Range range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<clang::CompilerInvocation>
 | 
					std::unique_ptr<clang::CompilerInvocation>
 | 
				
			||||||
BuildCompilerInvocation(std::vector<const char *> args,
 | 
					BuildCompilerInvocation(std::vector<const char *> args,
 | 
				
			||||||
                        llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
 | 
					                        llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
 | 
				
			||||||
 | 
				
			|||||||
@ -785,19 +785,18 @@ public:
 | 
				
			|||||||
    Usr usr = GetUsr(D, &info);
 | 
					    Usr usr = GetUsr(D, &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto do_def_decl = [&](auto *entity) {
 | 
					    auto do_def_decl = [&](auto *entity) {
 | 
				
			||||||
 | 
					      Use use{{loc, role}, lid};
 | 
				
			||||||
      if (is_def) {
 | 
					      if (is_def) {
 | 
				
			||||||
        SourceRange R = OrigD->getSourceRange();
 | 
					        SourceRange R = OrigD->getSourceRange();
 | 
				
			||||||
        entity->def.spell = {
 | 
					        entity->def.spell = {use,
 | 
				
			||||||
            Use{{loc, role}, lid},
 | 
					                             FromTokenRangeDefaulted(SM, Lang, R, FE, loc)};
 | 
				
			||||||
            R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc};
 | 
					 | 
				
			||||||
        GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind);
 | 
					        GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind);
 | 
				
			||||||
      } else if (is_decl) {
 | 
					      } else if (is_decl) {
 | 
				
			||||||
        DeclRef &dr = entity->declarations.emplace_back();
 | 
					 | 
				
			||||||
        static_cast<Use&>(dr) = {{loc, role}, lid};
 | 
					 | 
				
			||||||
        SourceRange R = OrigD->getSourceRange();
 | 
					        SourceRange R = OrigD->getSourceRange();
 | 
				
			||||||
        dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc;
 | 
					        entity->declarations.push_back(
 | 
				
			||||||
 | 
					            {use, FromTokenRangeDefaulted(SM, Lang, R, FE, loc)});
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        entity->uses.push_back({{loc, role}, lid});
 | 
					        entity->uses.push_back(use);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (entity->def.comments[0] == '\0' && g_config->index.comments)
 | 
					      if (entity->def.comments[0] == '\0' && g_config->index.comments)
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,18 @@ MAKE_REFLECT_STRUCT(In_CclsNavigate::Params, textDocument, position, direction);
 | 
				
			|||||||
MAKE_REFLECT_STRUCT(In_CclsNavigate, id, params);
 | 
					MAKE_REFLECT_STRUCT(In_CclsNavigate, id, params);
 | 
				
			||||||
REGISTER_IN_MESSAGE(In_CclsNavigate);
 | 
					REGISTER_IN_MESSAGE(In_CclsNavigate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Maybe<Range> FindParent(QueryFile *file, Position pos) {
 | 
				
			||||||
 | 
					  Maybe<Range> parent;
 | 
				
			||||||
 | 
					  for (auto [sym, refcnt] : file->symbol2refcnt)
 | 
				
			||||||
 | 
					    if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos &&
 | 
				
			||||||
 | 
					        pos < sym.extent.end &&
 | 
				
			||||||
 | 
					        (!parent || (parent->start == sym.extent.start
 | 
				
			||||||
 | 
					                         ? parent->end < sym.extent.end
 | 
				
			||||||
 | 
					                         : parent->start < sym.extent.start)))
 | 
				
			||||||
 | 
					      parent = sym.extent;
 | 
				
			||||||
 | 
					  return parent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Handler_CclsNavigate : BaseMessageHandler<In_CclsNavigate> {
 | 
					struct Handler_CclsNavigate : BaseMessageHandler<In_CclsNavigate> {
 | 
				
			||||||
  MethodType GetMethodType() const override { return kMethodType; }
 | 
					  MethodType GetMethodType() const override { return kMethodType; }
 | 
				
			||||||
  void Run(In_CclsNavigate *request) override {
 | 
					  void Run(In_CclsNavigate *request) override {
 | 
				
			||||||
@ -54,11 +66,7 @@ struct Handler_CclsNavigate : BaseMessageHandler<In_CclsNavigate> {
 | 
				
			|||||||
    Maybe<Range> res;
 | 
					    Maybe<Range> res;
 | 
				
			||||||
    switch (params.direction[0]) {
 | 
					    switch (params.direction[0]) {
 | 
				
			||||||
    case 'D': {
 | 
					    case 'D': {
 | 
				
			||||||
      Maybe<Range> parent;
 | 
					      Maybe<Range> parent = FindParent(file, pos);
 | 
				
			||||||
      for (auto [sym, refcnt] : file->symbol2refcnt)
 | 
					 | 
				
			||||||
        if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos &&
 | 
					 | 
				
			||||||
            pos < sym.extent.end && (!parent || parent->start < sym.extent.start))
 | 
					 | 
				
			||||||
          parent = sym.extent;
 | 
					 | 
				
			||||||
      for (auto [sym, refcnt] : file->symbol2refcnt)
 | 
					      for (auto [sym, refcnt] : file->symbol2refcnt)
 | 
				
			||||||
        if (refcnt > 0 && pos < sym.extent.start &&
 | 
					        if (refcnt > 0 && pos < sym.extent.start &&
 | 
				
			||||||
            (!parent || sym.extent.end <= parent->end) &&
 | 
					            (!parent || sym.extent.end <= parent->end) &&
 | 
				
			||||||
@ -74,11 +82,7 @@ struct Handler_CclsNavigate : BaseMessageHandler<In_CclsNavigate> {
 | 
				
			|||||||
          res = sym.extent;
 | 
					          res = sym.extent;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case 'R': {
 | 
					    case 'R': {
 | 
				
			||||||
      Maybe<Range> parent;
 | 
					      Maybe<Range> parent = FindParent(file, pos);
 | 
				
			||||||
      for (auto [sym, refcnt] : file->symbol2refcnt)
 | 
					 | 
				
			||||||
        if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos &&
 | 
					 | 
				
			||||||
            pos < sym.extent.end && (!parent || parent->start < sym.extent.start))
 | 
					 | 
				
			||||||
          parent = sym.extent;
 | 
					 | 
				
			||||||
      if (parent && parent->start.line == pos.line && pos < parent->end) {
 | 
					      if (parent && parent->start.line == pos.line && pos < parent->end) {
 | 
				
			||||||
        pos = parent->end;
 | 
					        pos = parent->end;
 | 
				
			||||||
        if (pos.column)
 | 
					        if (pos.column)
 | 
				
			||||||
 | 
				
			|||||||
@ -74,6 +74,8 @@ struct Handler_TextDocumentTypeDefinition
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::sort(result.begin(), result.end());
 | 
				
			||||||
 | 
					    result.erase(std::unique(result.begin(), result.end()), result.end());
 | 
				
			||||||
    pipeline::Reply(request->id, result);
 | 
					    pipeline::Reply(request->id, result);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user