mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 09:31:59 +08:00
[clangd] Fix one testcase in XRefsTests.
Summary: The test didn't test anything actually -- it used "[]" as annotation which should be "[[]]". This patch also fixes a bug in XRef where we may return duplicated refs. Reviewers: ilya-biryukov Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D66349 llvm-svn: 369387
This commit is contained in:
@@ -370,7 +370,6 @@ namespace {
|
||||
class ReferenceFinder : public index::IndexDataConsumer {
|
||||
public:
|
||||
struct Reference {
|
||||
const Decl *CanonicalTarget;
|
||||
SourceLocation Loc;
|
||||
index::SymbolRoleSet Role;
|
||||
};
|
||||
@@ -384,17 +383,15 @@ public:
|
||||
|
||||
std::vector<Reference> take() && {
|
||||
llvm::sort(References, [](const Reference &L, const Reference &R) {
|
||||
return std::tie(L.Loc, L.CanonicalTarget, L.Role) <
|
||||
std::tie(R.Loc, R.CanonicalTarget, R.Role);
|
||||
return std::tie(L.Loc, L.Role) < std::tie(R.Loc, R.Role);
|
||||
});
|
||||
// We sometimes see duplicates when parts of the AST get traversed twice.
|
||||
References.erase(
|
||||
std::unique(References.begin(), References.end(),
|
||||
[](const Reference &L, const Reference &R) {
|
||||
return std::tie(L.CanonicalTarget, L.Loc, L.Role) ==
|
||||
std::tie(R.CanonicalTarget, R.Loc, R.Role);
|
||||
}),
|
||||
References.end());
|
||||
References.erase(std::unique(References.begin(), References.end(),
|
||||
[](const Reference &L, const Reference &R) {
|
||||
return std::tie(L.Loc, L.Role) ==
|
||||
std::tie(R.Loc, R.Role);
|
||||
}),
|
||||
References.end());
|
||||
return std::move(References);
|
||||
}
|
||||
|
||||
@@ -407,7 +404,7 @@ public:
|
||||
const SourceManager &SM = AST.getSourceManager();
|
||||
Loc = SM.getFileLoc(Loc);
|
||||
if (isInsideMainFile(Loc, SM) && CanonicalTargets.count(D))
|
||||
References.push_back({D, Loc, Roles});
|
||||
References.push_back({Loc, Roles});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -441,6 +438,8 @@ std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
|
||||
// FIXME: show references to macro within file?
|
||||
auto References = findRefs(Symbols.Decls, AST);
|
||||
|
||||
// FIXME: we may get multiple DocumentHighlights with the same location and
|
||||
// different kinds, deduplicate them.
|
||||
std::vector<DocumentHighlight> Result;
|
||||
for (const auto &Ref : References) {
|
||||
if (auto Range =
|
||||
@@ -951,6 +950,15 @@ std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
|
||||
// We traverse the AST to find references in the main file.
|
||||
// TODO: should we handle macros, too?
|
||||
auto MainFileRefs = findRefs(Symbols.Decls, AST);
|
||||
// We may get multiple refs with the same location and different Roles, as
|
||||
// cross-reference is only interested in locations, we deduplicate them
|
||||
// by the location to avoid emitting duplicated locations.
|
||||
MainFileRefs.erase(std::unique(MainFileRefs.begin(), MainFileRefs.end(),
|
||||
[](const ReferenceFinder::Reference &L,
|
||||
const ReferenceFinder::Reference &R) {
|
||||
return L.Loc == R.Loc;
|
||||
}),
|
||||
MainFileRefs.end());
|
||||
for (const auto &Ref : MainFileRefs) {
|
||||
if (auto Range =
|
||||
getTokenRange(AST.getASTContext().getSourceManager(),
|
||||
|
||||
@@ -2037,35 +2037,36 @@ TEST(FindReferences, WithinAST) {
|
||||
TEST(FindReferences, ExplicitSymbols) {
|
||||
const char *Tests[] = {
|
||||
R"cpp(
|
||||
struct Foo { Foo* [self]() const; };
|
||||
struct Foo { Foo* [[self]]() const; };
|
||||
void f() {
|
||||
if (Foo* T = foo.[^self]()) {} // Foo member call expr.
|
||||
Foo foo;
|
||||
if (Foo* T = foo.[[^self]]()) {} // Foo member call expr.
|
||||
}
|
||||
)cpp",
|
||||
|
||||
R"cpp(
|
||||
struct Foo { Foo(int); };
|
||||
Foo f() {
|
||||
int [b];
|
||||
return [^b]; // Foo constructor expr.
|
||||
int [[b]];
|
||||
return [[^b]]; // Foo constructor expr.
|
||||
}
|
||||
)cpp",
|
||||
|
||||
R"cpp(
|
||||
struct Foo {};
|
||||
void g(Foo);
|
||||
Foo [f]();
|
||||
Foo [[f]]();
|
||||
void call() {
|
||||
g([^f]()); // Foo constructor expr.
|
||||
g([[^f]]()); // Foo constructor expr.
|
||||
}
|
||||
)cpp",
|
||||
|
||||
R"cpp(
|
||||
void [foo](int);
|
||||
void [foo](double);
|
||||
void [[foo]](int);
|
||||
void [[foo]](double);
|
||||
|
||||
namespace ns {
|
||||
using ::[fo^o];
|
||||
using ::[[fo^o]];
|
||||
}
|
||||
)cpp",
|
||||
};
|
||||
@@ -2075,6 +2076,7 @@ TEST(FindReferences, ExplicitSymbols) {
|
||||
std::vector<Matcher<Location>> ExpectedLocations;
|
||||
for (const auto &R : T.ranges())
|
||||
ExpectedLocations.push_back(RangeIs(R));
|
||||
ASSERT_THAT(ExpectedLocations, Not(IsEmpty()));
|
||||
EXPECT_THAT(findReferences(AST, T.point(), 0),
|
||||
ElementsAreArray(ExpectedLocations))
|
||||
<< Test;
|
||||
|
||||
Reference in New Issue
Block a user