Improve extent of definition/declaration; uniquify typeDefinition

This commit is contained in:
Fangrui Song 2018-10-18 22:11:43 -07:00
parent 46cfd5504a
commit 18b47d3f5c
5 changed files with 56 additions and 36 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -21,6 +21,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 {
@ -42,11 +54,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) &&
@ -62,11 +70,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)

View File

@ -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);
} }
}; };