forked from OSchip/llvm-project
[clangd] Show template argument list in workspacesymbols and documentsymbols responses
Summary: Last part of re-landing rC356541. Puts TemplateArgumentsList into responses of the above mentioned two requests. Reviewers: ioeric, ilya-biryukov Subscribers: MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59641 llvm-svn: 358274
This commit is contained in:
parent
79063de95c
commit
4f789e1b39
|
@ -94,7 +94,8 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
|
|||
std::string Scope = Sym.Scope;
|
||||
llvm::StringRef ScopeRef = Scope;
|
||||
ScopeRef.consume_back("::");
|
||||
SymbolInformation Info = {Sym.Name, SK, L, ScopeRef};
|
||||
SymbolInformation Info = {(Sym.Name + Sym.TemplateSpecializationArgs).str(),
|
||||
SK, L, ScopeRef};
|
||||
|
||||
SymbolQualitySignals Quality;
|
||||
Quality.merge(Sym);
|
||||
|
|
|
@ -38,15 +38,6 @@ bool MemIndex::fuzzyFind(
|
|||
for (const auto Pair : Index) {
|
||||
const Symbol *Sym = Pair.second;
|
||||
|
||||
// FIXME: Enable fuzzy find on template specializations once we start
|
||||
// storing template arguments in the name. Currently we only store name for
|
||||
// class template, which would cause duplication in the results.
|
||||
if (Sym->SymInfo.Properties &
|
||||
(static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization) |
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization)))
|
||||
continue;
|
||||
// Exact match against all possible scopes.
|
||||
if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope))
|
||||
continue;
|
||||
|
|
|
@ -86,15 +86,6 @@ void Dex::buildIndex() {
|
|||
llvm::DenseMap<Token, std::vector<DocID>> TempInvertedIndex;
|
||||
for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) {
|
||||
const auto *Sym = Symbols[SymbolRank];
|
||||
// FIXME: Enable fuzzy find on template specializations once we start
|
||||
// storing template arguments in the name. Currently we only store name for
|
||||
// class template, which would cause duplication in the results.
|
||||
if (Sym->SymInfo.Properties &
|
||||
(static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization) |
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization)))
|
||||
continue;
|
||||
for (const auto &Token : generateSearchTokens(*Sym))
|
||||
TempInvertedIndex[Token].push_back(SymbolRank);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "TestIndex.h"
|
||||
#include "index/Index.h"
|
||||
#include "index/Merge.h"
|
||||
#include "index/SymbolID.h"
|
||||
#include "index/dex/Dex.h"
|
||||
#include "index/dex/Iterator.h"
|
||||
#include "index/dex/Token.h"
|
||||
|
@ -24,6 +25,7 @@
|
|||
|
||||
using ::testing::AnyOf;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
|
||||
namespace clang {
|
||||
|
@ -719,30 +721,30 @@ TEST(DexTest, TemplateSpecialization) {
|
|||
|
||||
S = symbol("TempSpec");
|
||||
S.ID = SymbolID("1");
|
||||
S.TemplateSpecializationArgs = "<int, bool>";
|
||||
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization);
|
||||
B.insert(S);
|
||||
|
||||
S = symbol("TempSpec");
|
||||
S.ID = SymbolID("2");
|
||||
S.TemplateSpecializationArgs = "<int, U>";
|
||||
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization);
|
||||
B.insert(S);
|
||||
|
||||
auto I = dex::Dex::build(std::move(B).build(), RefSlab());
|
||||
FuzzyFindRequest Req;
|
||||
Req.Query = "TempSpec";
|
||||
Req.AnyScope = true;
|
||||
|
||||
std::vector<Symbol> Symbols;
|
||||
I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); });
|
||||
EXPECT_EQ(Symbols.size(), 1U);
|
||||
EXPECT_FALSE(Symbols.front().SymInfo.Properties &
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization));
|
||||
EXPECT_FALSE(Symbols.front().SymInfo.Properties &
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization));
|
||||
Req.Query = "TempSpec";
|
||||
EXPECT_THAT(match(*I, Req),
|
||||
UnorderedElementsAre("TempSpec", "TempSpec<int, bool>",
|
||||
"TempSpec<int, U>"));
|
||||
|
||||
// FIXME: Add filtering for template argument list.
|
||||
Req.Query = "TempSpec<int";
|
||||
EXPECT_THAT(match(*I, Req), IsEmpty());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -147,8 +147,7 @@ TEST_F(WorkspaceSymbolsTest, InMainFile) {
|
|||
int test() {}
|
||||
static test2() {}
|
||||
)cpp");
|
||||
EXPECT_THAT(getSymbols("test"),
|
||||
ElementsAre(QName("test"), QName("test2")));
|
||||
EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"), QName("test2")));
|
||||
}
|
||||
|
||||
TEST_F(WorkspaceSymbolsTest, Namespaces) {
|
||||
|
@ -301,6 +300,23 @@ TEST_F(WorkspaceSymbolsTest, WithLimit) {
|
|||
EXPECT_THAT(getSymbols("foo"), ElementsAre(QName("foo")));
|
||||
}
|
||||
|
||||
TEST_F(WorkspaceSymbolsTest, TempSpecs) {
|
||||
addFile("foo.h", R"cpp(
|
||||
template <typename T, typename U, int X = 5> class Foo {};
|
||||
template <typename T> class Foo<int, T> {};
|
||||
template <> class Foo<bool, int> {};
|
||||
template <> class Foo<bool, int, 3> {};
|
||||
)cpp");
|
||||
// Foo is higher ranked because of exact name match.
|
||||
EXPECT_THAT(
|
||||
getSymbols("Foo"),
|
||||
UnorderedElementsAre(
|
||||
AllOf(QName("Foo"), WithKind(SymbolKind::Class)),
|
||||
AllOf(QName("Foo<int, T>"), WithKind(SymbolKind::Class)),
|
||||
AllOf(QName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
|
||||
AllOf(QName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DocumentSymbolsTest : public ::testing::Test {
|
||||
public:
|
||||
|
@ -651,5 +667,22 @@ TEST_F(DocumentSymbolsTest, UsingDirectives) {
|
|||
WithName("using namespace ns_alias")));
|
||||
}
|
||||
|
||||
TEST_F(DocumentSymbolsTest, TempSpecs) {
|
||||
addFile("foo.cpp", R"cpp(
|
||||
template <typename T, typename U, int X = 5> class Foo {};
|
||||
template <typename T> class Foo<int, T> {};
|
||||
template <> class Foo<bool, int> {};
|
||||
template <> class Foo<bool, int, 3> {};
|
||||
)cpp");
|
||||
// Foo is higher ranked because of exact name match.
|
||||
EXPECT_THAT(
|
||||
getSymbols("foo.cpp"),
|
||||
UnorderedElementsAre(
|
||||
AllOf(WithName("Foo"), WithKind(SymbolKind::Class)),
|
||||
AllOf(WithName("Foo<int, T>"), WithKind(SymbolKind::Class)),
|
||||
AllOf(WithName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
|
||||
AllOf(WithName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
|
||||
}
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
|
|
|
@ -22,6 +22,7 @@ using testing::_;
|
|||
using testing::AllOf;
|
||||
using testing::AnyOf;
|
||||
using testing::ElementsAre;
|
||||
using testing::IsEmpty;
|
||||
using testing::Pair;
|
||||
using testing::Pointee;
|
||||
using testing::UnorderedElementsAre;
|
||||
|
@ -187,35 +188,35 @@ TEST(MemIndexTest, TemplateSpecialization) {
|
|||
SymbolSlab::Builder B;
|
||||
|
||||
Symbol S = symbol("TempSpec");
|
||||
S.ID = SymbolID("0");
|
||||
S.ID = SymbolID("1");
|
||||
B.insert(S);
|
||||
|
||||
S = symbol("TempSpec");
|
||||
S.ID = SymbolID("1");
|
||||
S.ID = SymbolID("2");
|
||||
S.TemplateSpecializationArgs = "<int, bool>";
|
||||
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization);
|
||||
B.insert(S);
|
||||
|
||||
S = symbol("TempSpec");
|
||||
S.ID = SymbolID("2");
|
||||
S.ID = SymbolID("3");
|
||||
S.TemplateSpecializationArgs = "<int, U>";
|
||||
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization);
|
||||
B.insert(S);
|
||||
|
||||
auto I = MemIndex::build(std::move(B).build(), RefSlab());
|
||||
FuzzyFindRequest Req;
|
||||
Req.Query = "TempSpec";
|
||||
Req.AnyScope = true;
|
||||
|
||||
std::vector<Symbol> Symbols;
|
||||
I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); });
|
||||
EXPECT_EQ(Symbols.size(), 1U);
|
||||
EXPECT_FALSE(Symbols.front().SymInfo.Properties &
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplateSpecialization));
|
||||
EXPECT_FALSE(Symbols.front().SymInfo.Properties &
|
||||
static_cast<index::SymbolPropertySet>(
|
||||
index::SymbolProperty::TemplatePartialSpecialization));
|
||||
Req.Query = "TempSpec";
|
||||
EXPECT_THAT(match(*I, Req),
|
||||
UnorderedElementsAre("TempSpec", "TempSpec<int, bool>",
|
||||
"TempSpec<int, U>"));
|
||||
|
||||
// FIXME: Add filtering for template argument list.
|
||||
Req.Query = "TempSpec<int";
|
||||
EXPECT_THAT(match(*I, Req), IsEmpty());
|
||||
}
|
||||
|
||||
TEST(MergeIndexTest, Lookup) {
|
||||
|
|
|
@ -94,7 +94,7 @@ SymbolSlab generateNumSymbols(int Begin, int End) {
|
|||
}
|
||||
|
||||
std::string getQualifiedName(const Symbol &Sym) {
|
||||
return (Sym.Scope + Sym.Name).str();
|
||||
return (Sym.Scope + Sym.Name + Sym.TemplateSpecializationArgs).str();
|
||||
}
|
||||
|
||||
std::vector<std::string> match(const SymbolIndex &I,
|
||||
|
|
Loading…
Reference in New Issue