-
-
Notifications
You must be signed in to change notification settings - Fork 389
Implement completionItem/resolve #3204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Wow, this is a big deal! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good! I'm going to do my usual routine and question whether it's really the case that adding a complex feature like this requires 0 lines of explanatory comments :)
docs <- getDocumentationTryGhc packageState curMod n | ||
toCompItem :: Parent -> Module -> T.Text -> Name -> Maybe (LImportDecl GhcPs) -> [CompItem] | ||
toCompItem par m mn n imp' = | ||
-- docs <- getDocumentationTryGhc packageState curMod n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented out code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wz1000 is this the line causing the eager deserialization of interfaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This along with lookupName
(the lookupName
is slightly worse since it forces typechecking the iface which is also done lazily, getDocumentation
will still load in the interface if it wasn't needed before and deserialize the documentation part).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still commented out
mdkm <- liftIO $ runAction "Completion resolve" ide $ use GetDocMap file | ||
case mdkm of | ||
Nothing -> pure (Right comp) | ||
Just (DKMap dm km) -> liftIO $ runAction "Completion resolve" ide $ do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can make this kind of pattern simpler using the pattern we use elsewhere in the codebase using pluginResponse
at the top level and maybeToEither
and friends.
Also: tests? |
Oh one last thing: we definitely want a cautionary comment on the main completion handler warning people not to accidentally pull in information from interface files in future! |
#3080 gets the HIE file during completions, is that acceptable? |
I am pretty confident getting the HIE file is 👍 |
I merged the record dot completions PR, which has introduced some conflicts. |
4fe528a
to
f91edea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous comments still need addressing also.
-- the NameCache. | ||
-- Reason: this may the first occurrence of (say) Foo.bar we have encountered. | ||
-- If we need to explore its value we will load Foo.hi; but meanwhile all we | ||
-- need is a Name for it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is that all we need? surely it will be the wrong Name and then we could get into trouble later? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In particular it looks like you look it up in the module environment later, how can that work if they're fresh?
1e1ad22
to
c983c6b
Compare
dee48c1
to
e7073d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm for wingman
b367ca7
to
cf0e3c3
Compare
cc06936
to
7cf643b
Compare
7988b03
to
fe7d852
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine, although I do think there were a few more comments that could be addressed.
.github/workflows/test.yml
Outdated
@@ -221,7 +221,7 @@ jobs: | |||
name: Test hls-explicit-imports-plugin test suite | |||
run: cabal test hls-explicit-imports-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-explicit-imports-plugin --test-options="$TEST_OPTS" | |||
|
|||
- if: matrix.test | |||
- if: matrix.test && matrix.os != 'windows-latest' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why? is there an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
call-hierarchy tests were very flaky, I've fixed the problem I think and removed this.
docs <- getDocumentationTryGhc packageState curMod n | ||
toCompItem :: Parent -> Module -> T.Text -> Name -> Maybe (LImportDecl GhcPs) -> [CompItem] | ||
toCompItem par m mn n imp' = | ||
-- docs <- getDocumentationTryGhc packageState curMod n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still commented out
Wait for index instead of compliation before making requests as indexing happens in the background in parallel with everything else, so we have to synchronize on the database being ready before making any call hierarchy requests.
fe7d852
to
2d58fe1
Compare
pre-commit check is also failing, I think you're missing formatting |
Implement
completionItem/resolve
to lazily resolve types and documentation for completion items.This results in very big memory usage improvments while also improving the responsiveness of completions.
Usually when GHC typechecks code, it reads in and deserializes interfaces lazily, so if the code imports
a bunch of modules, the interfaces will only be read in and deserialized if a particular name is actually
required for typechecking.
However, when we greedily generate completion lists, the act of querying for types and documentation results
in sucking in and deserializing interface sections for every single name in scope. This is very bad for
memory usage as it negates virtually all the benefits of lazy deserialization.
Instead, we can compute types and documentation on demand for individual completion items using the
completionItem/resolve
LSP functionality.
A downside to this is that we can no longer generate snippets for functions
arguments with placeholders mentioning the types because we no longer have this
information available when we generate the original completion, and it is not
supported by LSP to resolve the actual completion snippet using
completionItem/resolve
.However, I don't personally consider this to be a very big deal because this
feature was unreliable (eg for things from the export map which weren't in
scope) and I found it to be quite annoying when it did work.