[clang-tools-extra] [clangd] Allow specifying what headers are always included via "" or <> (PR #67749)
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 27 23:07:05 PST 2024
HighCommander4 wrote:
Anyways, I rebased the old version of the patch locally so that I could generate an interdiff, which I'll attach for reference:
<details>
```diff
diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h
index 12ed1420c93e..3559591fce00 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -124,7 +124,7 @@ struct Config {
// ::). All nested namespaces are affected as well.
std::vector<std::string> FullyQualifiedNamespaces;
- // List of regexes for inserting certain headers with <> or "".
+ // List of matcher functions for inserting certain headers with <> or "".
std::vector<std::function<bool(llvm::StringRef)>> QuotedHeaders;
std::vector<std::function<bool(llvm::StringRef)>> AngledHeaders;
} Style;
diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h
index 81474bbd86a5..f0d1080f6c83 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -302,12 +302,16 @@ struct Fragment {
/// AngledHeaders (i.e. a header matches a regex in both QuotedHeaders and
/// AngledHeaders), system headers use <> and non-system headers use "".
/// These can match any suffix of the header file in question.
+ /// Matching is performed against the header text, not its absolute path
+ /// within the project.
std::vector<Located<std::string>> QuotedHeaders;
/// List of regexes for headers that should always be included with a
/// <>-style include. By default, and in case of a conflict with
/// AngledHeaders (i.e. a header matches a regex in both QuotedHeaders and
/// AngledHeaders), system headers use <> and non-system headers use "".
/// These can match any suffix of the header file in question.
+ /// Matching is performed against the header text, not its absolute path
+ /// within the project.
std::vector<Located<std::string>> AngledHeaders;
};
StyleBlock Style;
diff --git a/clang-tools-extra/clangd/Headers.h b/clang-tools-extra/clangd/Headers.h
index e1f3eaa3397b..b91179da253e 100644
--- a/clang-tools-extra/clangd/Headers.h
+++ b/clang-tools-extra/clangd/Headers.h
@@ -9,7 +9,6 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H
-#include "Config.h"
#include "Protocol.h"
#include "SourceCode.h"
#include "index/Symbol.h"
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 6d387fec9b38..bf264a5a44ee 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -11,6 +11,7 @@
#include "ClangdServer.h"
#include "CodeComplete.h"
#include "Compiler.h"
+#include "Config.h"
#include "Feature.h"
#include "Matchers.h"
#include "Protocol.h"
@@ -916,6 +917,41 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
AllOf(named("Y"), Not(insertInclude()))));
}
+TEST(CompletionTest, IncludeInsertionRespectsQuotedAngledConfig) {
+ TestTU TU;
+ TU.ExtraArgs.push_back("-I" + testPath("sub"));
+ TU.AdditionalFiles["sub/bar.h"] = "";
+ auto BarURI = URI::create(testPath("sub/bar.h")).toString();
+
+ Symbol Sym = cls("ns::X");
+ Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
+ Sym.IncludeHeaders.emplace_back(BarURI, 1, Symbol::Include);
+ Annotations Test("int main() { ns::^ }");
+ TU.Code = Test.code().str();
+ auto Results = completions(TU, Test.point(), {Sym});
+ // Default for a local path is quoted include
+ EXPECT_THAT(Results.Completions,
+ ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
+ {
+ Config C;
+ C.Style.AngledHeaders.push_back(
+ [](auto header) { return header == "bar.h"; });
+ WithContextValue WithCfg(Config::Key, std::move(C));
+ Results = completions(TU, Test.point(), {Sym});
+ EXPECT_THAT(Results.Completions,
+ ElementsAre(AllOf(named("X"), insertInclude("<bar.h>"))));
+ }
+ {
+ Config C;
+ C.Style.QuotedHeaders.push_back(
+ [](auto header) { return header == "bar.h"; });
+ WithContextValue WithCfg(Config::Key, std::move(C));
+ Results = completions(TU, Test.point(), {Sym});
+ EXPECT_THAT(Results.Completions,
+ ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
+ }
+}
+
TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
Annotations Test(R"cpp(
#include "bar.h"
@@ -1134,8 +1170,8 @@ TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
}
TEST(CompletionTests, EmptySnippetDoesNotCrash) {
- // See https://github.com/clangd/clangd/issues/1216
- auto Results = completions(R"cpp(
+ // See https://github.com/clangd/clangd/issues/1216
+ auto Results = completions(R"cpp(
int main() {
auto w = [&](auto &&f) { return f(f); };
auto f = w([&](auto &&f) {
@@ -1151,18 +1187,18 @@ TEST(CompletionTests, EmptySnippetDoesNotCrash) {
}
TEST(CompletionTest, Issue1427Crash) {
- // Need to provide main file signals to ensure that the branch in
- // SymbolRelevanceSignals::computeASTSignals() that tries to
- // compute a symbol ID is taken.
- ASTSignals MainFileSignals;
- CodeCompleteOptions Opts;
- Opts.MainFileSignals = &MainFileSignals;
- completions(R"cpp(
+ // Need to provide main file signals to ensure that the branch in
+ // SymbolRelevanceSignals::computeASTSignals() that tries to
+ // compute a symbol ID is taken.
+ ASTSignals MainFileSignals;
+ CodeCompleteOptions Opts;
+ Opts.MainFileSignals = &MainFileSignals;
+ completions(R"cpp(
auto f = []() {
1.0_^
};
)cpp",
- {}, Opts);
+ {}, Opts);
}
TEST(CompletionTest, BacktrackCrashes) {
diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
index 0eea7ff01b48..efee23003067 100644
--- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -555,7 +555,9 @@ TEST_F(ConfigCompileTests, Style) {
return false;
};
EXPECT_TRUE(HeaderFilter("foo.h"));
+ EXPECT_TRUE(HeaderFilter("prefix/foo.h"));
EXPECT_FALSE(HeaderFilter("bar.h"));
+ EXPECT_FALSE(HeaderFilter("foo.h/bar.h"));
}
{
```
</details>
https://github.com/llvm/llvm-project/pull/67749
More information about the cfe-commits
mailing list