[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:
Kadir Cetinkaya 2019-04-12 10:09:37 +00:00
parent 79063de95c
commit 4f789e1b39
7 changed files with 64 additions and 45 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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