[PATCH] D92494: [clangd] Bundle code completion items when the include paths differ, but resolve to the same file.
Adam Czachorowski via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 2 10:02:35 PST 2020
adamcz created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman.
Herald added a project: clang.
adamcz requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.
This can happen when, for example, merging results from an external
index that generates IncludeHeaders with full URI rather than just
literal include.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D92494
Files:
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1628,6 +1628,29 @@
EXPECT_EQ(A.SnippetSuffix, "($0)");
}
+TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
+ clangd::CodeCompleteOptions Opts;
+ Opts.BundleOverloads = true;
+
+ Symbol SymX = sym("ns::X", index::SymbolKind::Function, "@F@\\0#");
+ Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#");
+ std::string BarHeader = testPath("bar.h");
+ auto BarURI = URI::create(BarHeader).toString();
+ SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
+ SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
+ // The include header is different, but really it's the same file.
+ SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1);
+ SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1);
+
+ auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts);
+ // Expect both results are bundled, despite the different-but-same
+ // IncludeHeader.
+ ASSERT_EQ(1u, Results.Completions.size());
+ const auto &R = Results.Completions.front();
+ EXPECT_EQ("X", R.Name);
+ EXPECT_EQ(2u, R.BundleSize);
+}
+
TEST(CompletionTest, DocumentationFromChangedFileCrash) {
MockFS FS;
auto FooH = testPath("foo.h");
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -173,9 +173,23 @@
// Returns a token identifying the overload set this is part of.
// 0 indicates it's not part of any overload set.
- size_t overloadSet(const CodeCompleteOptions &Opts) const {
+ size_t overloadSet(const CodeCompleteOptions &Opts, llvm::StringRef FileName,
+ IncludeInserter *Inserter) const {
if (!Opts.BundleOverloads.getValueOr(false))
return 0;
+
+ // Depending on the index implementation, we can see different header
+ // strings (literal or URI) mapping to the same file. We still want to
+ // bundle those, so we must resolve the header to be included here.
+ std::string HeaderForHash;
+ if (Inserter) {
+ if (auto Header = headerToInsertIfAllowed(Opts))
+ if (auto HeaderFile = toHeaderFile(*Header, FileName))
+ if (auto Spelled =
+ Inserter->calculateIncludePath(*HeaderFile, FileName))
+ HeaderForHash = *Spelled;
+ }
+
llvm::SmallString<256> Scratch;
if (IndexResult) {
switch (IndexResult->SymInfo.Kind) {
@@ -192,7 +206,7 @@
// This could break #include insertion.
return llvm::hash_combine(
(IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
- headerToInsertIfAllowed(Opts).getValueOr(""));
+ HeaderForHash);
default:
return 0;
}
@@ -206,8 +220,7 @@
llvm::raw_svector_ostream OS(Scratch);
D->printQualifiedName(OS);
}
- return llvm::hash_combine(Scratch,
- headerToInsertIfAllowed(Opts).getValueOr(""));
+ return llvm::hash_combine(Scratch, HeaderForHash);
}
assert(IdentifierResult);
return 0;
@@ -1570,7 +1583,8 @@
assert(IdentifierResult);
C.Name = IdentifierResult->Name;
}
- if (auto OverloadSet = C.overloadSet(Opts)) {
+ if (auto OverloadSet = C.overloadSet(
+ Opts, FileName, Inserter ? Inserter.getPointer() : nullptr)) {
auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
if (Ret.second)
Bundles.emplace_back();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92494.309002.patch
Type: text/x-patch
Size: 3774 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201202/1b7b8aea/attachment.bin>
More information about the cfe-commits
mailing list