This is an archive of the discontinued LLVM Phabricator instance.

[clangd][c++20] Drop first template argument in code completion in some contexts.
ClosedPublic

Authored by massberg on Jul 4 2023, 8:01 AM.

Details

Summary

In case of a top level context the first template argument of a concept
should be dropped. Currently the indexer doesn't support different
signatures for different contexts (for an index entry always the default
Symbol context is used). Thus we add a hack which checks if we are in
a top level context and have a concept and in that case removes the
first argument of the signature and snippet suffix. If there is only a
single argument, the signature and snippet suffix are completely
removed. The check for the first argument is done by simply looking for
the first comma which should be sufficient in most cases.

Diff Detail

Event Timeline

massberg created this revision.Jul 4 2023, 8:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 4 2023, 8:01 AM
massberg requested review of this revision.Jul 4 2023, 8:01 AM

Cool! This makes sense, and is much cheaper than actually working out how to render the abbreviated arg list and store it in the index.

Nice that TopLevel gives us some of these contexts, but I suspect it's not all. (If not, it's fine to handle just this case for now and leave the others as tests showing the bad behavior with a FIXME)

clang-tools-extra/clangd/CodeComplete.cpp
321

RemoveFirst => removeFirst

321

(if this function takes StringRef instead you get nicer APIs like split, and less copying)

327

I don't love the arithmetic, the repetition of 2 as the length of the string, and the reliance on the space after the comma.

Maybe: (assuming Signature is a StringRef)

[First, Rest] = Signature.split(",");
if (Rest.empty()) // no comma => one argument => no list needed
  return "";
return ("<" + Rest.ltrim()).str();
479

more important to say why rather than what: which cases?

/// When a concept is used as a type-constraint (e.g. `Iterator auto x`),
/// and in some other contexts, its first type argument is not written.
/// Drop the parameter from the signature.
482

maybe leave a comment:

dropping the first placeholder from the suffix will leave a $2 with no $1.
However, editors appear to deal with this OK.

(assuming you've tested this in vscode)

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
3964

this doesn't look valid - what is U here?
shouldn't requires A be `requires A<...>?

(generally if we're mixing completion cases in one file it's important that they're valid so subsequent ones parse correctly - also to not confuse the reader)

3968–3972

I think it might be worth renaming "other" to "expr", it seems to more clearly describe all the situations here

3974–3975

can you also add tests for

void abbreviated(A auto x) {}

template<A auto X> int constrainedNTTP();
clang-tools-extra/clangd/unittests/TestIndex.h
38 ↗(On Diff #537108)

this diverges from how the other helpers work: they're mostly creating minimal skeletons and encapsulate the mess of synthesizing USRs.

Instead of extending the function here, we can assign the appropriate fields on the returned symbol at the callsite (or add a local helper to do so)

(objcSym is also out-of-line with the pattern here, but we shouldn't follow it off the rails)

massberg updated this revision to Diff 537161.Jul 4 2023, 1:02 PM

Update code by resolving comments.

massberg marked 7 inline comments as done.Jul 4 2023, 1:06 PM
massberg added inline comments.
clang-tools-extra/clangd/CodeComplete.cpp
327

Thanks! I agree that the code with StringRefs looks much better.

482

Yes I've tested it with vscode and it looks fine. Why is the numbering of the parameters required?

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
3974–3975

The
`
void abbreviated(A auto x) {}
`

case doesn't work yet. I will fix it in a follow-up patch.

massberg updated this revision to Diff 537163.Jul 4 2023, 1:12 PM
massberg marked 2 inline comments as done.

Add test case that isn't correctly handled yet and add FIXME comment.

massberg edited the summary of this revision. (Show Details)Jul 4 2023, 1:13 PM
massberg edited the summary of this revision. (Show Details)
sammccall accepted this revision.Jul 5 2023, 2:31 AM
sammccall added inline comments.
clang-tools-extra/clangd/CodeComplete.cpp
482

The numbering defines the logical sequence, in practice which placeholder will be selected first, and the order that pressing <tab> will visit the others in.

I guess this could make sense when they're not parameters but some other snippet placeholders, but honestly this seems more confusing than useful, I'd prefer they were un-numbered and always LTR.

This revision is now accepted and ready to land.Jul 5 2023, 2:31 AM
nridge added a subscriber: nridge.Jul 6 2023, 6:26 PM