Skip to content

Commit

Permalink
[clangd] Show template argument list in workspacesymbols and document…
Browse files Browse the repository at this point in the history
…symbols 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
  • Loading branch information
kadircet committed Apr 12, 2019
1 parent 79063de commit 4f789e1
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 45 deletions.
3 changes: 2 additions & 1 deletion clang-tools-extra/clangd/FindSymbols.cpp
Expand Up @@ -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);
Expand Down
9 changes: 0 additions & 9 deletions clang-tools-extra/clangd/index/MemIndex.cpp
Expand Up @@ -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;
Expand Down
9 changes: 0 additions & 9 deletions clang-tools-extra/clangd/index/dex/Dex.cpp
Expand Up @@ -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);
}
Expand Down
22 changes: 12 additions & 10 deletions clang-tools-extra/unittests/clangd/DexTests.cpp
Expand Up @@ -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"
Expand All @@ -24,6 +25,7 @@

using ::testing::AnyOf;
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::UnorderedElementsAre;

namespace clang {
Expand Down Expand Up @@ -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
Expand Down
37 changes: 35 additions & 2 deletions clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
27 changes: 14 additions & 13 deletions clang-tools-extra/unittests/clangd/IndexTests.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/unittests/clangd/TestIndex.cpp
Expand Up @@ -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,
Expand Down

0 comments on commit 4f789e1

Please sign in to comment.