[clang-tools-extra] 9cdbc47 - [clangd] Add `HeaderInsertion` config option (#128503)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 19 23:22:33 PDT 2025
Author: Mythreya
Date: 2025-03-20T02:22:29-04:00
New Revision: 9cdbc47144f28785133592b1ae219cb49b9ac61d
URL: https://github.com/llvm/llvm-project/commit/9cdbc47144f28785133592b1ae219cb49b9ac61d
DIFF: https://github.com/llvm/llvm-project/commit/9cdbc47144f28785133592b1ae219cb49b9ac61d.diff
LOG: [clangd] Add `HeaderInsertion` config option (#128503)
This is the config file equivalent of the `--header-insertion` command line option
Fixes https://github.com/clangd/clangd/issues/2032
Added:
Modified:
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/CodeComplete.h
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/tool/ClangdMain.cpp
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 49a97da2bfa42..52844129834c3 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -455,6 +455,8 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
CodeCompleteOpts.MainFileSignals = IP->Signals;
CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes;
CodeCompleteOpts.ArgumentLists = Config::current().Completion.ArgumentLists;
+ CodeCompleteOpts.InsertIncludes =
+ Config::current().Completion.HeaderInsertion;
// FIXME(ibiryukov): even if Preamble is non-null, we may want to check
// both the old and the new version in case only one of them matches.
CodeCompleteResult Result = clangd::codeComplete(
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index a8182ce98ebe0..008cc96c91996 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -294,7 +294,7 @@ struct CompletionCandidate {
std::optional<llvm::StringRef>
headerToInsertIfAllowed(const CodeCompleteOptions &Opts,
CodeCompletionContext::Kind ContextKind) const {
- if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
+ if (Opts.InsertIncludes == Config::HeaderInsertionPolicy::NeverInsert ||
RankedIncludeHeaders.empty() ||
!contextAllowsHeaderInsertion(ContextKind))
return std::nullopt;
diff --git a/clang-tools-extra/clangd/CodeComplete.h b/clang-tools-extra/clangd/CodeComplete.h
index cd41f04e4fb5c..83d347054119e 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -71,10 +71,8 @@ struct CodeCompleteOptions {
/// Whether to present doc comments as plain-text or markdown.
MarkupKind DocumentationFormat = MarkupKind::PlainText;
- enum IncludeInsertion {
- IWYU,
- NeverInsert,
- } InsertIncludes = IncludeInsertion::IWYU;
+ Config::HeaderInsertionPolicy InsertIncludes =
+ Config::HeaderInsertionPolicy::IWYU;
/// Whether include insertions for Objective-C code should use #import instead
/// of #include.
diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h
index 3f8a3c9b060f6..2891a6d1e77b0 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -147,6 +147,11 @@ struct Config {
FullPlaceholders,
};
+ enum class HeaderInsertionPolicy {
+ IWYU, // Include what you use
+ NeverInsert // Never insert headers as part of code completion
+ };
+
/// Configures code completion feature.
struct {
/// Whether code completion includes results that are not visible in current
@@ -154,6 +159,8 @@ struct Config {
bool AllScopes = true;
/// controls the completion options for argument lists.
ArgumentListsPolicy ArgumentLists = ArgumentListsPolicy::FullPlaceholders;
+ /// Controls if headers should be inserted when completions are accepted
+ HeaderInsertionPolicy HeaderInsertion = HeaderInsertionPolicy::IWYU;
} Completion;
/// Configures hover feature.
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp
index 31530c206acd7..21304a8c0fac7 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -697,6 +697,17 @@ struct FragmentCompiler {
C.Completion.ArgumentLists = *Val;
});
}
+ if (F.HeaderInsertion) {
+ if (auto Val =
+ compileEnum<Config::HeaderInsertionPolicy>("HeaderInsertion",
+ *F.HeaderInsertion)
+ .map("IWYU", Config::HeaderInsertionPolicy::IWYU)
+ .map("Never", Config::HeaderInsertionPolicy::NeverInsert)
+ .value())
+ Out.Apply.push_back([Val](const Params &, Config &C) {
+ C.Completion.HeaderInsertion = *Val;
+ });
+ }
}
void compile(Fragment::HoverBlock &&F) {
diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h
index 6f95474b9c008..f05ed4d1acdfc 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -341,6 +341,14 @@ struct Fragment {
/// Delimiters: empty pair of delimiters "()" or "<>"
/// FullPlaceholders: full name of both type and parameter
std::optional<Located<std::string>> ArgumentLists;
+ /// Add #include directives when accepting code completions. Config
+ /// equivalent of the CLI option '--header-insertion'
+ /// Valid values are enum Config::HeaderInsertionPolicy values:
+ /// "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
+ /// "NeverInsert": Never insert headers
+ std::optional<Located<std::string>> HeaderInsertion;
};
CompletionBlock Completion;
diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp
index a46d45df0d319..47c6e1cd0f7e7 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -245,6 +245,10 @@ class Parser {
if (auto ArgumentLists = scalarValue(N, "ArgumentLists"))
F.ArgumentLists = *ArgumentLists;
});
+ Dict.handle("HeaderInsertion", [&](Node &N) {
+ if (auto HeaderInsertion = scalarValue(N, "HeaderInsertion"))
+ F.HeaderInsertion = *HeaderInsertion;
+ });
Dict.parse(N);
}
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 714891703b6f3..4bd256d6be22b 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -251,19 +251,19 @@ opt<std::string> EnableFunctionArgSnippets{
init("-1"),
};
-opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
+opt<Config::HeaderInsertionPolicy> HeaderInsertion{
"header-insertion",
cat(Features),
desc("Add #include directives when accepting code completions"),
init(CodeCompleteOptions().InsertIncludes),
values(
- clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
+ clEnumValN(Config::HeaderInsertionPolicy::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",
+ Config::HeaderInsertionPolicy::NeverInsert, "never",
"Never insert #include directives as part of code completion")),
};
@@ -668,6 +668,7 @@ class FlagsConfigProvider : public config::Provider {
std::optional<Config::ExternalIndexSpec> IndexSpec;
std::optional<Config::BackgroundPolicy> BGPolicy;
std::optional<Config::ArgumentListsPolicy> ArgumentLists;
+ std::optional<Config::HeaderInsertionPolicy> HeaderInsertionPolicy;
// If --compile-commands-dir arg was invoked, check value and override
// default path.
@@ -712,6 +713,11 @@ class FlagsConfigProvider : public config::Provider {
BGPolicy = Config::BackgroundPolicy::Skip;
}
+ // If CLI has set never, use that regardless of what the config files have
+ if (HeaderInsertion == Config::HeaderInsertionPolicy::NeverInsert) {
+ HeaderInsertionPolicy = Config::HeaderInsertionPolicy::NeverInsert;
+ }
+
if (std::optional<bool> Enable = shouldEnableFunctionArgSnippets()) {
ArgumentLists = *Enable ? Config::ArgumentListsPolicy::FullPlaceholders
: Config::ArgumentListsPolicy::Delimiters;
@@ -726,6 +732,8 @@ class FlagsConfigProvider : public config::Provider {
C.Index.Background = *BGPolicy;
if (ArgumentLists)
C.Completion.ArgumentLists = *ArgumentLists;
+ if (HeaderInsertionPolicy)
+ C.Completion.HeaderInsertion = *HeaderInsertionPolicy;
if (AllScopesCompletion.getNumOccurrences())
C.Completion.AllScopes = AllScopesCompletion;
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index b12f8275b8a26..718bee2e40b11 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -882,7 +882,7 @@ TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
// Can be disabled via option.
CodeCompleteOptions NoInsertion;
- NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
+ NoInsertion.InsertIncludes = Config::HeaderInsertionPolicy::NeverInsert;
Results = completions(TU, Test.point(), {Sym}, NoInsertion);
EXPECT_THAT(Results.Completions,
ElementsAre(AllOf(named("X"), Not(insertInclude()))));
@@ -1191,7 +1191,7 @@ TEST(CompletionTest, CommentsOnMembersFromHeaderOverloadBundling) {
int delta(int i);
void epsilon(long l);
-
+
/// This one has a comment.
void epsilon(int i);
};
More information about the cfe-commits
mailing list