[clangd] Expose the xref's incomplete flag to clangdServer API.

Summary: so that clangd C++ API users (via ClangdServer) can access it.

Reviewers: sammccall

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D70380
This commit is contained in:
Haojian Wu 2019-11-18 11:35:00 +01:00
parent 1e3cc06d98
commit 5181adab61
6 changed files with 46 additions and 29 deletions

View File

@ -1152,7 +1152,13 @@ void ClangdLSPServer::onChangeConfiguration(
void ClangdLSPServer::onReference(const ReferenceParams &Params,
Callback<std::vector<Location>> Reply) {
Server->findReferences(Params.textDocument.uri.file(), Params.position,
CCOpts.Limit, std::move(Reply));
CCOpts.Limit,
[Reply = std::move(Reply)](
llvm::Expected<ReferencesResult> Refs) mutable {
if (!Refs)
return Reply(Refs.takeError());
return Reply(std::move(Refs->References));
});
}
void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,

View File

@ -562,7 +562,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File,
}
void ClangdServer::findReferences(PathRef File, Position Pos, uint32_t Limit,
Callback<std::vector<Location>> CB) {
Callback<ReferencesResult> CB) {
auto Action = [Pos, Limit, CB = std::move(CB),
this](llvm::Expected<InputsAndAST> InpAST) mutable {
if (!InpAST)

View File

@ -225,7 +225,7 @@ public:
/// Retrieve locations for symbol references.
void findReferences(PathRef File, Position Pos, uint32_t Limit,
Callback<std::vector<Location>> CB);
Callback<ReferencesResult> CB);
/// Run formatting for \p Rng inside \p File with content \p Code.
llvm::Expected<tooling::Replacements> formatRange(StringRef Code,

View File

@ -883,11 +883,11 @@ llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
return HI;
}
std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
uint32_t Limit, const SymbolIndex *Index) {
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
const SymbolIndex *Index) {
if (!Limit)
Limit = std::numeric_limits<uint32_t>::max();
std::vector<Location> Results;
ReferencesResult Results;
const SourceManager &SM = AST.getSourceManager();
auto MainFilePath =
getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
@ -922,12 +922,11 @@ std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
Location Result;
Result.range = *Range;
Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
Results.push_back(std::move(Result));
Results.References.push_back(std::move(Result));
}
}
// Now query the index for references from other files.
if (Index && Results.size() < Limit) {
if (Index && Results.References.size() <= Limit) {
RefsRequest Req;
Req.Limit = Limit;
@ -942,15 +941,22 @@ std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
}
if (Req.IDs.empty())
return Results;
Index->refs(Req, [&](const Ref &R) {
Results.HasMore |= Index->refs(Req, [&](const Ref &R) {
// no need to continue process if we reach the limit.
if (Results.References.size() > Limit)
return;
auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
// Avoid indexed results for the main file - the AST is authoritative.
if (LSPLoc && LSPLoc->uri.file() != *MainFilePath)
Results.push_back(std::move(*LSPLoc));
if (!LSPLoc || LSPLoc->uri.file() == *MainFilePath)
return;
Results.References.push_back(std::move(*LSPLoc));
});
}
if (Results.size() > Limit)
Results.resize(Limit);
if (Results.References.size() > Limit) {
Results.HasMore = true;
Results.References.resize(Limit);
}
return Results;
}

View File

@ -124,11 +124,14 @@ llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
format::FormatStyle Style,
const SymbolIndex *Index);
/// Returns reference locations of the symbol at a specified \p Pos.
struct ReferencesResult {
std::vector<Location> References;
bool HasMore = false;
};
/// Returns references of the symbol at a specified \p Pos.
/// \p Limit limits the number of results returned (0 means no limit).
std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
uint32_t Limit,
const SymbolIndex *Index = nullptr);
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
const SymbolIndex *Index = nullptr);
/// Get info about symbols at \p Pos.
std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos);

View File

@ -2109,7 +2109,7 @@ TEST(FindReferences, WithinAST) {
std::vector<Matcher<Location>> ExpectedLocations;
for (const auto &R : T.ranges())
ExpectedLocations.push_back(RangeIs(R));
EXPECT_THAT(findReferences(AST, T.point(), 0),
EXPECT_THAT(findReferences(AST, T.point(), 0).References,
ElementsAreArray(ExpectedLocations))
<< Test;
}
@ -2170,7 +2170,7 @@ TEST(FindReferences, ExplicitSymbols) {
for (const auto &R : T.ranges())
ExpectedLocations.push_back(RangeIs(R));
ASSERT_THAT(ExpectedLocations, Not(IsEmpty()));
EXPECT_THAT(findReferences(AST, T.point(), 0),
EXPECT_THAT(findReferences(AST, T.point(), 0).References,
ElementsAreArray(ExpectedLocations))
<< Test;
}
@ -2185,8 +2185,9 @@ TEST(FindReferences, NeedsIndex) {
auto AST = TU.build();
// References in main file are returned without index.
EXPECT_THAT(findReferences(AST, Main.point(), 0, /*Index=*/nullptr),
ElementsAre(RangeIs(Main.range())));
EXPECT_THAT(
findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
ElementsAre(RangeIs(Main.range())));
Annotations IndexedMain(R"cpp(
int main() { [[f^oo]](); }
)cpp");
@ -2196,17 +2197,18 @@ TEST(FindReferences, NeedsIndex) {
IndexedTU.Code = IndexedMain.code();
IndexedTU.Filename = "Indexed.cpp";
IndexedTU.HeaderCode = Header;
EXPECT_THAT(findReferences(AST, Main.point(), 0, IndexedTU.index().get()),
ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
EXPECT_EQ(1u, findReferences(AST, Main.point(), /*Limit*/ 1,
IndexedTU.index().get())
.size());
EXPECT_THAT(
findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
auto LimitRefs =
findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
EXPECT_EQ(1u, LimitRefs.References.size());
EXPECT_TRUE(LimitRefs.HasMore);
// If the main file is in the index, we don't return duplicates.
// (even if the references are in a different location)
TU.Code = ("\n\n" + Main.code()).str();
EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()),
EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()).References,
ElementsAre(RangeIs(Main.range())));
}