Skip to content
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

References via hiedb #704

Merged
merged 5 commits into from
Jan 30, 2021
Merged

References via hiedb #704

merged 5 commits into from
Jan 30, 2021

Conversation

wz1000
Copy link
Collaborator

@wz1000 wz1000 commented Dec 29, 2020

Continuing from haskell/ghcide#898

Includes support for references, workspace symbols, faster loading by loading (stale) .hie files from disk and jump to definition for arbitrary dependencies.

As described here and here

TODO:

  • Release hiedb on hackage
  • Tests

I'll be pressed for time in the near future, so would appreciate any help to get this over the finish line, especially with the first two points above.

@peterwicksstringfield
Copy link
Contributor

peterwicksstringfield commented Jan 1, 2021

I wrote some tests in HLS, for looking up references within one module, between a module and a module that imports it, between a module and a module that imports it transitively, and between a package and another package on which it depends (with the two packages being in the same cabal project).

textDocument/references has an extra flag includeDeclaration. When this flag is false, looking up the symbol "foo" in "foo = 2; bar = foo + 3" should pick up "... = foo + ..." as a reference, but not "foo = ...". The references provider in this branch currently ignores this flag. There's a test with an expected failure documenting this.

There's a test in test/functional/TypeDefinition failing too. "find definition of parameterized data type". It looks like, when we have this code:

module Lib where

data Parameter a = Parameter a

parameterId :: Parameter a -> Parameter a
parameterId pid = p[CURSOR HERE]id

And we ask for the type definition of the symbol pid, we get the "data Parameter a = Parameter a" line that defines the type Parameter a AND the "parameterId :: Parameter a -> Parameter a" line that defines the type of parameterId. That's new, is it supposed to be doing that?

...

