This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Merge index-provided completions with those from Sema.
ClosedPublic

Authored by sammccall on Jan 17 2018, 6:52 AM.

Details

Summary
  • we match on USR, and do a field-by-field merge if both have results
  • scoring is post-merge, with both sets of information available (for now, sema priority is used if available, static score for index results)
  • limit is applied to the complete result set (previously index ignored limit)
  • CompletionItem is only produces for the returned results
  • If the user doesn't type a scope, we send the scopeless query to the index for global completion.

This needs tests for the new functionality, but I thought you could take a look
while I work on that. It passes the existing tests, and works in VSCode.

Diff Detail

Repository
rL LLVM

Event Timeline

sammccall created this revision.Jan 17 2018, 6:52 AM

Overall looks good! Some ideas about code structure inlined.

clangd/CodeComplete.cpp
327 ↗(On Diff #130173)

Does the recorder still do fuzzy-matching?

339 ↗(On Diff #130173)

It seems that CCContext can change during ProcessCodeCompleteResults. It's unclear what the implication is for codeCompletionString at the end.

434 ↗(On Diff #130173)

Maybe dropped()?

679 ↗(On Diff #130173)

The overall behavior looks good. And the comments really help understand the code! As chatted offline, we might want to break down this function, and a class that book-keeps all the states might be helpful.

734 ↗(On Diff #130173)

I think we already only query namespace scopes now?

747 ↗(On Diff #130173)

As discussed offline, we want to defer unqualified completion support (IIRC?) until we have enough information about visible scopes (i.e. after D42073).

782 ↗(On Diff #130173)

It would be a bit more natural if the decision of building CCS is hidden in the candidate. Maybe pass in a callback for creating CCS from a sema result and let candidate decide whether to create CCS or not? This would also get rid of the constraint for build.

789 ↗(On Diff #130173)

Would it make sense to move the score construction into build, by passing in necessary information in Candidate.second?

sammccall updated this revision to Diff 130417.Jan 18 2018, 8:20 AM
sammccall marked 7 inline comments as done.

Addressed review comments, except for "refactor into class" which is still todo.
Added explicit check of code completion context kind.
Added tests (mostly updating existing ones).

Converted the big codeComplete function to a CodeCompleteFlow class

LGTM

clangd/CodeComplete.cpp
743 ↗(On Diff #130440)

InComplete can probably be output variable of queryIndex and addCandidate instead of a state?

hokein added a subscriber: hokein.Jan 19 2018, 6:06 AM

looks good to me too, just a few nits.

clangd/CodeComplete.cpp
308 ↗(On Diff #130440)

add return None to make compiler happier? I think it might trigger -Wreturn-type warning.

341 ↗(On Diff #130440)

I'd suggesting rename the variable Sema to another name, since Sema is already a class name (although naming is hard).

845 ↗(On Diff #130440)

consider using llvm::set_difference here?

Oops, I forgot to submit comments with my last update.
I don't think there's anything surprising so I'll land this, but let me know if you want any changes!

clangd/CodeComplete.cpp
743 ↗(On Diff #130440)

Certainly it can (it needs to be an out-param, because these functions already have primary return values). Just as these could all be free functions :-)

I tried it out - I find the out-params are a bit messy/hard to read, and they'd need to be added to mergeResults, queryIndex and addCandidate. It adds quite a lot of noise, and I'm not sure on balance emphasizing the flow of IsIncomplete is worth obscuring the flow of the results themselves. If you disagree, let me know (or just change it!)

339 ↗(On Diff #130173)

This function is only ever called once, but this isn't documented anywhere :-\
Added an assert.

734 ↗(On Diff #130173)

Nope, we never check the completion context kind, and I think I've seen cases where we end up completing when it's inappropriate.

Fixed this (see the new allowIndex() check) and removed the fixme.

747 ↗(On Diff #130173)

Done - we now complete only symbols in the global scope.
I added two FIXMEs describing how we can progressively make this better over time. Do they match your understanding?

782 ↗(On Diff #130173)

I agree, but trying this out I found it equally hard to read, and not as decoupled as I'd hope.
So as discussed offline, sticking with the ugly-and-direct approach :-)

sammccall marked 2 inline comments as done.Jan 19 2018, 6:23 AM
sammccall added inline comments.
clangd/CodeComplete.cpp
308 ↗(On Diff #130440)

added llvm_unreachable.

845 ↗(On Diff #130440)

The value type is different: Symbol vs Symbol*

This revision was not accepted when it landed; it landed in state Needs Review.Jan 19 2018, 6:36 AM
This revision was not accepted when it landed; it landed in state Needs Review.
This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.
sammccall marked an inline comment as done.