summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/CodeComplete.cpp6
-rw-r--r--clang-tools-extra/clangd/index/FileIndex.cpp2
-rw-r--r--clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp46
3 files changed, 47 insertions, 7 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index e2fc5019708..fa6c5d18a71 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -642,8 +642,10 @@ clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
Result.IncludeGlobals = IncludeGlobals;
Result.IncludeBriefComments = IncludeBriefComments;
- // Enable index-based code completion when Index is provided.
- Result.IncludeNamespaceLevelDecls = !Index;
+ // When an is used, Sema is responsible for completing the main file,
+ // the index can provide results from the preamble.
+ // Tell Sema not to deserialize the preamble to look for results.
+ Result.LoadExternal = !Index;
return Result;
}
diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp
index 1f3cc38d25b..43e8d322f4b 100644
--- a/clang-tools-extra/clangd/index/FileIndex.cpp
+++ b/clang-tools-extra/clangd/index/FileIndex.cpp
@@ -20,6 +20,8 @@ std::unique_ptr<SymbolSlab> indexAST(ASTContext &Ctx,
std::shared_ptr<Preprocessor> PP,
llvm::ArrayRef<const Decl *> Decls) {
SymbolCollector::Options CollectorOpts;
+ // Code completion gets main-file results from Sema.
+ // But we leave this option on because features like go-to-definition want it.
CollectorOpts.IndexMainFiles = true;
auto Collector = std::make_shared<SymbolCollector>(std::move(CollectorOpts));
Collector->setPreprocessor(std::move(PP));
diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
index 39f9117ae04..3329794b985 100644
--- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
+++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
@@ -57,6 +57,7 @@ using ::testing::Contains;
using ::testing::Each;
using ::testing::ElementsAre;
using ::testing::Not;
+using ::testing::UnorderedElementsAre;
class IgnoreDiagnostics : public DiagnosticsConsumer {
void
@@ -104,7 +105,7 @@ CompletionList completions(StringRef Text,
/*StorePreamblesInMemory=*/true);
auto File = getVirtualTestFilePath("foo.cpp");
Annotations Test(Text);
- Server.addDocument(Context::empty(), File, Test.code());
+ Server.addDocument(Context::empty(), File, Test.code()).wait();
auto CompletionList =
Server.codeComplete(Context::empty(), File, Test.point(), Opts)
.get()
@@ -506,11 +507,11 @@ TEST(CompletionTest, NoIndex) {
Opts.Index = nullptr;
auto Results = completions(R"cpp(
- namespace ns { class No {}; }
+ namespace ns { class Local {}; }
void f() { ns::^ }
)cpp",
Opts);
- EXPECT_THAT(Results.items, Has("No"));
+ EXPECT_THAT(Results.items, Has("Local"));
}
TEST(CompletionTest, StaticAndDynamicIndex) {
@@ -538,13 +539,13 @@ TEST(CompletionTest, SimpleIndexBased) {
Opts.Index = I.get();
auto Results = completions(R"cpp(
- namespace ns { class No {}; }
+ namespace ns { int local; }
void f() { ns::^ }
)cpp",
Opts);
EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
EXPECT_THAT(Results.items, Has("foo", CompletionItemKind::Function));
- EXPECT_THAT(Results.items, Not(Has("No")));
+ EXPECT_THAT(Results.items, Has("local"));
}
TEST(CompletionTest, IndexBasedWithFilter) {
@@ -585,6 +586,41 @@ TEST(CompletionTest, FullyQualifiedScope) {
EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
}
+TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
+ MockFSProvider FS;
+ MockCompilationDatabase CDB;
+ IgnoreDiagnostics DiagConsumer;
+ ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+ /*StorePreamblesInMemory=*/true);
+
+ FS.Files[getVirtualTestFilePath("bar.h")] =
+ R"cpp(namespace ns { int preamble; })cpp";
+ auto File = getVirtualTestFilePath("foo.cpp");
+ Annotations Test(R"cpp(
+ #include "bar.h"
+ namespace ns { int local; }
+ void f() { ns::^ }
+ )cpp");
+ Server.addDocument(Context::empty(), File, Test.code()).wait();
+ clangd::CodeCompleteOptions Opts = {};
+
+ auto WithoutIndex =
+ Server.codeComplete(Context::empty(), File, Test.point(), Opts)
+ .get()
+ .second.Value;
+ EXPECT_THAT(WithoutIndex.items,
+ UnorderedElementsAre(Named("local"), Named("preamble")));
+
+ auto I = simpleIndexFromSymbols({{"ns::index", index::SymbolKind::Variable}});
+ Opts.Index = I.get();
+ auto WithIndex =
+ Server.codeComplete(Context::empty(), File, Test.point(), Opts)
+ .get()
+ .second.Value;
+ EXPECT_THAT(WithIndex.items,
+ UnorderedElementsAre(Named("local"), Named("index")));
+}
+
TEST(CompletionTest, ASTIndexMultiFile) {
MockFSProvider FS;
MockCompilationDatabase CDB;
OpenPOWER on IntegriCloud