Also I hacked up a bunch of HLS to make it compile (at least on 8.10.2). Don't take that part of the code, it's the unit tests I am interested in here. I just needed them to run. (Hacked up HLS works in vscode though, and get all references does what it's supposed to. XD)

(The tactics and class plugins will need to be updated to account for this:

 data HieAstResult
-  = HAR
+  = forall a. HAR
   { hieModule :: Module
-  , hieAst :: !(HieASTs Type)
-  , refMap :: RefMap
+  , hieAst :: !(HieASTs a)
+  , refMap :: RefMap a
   -- ^ Lazy because its value only depends on the hieAst, which is bundled in this type
   -- Lazyness can't cause leaks here because the lifetime of `refMap` will be the same
   -- as that of `hieAst`
+  , hieKind :: !(HieKind a)
+  -- ^ Is this hie file loaded from the disk, or freshly computed?
   }

)

I also fixed a couple hlint hints, and a couple ghcide tests.

wz1000#1

@jneira jneira linked an issue Jan 3, 2021 that may be closed by this pull request
@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 3, 2021

And we ask for the type definition of the symbol pid, we get the "data Parameter a = Parameter a" line that defines the type Parameter a AND the "parameterId :: Parameter a -> Parameter a" line that defines the type of parameterId. That's new, is it supposed to be doing that?

It's returning the definition of the type variable a (which is defined by the implicit forall on the type declaration), though I can see how it may be confusing. The idea is to support things that have something like type Foo (Bar Baz), returning the definition of Foo, Bar and Baz.

@peterwicksstringfield
Copy link
Contributor

That makes sense. Symbol "pid" has type "Parameter a" ... and if I want the definition of "Parameter a", then that comes in two parts: the definition of "Parameter" ("data Parameter = ...") and the definition of "a" ("forall a. ..."). Okay question answered. That test needs to be updated to expect two type definitions. (I will make this change on my PR.)

@wz1000 wz1000 force-pushed the hiedb branch 3 times, most recently from 23f091f to 39f460a Compare January 9, 2021 12:49
@wz1000 wz1000 marked this pull request as ready for review January 9, 2021 13:16
@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 9, 2021

I think this is ready for review while I work on final tweaks to tests and the HLS CLI parser.

@wz1000 wz1000 requested a review from pepeiborra January 9, 2021 13:19
@wz1000 wz1000 force-pushed the hiedb branch 2 times, most recently from 7429171 to d8178bd Compare January 10, 2021 10:00
ghcide/exe/Arguments.hs Outdated Show resolved Hide resolved
ghcide/exe/Main.hs Outdated Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Shake.hs Show resolved Hide resolved
ghcide/src/Development/IDE/LSP/HoverDefinition.hs Outdated Show resolved Hide resolved
Comment on lines 102 to 103
let docUri = (<> "#" <> selector <> showGhc name) <$> docFu
srcUri = (<> "#" <> showGhc name) <$> srcFu
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced of replacing showName here, which is a more intentional operation than showGhc.
In the future showGhc could change in unexpected ways, while showName would be more stable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completions uses showGhc all over the place, lets fix this in another PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this PR is making it worse, right? At least previously they calling showName was expressing the intent. All I am asking is to preserve that intent

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were keeping showName?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used showNameWithoutUniques instead of resurrecting showName.

ghcide/src/Development/IDE/Core/Rules.hs Outdated Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Rules.hs Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Rules.hs Outdated Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Rules.hs Outdated Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Rules.hs Show resolved Hide resolved
@jneira jneira mentioned this pull request Jan 11, 2021
9 tasks
@wz1000 wz1000 force-pushed the hiedb branch 5 times, most recently from d623623 to 4b85e2a Compare January 17, 2021 23:22
@wz1000 wz1000 force-pushed the hiedb branch 2 times, most recently from 169000d to 121ae0b Compare January 26, 2021 12:13
@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 26, 2021

I've squashed this down into one commit with a clear commit message.

Copy link
Collaborator

@pepeiborra pepeiborra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benchmarks do not show any regressions, and I think this is ready to merge. Super awesome, thank you @wz1000 !!!

It's a big change, please land it asap so that HEAD users have a chance to play with it before the next release.

ghcide/bench/lib/Experiments.hs Outdated Show resolved Hide resolved
ghcide/exe/Arguments.hs Show resolved Hide resolved
ghcide/session-loader/Development/IDE/Session.hs Outdated Show resolved Hide resolved
@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 26, 2021

I think it would be good to have a "stable" release before this change lands, since that would buy us some time to address any issues that may arise.

@pepeiborra
Copy link
Collaborator

I think it would be good to have a "stable" release before this change lands, since that would buy us some time to address any issues that may arise.

There hasn't been an HLS release in a while and the last one had a pretty annoying diagnostics bug, so I think this is a good idea (for HLS).

But for ghcide, there was a release pretty recently and I don't think it's a priority to make another one.

@wz1000 wz1000 force-pushed the hiedb branch 2 times, most recently from cfca3b0 to 5db56b7 Compare January 27, 2021 20:33
@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 28, 2021

@jneira sorry to bother you, but would you have time to do a release of HLS so that this can land? I would do it, but I'm not familiar enough with the HLS release process.

@jneira
Copy link
Member

jneira commented Jan 28, 2021

Sure, I will try to do asap
I want to complete the actual doc about releases and involve other people (@Ailrun f.e. 😬 if agree), to share the knowledge, but it can be done after the next release

@Ailrun
Copy link
Member

Ailrun commented Jan 28, 2021

If there's a detailed documentation, I'm good for that.

This was referenced Jan 28, 2021
@michaelpj
Copy link
Collaborator

Is there any user documentation we need as part of this? e.g. is it possible to clear out the hiedb files if it's misbehaving? Should we add some troubleshooting notes?

@wz1000
Copy link
Collaborator Author

wz1000 commented Jan 29, 2021

@michaelpj there is a whole hiedb subcommand added to hls and ghcide to allow you to query and modify the db. Ideally, the changes in this PR and the existence of the database should be invisible to users. Of course, this is not going to be the case, and we would need to directly inspect the database to debug issues. The sub-command exists for this precisely purpose (with automatically generated help messages). I would like to see what kinds of issues people actually end up running into before offering any kind of debugging advice.

wz1000 and others added 5 commits January 30, 2021 14:15
1. Add 'indexHieFile' and rule 'GetModIfaceFromDiskAndIndex' to maintain
   database integrity
   - 'writeHieFile' -> 'writeAndIndexHieFile'
2. References fromm database
3. Use db for go to definition
   - Return multiple definitions for things defined in boot files
   - More robust definitions for multi-component
4. Add persistent stale rules to answer queries immedidately on startup
   - Setup `unsafeGlobalDynFlags` on startup
5. Add hiedb command line to ghcide and hls

Co-authored-by: Pepe Iborra <pepeiborra@me.com>
Co-authored-by: Peter Wicks Stringfield <peterwicksstringfield@gmail.com>
Co-authored-by: Pepe Iborra <pepeiborra@me.com>
@wz1000 wz1000 added the merge me Label to trigger pull request merge label Jan 30, 2021
@mergify mergify bot merged commit 755fc37 into haskell:master Jan 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge me Label to trigger pull request merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Go-to definition jumps to hs-boot files
7 participants