Index: clang-tools-extra/trunk/clangd/FindSymbols.cpp =================================================================== --- clang-tools-extra/trunk/clangd/FindSymbols.cpp +++ clang-tools-extra/trunk/clangd/FindSymbols.cpp @@ -94,7 +94,8 @@ 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); Index: clang-tools-extra/trunk/clangd/index/MemIndex.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/MemIndex.cpp +++ clang-tools-extra/trunk/clangd/index/MemIndex.cpp @@ -38,15 +38,6 @@ 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::SymbolProperty::TemplateSpecialization) | - static_cast( - index::SymbolProperty::TemplatePartialSpecialization))) - continue; // Exact match against all possible scopes. if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope)) continue; Index: clang-tools-extra/trunk/clangd/index/dex/Dex.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/dex/Dex.cpp +++ clang-tools-extra/trunk/clangd/index/dex/Dex.cpp @@ -86,15 +86,6 @@ llvm::DenseMap> 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::SymbolProperty::TemplateSpecialization) | - static_cast( - index::SymbolProperty::TemplatePartialSpecialization))) - continue; for (const auto &Token : generateSearchTokens(*Sym)) TempInvertedIndex[Token].push_back(SymbolRank); } Index: clang-tools-extra/trunk/unittests/clangd/DexTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/DexTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/DexTests.cpp @@ -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 @@ S = symbol("TempSpec"); S.ID = SymbolID("1"); + S.TemplateSpecializationArgs = ""; S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplateSpecialization); B.insert(S); S = symbol("TempSpec"); S.ID = SymbolID("2"); + S.TemplateSpecializationArgs = ""; S.SymInfo.Properties = static_cast( 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 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::SymbolProperty::TemplateSpecialization)); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplatePartialSpecialization)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec", + "TempSpec")); + + // FIXME: Add filtering for template argument list. + Req.Query = "TempSpec class Foo {}; + template class Foo {}; + template <> class Foo {}; + template <> class Foo {}; + )cpp"); + // Foo is higher ranked because of exact name match. + EXPECT_THAT( + getSymbols("Foo"), + UnorderedElementsAre( + AllOf(QName("Foo"), WithKind(SymbolKind::Class)), + AllOf(QName("Foo"), WithKind(SymbolKind::Class)), + AllOf(QName("Foo"), WithKind(SymbolKind::Class)), + AllOf(QName("Foo"), WithKind(SymbolKind::Class)))); +} + namespace { class DocumentSymbolsTest : public ::testing::Test { public: @@ -651,5 +667,22 @@ WithName("using namespace ns_alias"))); } +TEST_F(DocumentSymbolsTest, TempSpecs) { + addFile("foo.cpp", R"cpp( + template class Foo {}; + template class Foo {}; + template <> class Foo {}; + template <> class Foo {}; + )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"), WithKind(SymbolKind::Class)), + AllOf(WithName("Foo"), WithKind(SymbolKind::Class)), + AllOf(WithName("Foo"), WithKind(SymbolKind::Class)))); +} + } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp @@ -22,6 +22,7 @@ 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 @@ 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 = ""; S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplateSpecialization); B.insert(S); S = symbol("TempSpec"); - S.ID = SymbolID("2"); + S.ID = SymbolID("3"); + S.TemplateSpecializationArgs = ""; S.SymInfo.Properties = static_cast( 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 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::SymbolProperty::TemplateSpecialization)); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplatePartialSpecialization)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec", + "TempSpec")); + + // FIXME: Add filtering for template argument list. + Req.Query = "TempSpec match(const SymbolIndex &I,