And make use of this from clangd's CodeComplete and IncludeFixer, although currently they are both restricted only to #include symbols.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
we should have tests in clang/unittests/Tooling/HeaderIncludesTest.cpp and the commit itself should be tagged as [clang][Tooling] rather than [clangd].
clang-tools-extra/clangd/Headers.h | ||
---|---|---|
252 | again it's better to have an enum here. | |
clang-tools-extra/clangd/IncludeFixer.cpp | ||
253 | again can we rather pass the directive enum around? | |
clang/include/clang/Tooling/Inclusions/HeaderIncludes.h | ||
77 | rather than a boolean flag, can you introduce an enum IncludeDirective { Include, Import }; and default it to Include here? | |
89 | we also need to preserve includedirective here now. as the behaviour of insert is to return none iff it's exactly the same spelling. so if there's a #include "foo.h" and we want to insert #import "foo.h" it shouldn't fail. |
thanks, mostly LG. some small changes.
clang-tools-extra/clangd/IncludeFixer.cpp | ||
---|---|---|
263 | nit: llvm::StringLiteral DirectiveSpelling = Directive == tooling::IncludeDirective::Include ? "Include" : "Import"; and use that inside formatv calls | |
clang-tools-extra/clangd/unittests/HeadersTests.cpp | ||
338 | nit: ASSERT_TRUE, here and above. | |
clang/include/clang/Tooling/Inclusions/HeaderIncludes.h | ||
47 | this will leak enum values to the whole clang::tooling namespace. can you make this an enum class IncludeDirective instead (sorry for forgetting that in the initial comment) | |
78 | i don't think we have many callers here. can we just update them instead of defaulting to Include here? | |
78–79 | s/#includes/#includes and #imports/ | |
clang/lib/Tooling/Inclusions/HeaderIncludes.cpp | ||
300 | i know this is not possible today, but just to be safe, can we actually check for import here and default to include ? | |
354 | nit: can you put some braces around the outermost if, as the statements inside are getting long. | |
381 | nit: llvm::StringLiteral DirectiveSpelling = Directive == IncludeDirective::Include ? "include" : "import"; std::string NewInclude = llvm::formatv("#{0} {1}\n", DirectiveSpelling, QuotedName); // this already has an implicit conversion operator to std::string | |
clang/unittests/Tooling/HeaderIncludesTest.cpp | ||
65 | can you also add a removal test? i know we didn't change the implementation, but today there's nothing checking the behaviour. so explicitly encoding the expectation here, especially for the case where we have both #include and #import with same spelling is useful. btw is it likely that #include "foo.h" and #import "foo.h" can refer to different physical headers (e.g. due to framework handling and whatnot)? we're not changing the behaviour today, but if there's a difference, this is likely a bug (that already exists), so we should leave a fixme (or address it here if you got time, by introducing a IncludeDirective parameter into remove. updating users is likely harder in this case, as everyone needs to propagate/store the directive during their analysis). |
Fixes for review + fix diffbase
clang/unittests/Tooling/HeaderIncludesTest.cpp | ||
---|---|---|
65 | No, I don't think #import and #include can refer to different headers. |
thanks!
clang/unittests/Tooling/HeaderIncludesTest.cpp | ||
---|---|---|
77 | nit: feel free to use raw string literals here and in other tests (or angled (<) includes), e.g: llvm::StringRef Code = R"cpp( #include <abc.h> #import <abc.h> int x;)cpp"; EXPECT_EQ("int x;", remove(Code, "<abc.h>")); | |
81 | nit: just inline "int x" to the LHS. |
again it's better to have an enum here.