summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/CodeComplete.cpp18
-rw-r--r--clang-tools-extra/clangd/CodeComplete.h5
-rw-r--r--clang-tools-extra/clangd/tool/ClangdMain.cpp18
-rw-r--r--clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp10
4 files changed, 43 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 62ebe3e96f07..137715ea7093 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -191,7 +191,9 @@ struct CompletionCandidate {
// 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 {
+ size_t overloadSet(const CodeCompleteOptions &Opts) const {
+ if (!Opts.BundleOverloads)
+ return 0;
llvm::SmallString<256> Scratch;
if (IndexResult) {
switch (IndexResult->SymInfo.Kind) {
@@ -208,7 +210,7 @@ struct CompletionCandidate {
// This could break #include insertion.
return llvm::hash_combine(
(IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
- headerToInsertIfAllowed().getValueOr(""));
+ headerToInsertIfAllowed(Opts).getValueOr(""));
default:
return 0;
}
@@ -223,12 +225,14 @@ struct CompletionCandidate {
D->printQualifiedName(OS);
}
return llvm::hash_combine(Scratch,
- headerToInsertIfAllowed().getValueOr(""));
+ headerToInsertIfAllowed(Opts).getValueOr(""));
}
// The best header to include if include insertion is allowed.
- llvm::Optional<llvm::StringRef> headerToInsertIfAllowed() const {
- if (RankedIncludeHeaders.empty())
+ llvm::Optional<llvm::StringRef>
+ headerToInsertIfAllowed(const CodeCompleteOptions &Opts) const {
+ if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
+ RankedIncludeHeaders.empty())
return None;
if (SemaResult && SemaResult->Declaration) {
// Avoid inserting new #include if the declaration is found in the current
@@ -338,7 +342,7 @@ struct CodeCompletionBuilder {
Includes.calculateIncludePath(*ResolvedDeclaring, *ResolvedInserted),
Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
};
- bool ShouldInsert = C.headerToInsertIfAllowed().hasValue();
+ bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue();
// Calculate include paths and edits for all possible headers.
for (const auto &Inc : C.RankedIncludeHeaders) {
if (auto ToInclude = Inserted(Inc)) {
@@ -1373,7 +1377,7 @@ private:
if (C.IndexResult)
C.RankedIncludeHeaders = getRankedIncludes(*C.IndexResult);
C.Name = IndexResult ? IndexResult->Name : Recorder->getName(*SemaResult);
- if (auto OverloadSet = Opts.BundleOverloads ? C.overloadSet() : 0) {
+ if (auto OverloadSet = C.overloadSet(Opts)) {
auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
if (Ret.second)
Bundles.emplace_back();
diff --git a/clang-tools-extra/clangd/CodeComplete.h b/clang-tools-extra/clangd/CodeComplete.h
index aced6bef7d5b..e1110dccc0de 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -68,6 +68,11 @@ struct CodeCompleteOptions {
/// If more results are available, we set CompletionList.isIncomplete.
size_t Limit = 0;
+ enum IncludeInsertion {
+ IWYU,
+ NeverInsert,
+ } InsertIncludes = IncludeInsertion::IWYU;
+
/// A visual indicator to prepend to the completion label to indicate whether
/// completion result would trigger an #include insertion or not.
struct IncludeInsertionIndicator {
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 034d6ecb8751..b6efd3822a14 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -6,8 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#include "Features.inc"
#include "ClangdLSPServer.h"
+#include "CodeComplete.h"
+#include "Features.inc"
#include "Path.h"
#include "Protocol.h"
#include "Trace.h"
@@ -154,6 +155,20 @@ static llvm::cl::opt<bool> ShowOrigins(
"debug-origin", llvm::cl::desc("Show origins of completion items"),
llvm::cl::init(CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden);
+static llvm::cl::opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion(
+ "header-insertion",
+ llvm::cl::desc("Add #include directives when accepting code completions"),
+ llvm::cl::init(CodeCompleteOptions().InsertIncludes),
+ llvm::cl::values(
+ clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
+ "Include what you use. "
+ "Insert the owning header for top-level symbols, unless the "
+ "header is already directly included or the symbol is "
+ "forward-declared."),
+ clEnumValN(
+ CodeCompleteOptions::NeverInsert, "never",
+ "Never insert #include directives as part of code completion")));
+
static llvm::cl::opt<bool> HeaderInsertionDecorators(
"header-insertion-decorators",
llvm::cl::desc("Prepend a circular dot or space before the completion "
@@ -438,6 +453,7 @@ int main(int argc, char *argv[]) {
CCOpts.Limit = LimitResults;
CCOpts.BundleOverloads = CompletionStyle != Detailed;
CCOpts.ShowOrigins = ShowOrigins;
+ CCOpts.InsertIncludes = HeaderInsertion;
if (!HeaderInsertionDecorators) {
CCOpts.IncludeIndicator.Insert.clear();
CCOpts.IncludeIndicator.NoInsert.clear();
diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
index 28c2e6be5f69..f0a8097bf468 100644
--- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
+++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
@@ -555,6 +555,16 @@ TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
{Sym});
EXPECT_THAT(Results.Completions,
ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\""))));
+ // Can be disabled via option.
+ CodeCompleteOptions NoInsertion;
+ NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
+ Results = completions(Server,
+ R"cpp(
+ int main() { ns::^ }
+ )cpp",
+ {Sym}, NoInsertion);
+ EXPECT_THAT(Results.Completions,
+ ElementsAre(AllOf(Named("X"), Not(InsertInclude()))));
// Duplicate based on inclusions in preamble.
Results = completions(Server,
R"cpp(