o Remove IncludeInsertion LSP command.
o Populate include insertion edits synchromously in completion items.
o Share the code completion compiler instance and precompiled preamble to get existing inclusions in main file.
o Include insertion logic lives only in CodeComplete now.
o Use tooling::HeaderIncludes for inserting new includes.
o Refactored tests.
Details
- Reviewers
sammccall - Commits
- rG63f419a5c676: [clangd] Populate #include insertions as additional edits in completion items.
rL332363: [clangd] Populate #include insertions as additional edits in completion items.
rCTE332363: [clangd] Populate #include insertions as additional edits in completion items.
Diff Detail
- Repository
- rCTE Clang Tools Extra
Event Timeline
I'm concerned about the scope of this patch - it does too many things and touches too many files for me to feel comfortable that I understand it well enough to review.
Is it possible to split it up? (You mention 6 distinct things in the description).
Have tried to focus comments on what seems to be the core parts.
clangd/CodeComplete.cpp | ||
---|---|---|
247 | I can't parse this name as it relates to this class. This inserts includes, it isn't itself an insertion. | |
clangd/CodeComplete.h | ||
79 | IncLocations isn't an appropriate name for the variable - it's coupled to the preamble | |
clangd/Headers.h | ||
1 | The interface to this header looks a bit complex and entangled after this change.
it would be nice to achieve a simpler interface with the restricted set of functionality, or expand the functionality... | |
28 | I had some trouble working out the role of this struct (e.g. that it might have been a *proposed* inclusion). So this could maybe be // An #include directive that we found in the main file. struct Inclusion but it does also seem a little strange that this is part of the public interface at all (other than for testing) | |
39 | This doesn't seem to add any semantics over the vector, so it just seems to obscure a bit. | |
67–102 | the main value-add of this class over HeaderSearch is that it determines whether to insert, so that should probably be mentioned. | |
68 | can you describe the design a little bit here? | |
69 | This name suggests a set or sequence of include path entries (-I flags). | |
72 | hmm, if we require the InclusionLocations to be prebuilt for the preamble, why can't we do the same for non-preamble includes? i.e. can't we split up the "collect existing includes" and "calculate new includes" parts to simplify the interface here? Among other things, testing would be a ton easier. | |
75 | The contract around PP is really confusing: we need to be able to mutate it (to add PP hooks), we need someone to use it in the middle, we need to use its HeaderSearch structure later, and to add more confusion we have shared ownership. Maybe instead something like:
Then usage looks like: IncludePaths Paths(SM, PreambleLocs, PP.getHeaderSearch()); PP.addPPCallbacks(Paths.record()); // do something with PP Paths.calculate(...); and AFAICT, all the lifetime issues/interactions would be communicated by the types. | |
76 | consider adding a addExistingInclude(InclusionLocation) instead of the InclusionLocations parameter here. This gives you somewhere to document what this does and what it's for (constructors are always crowded), and makes the callsites a little more self-documenting. It also lets you take InclusionLocations out of the public interface here, which I think would be a win. | |
95 | is this used? | |
97 | and this? | |
107 | is this unused? this seems like it could be a natural part of this class... | |
clangd/tool/ClangdMain.cpp | ||
103 ↗ | (On Diff #145385) | why this change? |
unittests/clangd/HeadersTests.cpp | ||
97 | Is there any way we can avoid creating another copy of this code? |
Sorry about the big change! And thanks for the early feedback on headers library!
I think there are a few things going on here:
- Removing the existing way of include insertion (additional command)
- Populating #include insertion in code completion workflow.
- Refactoring #include path calculation to make 2 work
- Move some helpers (e.g. replacementToEdit) to public header.
- Share InclusionLocation between preamble code and header insertion code.
I was trying to keep 1 and 2 in the same patch so that we don't regress features, but it's probably fine if no one is actually using it... I'm happy to split that out if having them in the same patch makes review hard.
I think 2 and 3 could stay in the same patch as it would be hard to see where the design in 3 came from without 2. But if you got the idea, I guess they could still be split.
4 and 5 should be independent enough to be 2 separate patches. I thought the changes were small and could be included in this patch. I'll split them as well now that you mention.
clangd/Headers.h | ||
---|---|---|
1 | Refactored code according to your suggestions. PTAL
Sorry... forgot to delete some leftover after an earlier revision. | |
28 | Thanks! Inclusion sounds better. Apart from header insertion and testing, this is also shared with the preamble code. | |
69 | I think there are three pretty independent parts of include insertion:
Initially, I grouped all these in one class (something like HeaderInsertion) which returns an edit given the URIs in the symbol info, but it turned out to be hard to test. For example, among all 3 components, 2 was the most interesting piece to test, while an integration test is probably enough for 1 and 3, but we would need to create URIs (due to 1) and retrieve include name from edits (due to 3) in order to test 2. Since each individual piece seemed independent enough, I decided to keep them separated. I also kept URI logic out of the header library so that it could potentially be shared with other features that are not index-based include insertion, or be moved out of clangd as a tooling library. In the new revision, I refactored the code according to your suggestions and got rid of this class. | |
72 | Good idea! | |
107 | Thanks for the catches! Missed these after iterating from an earlier version.,, | |
clangd/tool/ClangdMain.cpp | ||
103 ↗ | (On Diff #145385) | Oops, this was not intended. I increased the limit for profiling. Reverted... |
unittests/clangd/HeadersTests.cpp | ||
97 | This was moved here. Headers library no longer needs compiler instance. I'm not sure if there is an easier way to test HeaderSearch and PPCallbacks without a compiler instance... |
clangd/CodeComplete.cpp | ||
---|---|---|
247 | Do you think it would make sense to move this class to Headers.h? This would reduce the non-completion related code in this large file. | |
261 | If we wanted to avoid URI dependencies in Headers.h but move this class there, the Declaring/Inserted headers could be HeaderFile (possibly invalid). toHeaderFile would stay here. This might be a neater separation of concerns anyway. | |
317 | This strikes me as overly defensive. We should never have an include header but no declaration location, and if the declaration header is invalid then the include inserter should take care of that, not this code (I think?) | |
700 | PreambleInclusions? | |
969 | this callback is a bit confusing, particularly sequencing/lifetimes. This would be a bit more natural if we had IncludeInsertion::addExisting(Insertion) instead of IncludeInsertion::setExisting(vector<Insertion>), I think. | |
1130 | nit: /*Inclusions=*/ | |
clangd/CodeComplete.h | ||
73 | should this be PreambleInclusions, or is it broader than that? | |
clangd/Headers.h | ||
69 | OK, SGTM | |
unittests/clangd/HeadersTests.cpp | ||
97 | Moved from where? You could consider adding inclusions to TestTU (sorry it's in D46524 which I thought had already landed, but should today) |
should this be PreambleInclusions, or is it broader than that?