-
Notifications
You must be signed in to change notification settings - Fork 97
Conversation
Go to definition for dependencies works in the following way: First, the user must index the Then, whenever we report a definition in one of the dependencies(say The |
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've taken a first look, there's loads of changes.
,argsVersion :: Bool | ||
,argsShakeProfiling :: Maybe FilePath | ||
,argsTesting :: Bool | ||
,argsThreads :: Int | ||
,argsVerbose :: Bool | ||
,argFilesOrCmd :: a |
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.
Can we call this simply argCmd
? Or even take it out of this record, and change the type of getArguments
to (Arguments, IdeCmd)
.
@@ -778,16 +819,16 @@ useWithStaleFast' key file = do | |||
liftIO $ case r of |
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.
Isn't the call to getValues
made redundant by lastValueIO
?
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.
We still need to know whether the key is the map so that we can decide to block or not?
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 don't see it, could you walk me through the cases?
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.
There are three cases:
1a) The value isn't in the store, and we can't (or fail to) compute a stale persistent value - we want to wait for the rule to compute a fresh value (matching the previous semantics)
1b) The value isn't in the store but we can compute a stale persistent value - return the value
2) The value is in the store - we can just return it.
(sorry for the delay, hope you will be able to page this back in)
The situation with the |
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.
Second pass done.
Can you write a high-level comment describing the integration with hiedb?
In particular, regarding the paragraph below, for non FOIs, what things are now obtained from hiedb instead of from .hie
files?
Under this paradigm, ghcide acts as an indexing service for hiedb, generating .hi and .hie files which are indexed and saved in the database, available for all future queries, even across restarts. A local cache of .hie files/typechecked modules is maintained on top of this to answer queries for the files the user is currently editing, while non-local information about other files in the project is accessed through the database.
src/Development/IDE/Core/Rules.hs
Outdated
persistentHieFileRule :: Rules () | ||
persistentHieFileRule = addPersistentRule GetHieAst $ \file -> runMaybeT $ do | ||
res <- readHieFileForSrcFromDisk file | ||
let refmap = generateReferencesMap . getAsts . hie_asts $ res | ||
pure $ HAR (hie_module res) (hie_asts res) refmap (HieFromDisk res) | ||
|
||
readHieFileForSrcFromDisk :: NormalizedFilePath -> MaybeT IdeAction HieFile | ||
readHieFileForSrcFromDisk file = do | ||
db <- asks hiedb | ||
log <- asks $ L.logInfo . logger | ||
row <- MaybeT $ liftIO $ HieDb.lookupHieFileFromSource db $ fromNormalizedFilePath file | ||
let hie_loc = HieDb.hieModuleHieFile row | ||
liftIO $ log $ "LOADING HIE FILE :" <> T.pack (show file) | ||
readHieFileFromDisk hie_loc |
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 am trying to understand what the persistent rule buys us. Ghcide already reuses .hie
files from the cache dir at startup if they are up-to-date, so in what cases does this make a difference?
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.
Ghcide already reuses .hie files from the cache dir at startup if they are up-to-date
It doesn't, at least not for things like hover/definition etc.
With the persistent rule stuff we get:
- Instant availability of select IDE features (hover/definition...) on startup, even before
cabal configure
etc. finish - If the project doesn't compile on startup, we can still use the above features from the stale
.hie
file.
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.
That's awesome.
But surely ghcide will block until the cradle is loaded, as it usually happens on a Notification?
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.
But surely ghcide will block until the cradle is loaded, as it usually happens on a Notification?
Ah, this is indeed the behavior in vscode. I didn't notice because my client sends the request immediately after initialize if the server isn't already running, so I was getting instant responses most of the time.
I think we can serialize notifications with respect to each other, but handle requests concurrently without blocking?
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.
We decided to process notifications synchronously to ensure consistency after seeing test failures showing real inconsistency issues around e.g. completions. I don't see how to avoid such inconsistencies if we handle requests concurrently with notifications.
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.
haskell/hie-bios#265 will make startup much faster when it lands, so we will get most of the benefits of quick startup even without async notifications. Do we still want to keep this mechanism to provide code navigation when the project doesn't compile on startup, or should I just remove it?
If we are keeping it, I think it needs a re-design. I'm thinking another variant of define
in which we can return a stale value if the regular codepath fails.
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've answered yourself! Get rid of this version and leave the redesign for future work
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 that my assumption that ghcide blocks on a FileOpened Notification might be wrong.
The handler calls restartShakeSession
but doesn't wait on the results, so it might not be actually blocking.
The open telemetry stuff will make it very easy to find out whether it blocks or not.
Sounds like extending the |
What should If it's just the same folder where |
What ever You would put something like the following in a
One limitation is that I don't know if there is a way for ghcide to pass such options to cabal/stack, but it might not be a good idea anyway since it would force recompilation of all dependencies. If it is possible, we can have a special /cc @fendor |
This might just about work, but in the long term, do we want |
@wz1000 when do you expect to be able to push this forward? |
Unfortunately I won't be able to get back to this for another 1-2 weeks at least. Meanwhile, @jhrcek has very kindly volunteered to help out with tests and documentation for the hiedb library itself, before its hackage release. |
Use db for findDef save source file location to db Find source for boot files Use DynFlags from HieDb instead of unsafeGlobalDynFlags Return multiple definitions don't typecheck files on load Add support for persistent stale values Add persistent hie file rule docs wip better typedef defs for deps update hiedb Fix for files with errors Fix build integrate hiedb commands and set dynflags on boot workspace symbol tweaks, cabal.project Write ifaces on save use real mtime for saved files safe indexing bump hiedb Proper refs for FOIs hlint Update exe/Main.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Review comments update hiedb Update src/Development/IDE/Core/Shake.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Update src/Development/IDE/Core/Rules.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Update src/Development/IDE/Core/Rules.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Update src/Development/IDE/Spans/AtPoint.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Update src/Development/IDE/Core/Rules.hs Co-authored-by: Pepe Iborra <pepeiborra@me.com> Apply suggestions from code review Co-authored-by: Pepe Iborra <pepeiborra@me.com> more careful re-indexing update for hiedb-0.1.0.0
I've removed all the stuff to do with non-project dependencies for now, will re-add in another PR. |
The ghcide Github project is becoming archived and merged into https://github.com/haskell/haskell-language-server This PR will need to be reopened in the HLS repo. To do that, create a new branch from HLS HEAD in your HLS repo and do:
Thanks! |
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:
hiedb
on hackageI'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.