mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Improve extent of definition/declaration; uniquify typeDefinition
This commit is contained in:
parent
ca1edb582e
commit
610798f634
@ -28,47 +28,57 @@ std::string PathFromFileEntry(const FileEntry &file) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Position Decomposed2LineAndCol(const SourceManager &SM,
|
||||||
|
std::pair<FileID, unsigned> I) {
|
||||||
|
int l = (int)SM.getLineNumber(I.first, I.second) - 1,
|
||||||
|
c = (int)SM.getColumnNumber(I.first, I.second) - 1;
|
||||||
|
return {(int16_t)std::min<int>(l, INT16_MAX),
|
||||||
|
(int16_t)std::min<int>(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) {
|
||||||
|
@ -32,6 +32,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);
|
||||||
|
@ -770,20 +770,19 @@ 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};
|
|
||||||
entity->def.parent_kind = lsSymbolKind::File;
|
entity->def.parent_kind = lsSymbolKind::File;
|
||||||
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)
|
||||||
|
@ -62,6 +62,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