kadircet created this revision. Herald added subscribers: cfe-commits, usaxena95, arphaman. Herald added a project: clang. kadircet requested review of this revision. Herald added subscribers: MaskRay, ilya-biryukov.
This will enable queries like "clangd::" to find symbols under clangd namespace, without requiring full "clang::clangd::" qualification. Since Fuzzyfind performs the search under all scopes and only boosts the symbols from relevant namespaces, we might get symbols from non-matching namespaces. This patch chooses to drop those as they clearly do not match the query. Fixes https://github.com/clangd/clangd/issues/550. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D88814 Files: clang-tools-extra/clangd/FindSymbols.cpp clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp Index: clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -141,7 +141,10 @@ EXPECT_THAT(getSymbols(TU, "::"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "::a"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "ans1::"), - UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); + UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"), + QName("ans1::ans2::ai2"))); + EXPECT_THAT(getSymbols(TU, "ans2::"), + UnorderedElementsAre(QName("ans1::ans2::ai2"))); EXPECT_THAT(getSymbols(TU, "::ans1"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "::ans1::"), UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); Index: clang-tools-extra/clangd/FindSymbols.cpp =================================================================== --- clang-tools-extra/clangd/FindSymbols.cpp +++ clang-tools-extra/clangd/FindSymbols.cpp @@ -76,20 +76,26 @@ FuzzyFindRequest Req; Req.Query = std::string(Names.second); - // FuzzyFind doesn't want leading :: qualifier - bool IsGlobalQuery = Names.first.consume_front("::"); - // Restrict results to the scope in the query string if present (global or - // not). - if (IsGlobalQuery || !Names.first.empty()) + // FuzzyFind doesn't want leading :: qualifier. Also limit the query to + // specific namespace if it is fully-qualified. + Req.AnyScope = !Names.first.consume_front("::"); + // Boost symbols from desired namespace. + if (!Req.AnyScope || !Names.first.empty()) Req.Scopes = {std::string(Names.first)}; - else - Req.AnyScope = true; if (Limit) Req.Limit = Limit; TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top( Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max()); FuzzyMatcher Filter(Req.Query); - Index->fuzzyFind(Req, [HintPath, &Top, &Filter](const Symbol &Sym) { + Index->fuzzyFind(Req, [HintPath, &Top, &Filter, &Names](const Symbol &Sym) { + std::string Scope = std::string(Sym.Scope); + llvm::StringRef ScopeRef = Scope; + // Fuzzfind might return symbols from irrelevant namespaces if query was not + // fully-qualified, drop those. + if (!ScopeRef.contains(Names.first)) + return; + ScopeRef.consume_back("::"); + auto Loc = symbolToLocation(Sym, HintPath); if (!Loc) { log("Workspace symbols: {0}", Loc.takeError()); @@ -97,9 +103,6 @@ } SymbolKind SK = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind); - std::string Scope = std::string(Sym.Scope); - llvm::StringRef ScopeRef = Scope; - ScopeRef.consume_back("::"); SymbolInformation Info = {(Sym.Name + Sym.TemplateSpecializationArgs).str(), SK, *Loc, std::string(ScopeRef)};
Index: clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -141,7 +141,10 @@ EXPECT_THAT(getSymbols(TU, "::"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "::a"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "ans1::"), - UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); + UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"), + QName("ans1::ans2::ai2"))); + EXPECT_THAT(getSymbols(TU, "ans2::"), + UnorderedElementsAre(QName("ans1::ans2::ai2"))); EXPECT_THAT(getSymbols(TU, "::ans1"), ElementsAre(QName("ans1"))); EXPECT_THAT(getSymbols(TU, "::ans1::"), UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); Index: clang-tools-extra/clangd/FindSymbols.cpp =================================================================== --- clang-tools-extra/clangd/FindSymbols.cpp +++ clang-tools-extra/clangd/FindSymbols.cpp @@ -76,20 +76,26 @@ FuzzyFindRequest Req; Req.Query = std::string(Names.second); - // FuzzyFind doesn't want leading :: qualifier - bool IsGlobalQuery = Names.first.consume_front("::"); - // Restrict results to the scope in the query string if present (global or - // not). - if (IsGlobalQuery || !Names.first.empty()) + // FuzzyFind doesn't want leading :: qualifier. Also limit the query to + // specific namespace if it is fully-qualified. + Req.AnyScope = !Names.first.consume_front("::"); + // Boost symbols from desired namespace. + if (!Req.AnyScope || !Names.first.empty()) Req.Scopes = {std::string(Names.first)}; - else - Req.AnyScope = true; if (Limit) Req.Limit = Limit; TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top( Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max()); FuzzyMatcher Filter(Req.Query); - Index->fuzzyFind(Req, [HintPath, &Top, &Filter](const Symbol &Sym) { + Index->fuzzyFind(Req, [HintPath, &Top, &Filter, &Names](const Symbol &Sym) { + std::string Scope = std::string(Sym.Scope); + llvm::StringRef ScopeRef = Scope; + // Fuzzfind might return symbols from irrelevant namespaces if query was not + // fully-qualified, drop those. + if (!ScopeRef.contains(Names.first)) + return; + ScopeRef.consume_back("::"); + auto Loc = symbolToLocation(Sym, HintPath); if (!Loc) { log("Workspace symbols: {0}", Loc.takeError()); @@ -97,9 +103,6 @@ } SymbolKind SK = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind); - std::string Scope = std::string(Sym.Scope); - llvm::StringRef ScopeRef = Scope; - ScopeRef.consume_back("::"); SymbolInformation Info = {(Sym.Name + Sym.TemplateSpecializationArgs).str(), SK, *Loc, std::string(ScopeRef)};
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits