-
Notifications
You must be signed in to change notification settings - Fork 92
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
Type safe API, significantly simplify Core, Remove Capture, Update to 3.15, Split out features into modules, Use TH to generate datatypes, Add proper support for dynamic registration #244
Conversation
Great stuff! Going to try plugging this into lsp-test to dogfood this. At the very least this will require a major major version bump (i.e. haskell-lsp-types-1.0) or putting this into alternative library a-la haskell-lsp-types-safe if this type level stuff is too much overhead for users. |
I'm currently working on migrating the example server |
|
src/Language/Haskell/LSP/Core.hs
Outdated
|
||
-- Send initial notification | ||
liftIO $ sf $ J.fromServerNot $ J.NotificationMessage "2.0" J.SProgress $ | ||
mkSendNotFunc tvarCtx J.SProgress $ |
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.
Couldn't these notifications be moved inside the Right () ->
case branch above to fix the 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.
Unfortunately it needs to return the result of running the user's callback, which would have to happen inside the response handler. I think it might be possible with the use of some async
|
6aa60a4
to
fdf3a2f
Compare
1259b4a
to
30044cb
Compare
6850027
to
886c45c
Compare
commit 6aa60a4 Author: Zubin Duggal <[email protected]> Date: Fri Jun 5 15:46:30 2020 +0530 Separate out static LanguageContextData from dynamic, introduce LspM, handle initialize specially commit 0cf607f Author: Zubin Duggal <[email protected]> Date: Fri Jun 5 00:48:06 2020 +0530 Eliminate duplication of parsing logic commit cb8bd35 Author: Zubin Duggal <[email protected]> Date: Thu Jun 4 23:01:05 2020 +0530 Import LSP types unqualified in Core and other cleanup commit bb7a3f8 Author: Zubin Duggal <[email protected]> Date: Thu Jun 4 19:16:09 2020 +0530 tweaks for lsp-test commit 58609e1 Author: Luke Lau <[email protected]> Date: Thu May 14 18:21:46 2020 +0100 Fix method type in Unregistration This could probably be backported commit 3f35d04 Author: Luke Lau <[email protected]> Date: Tue May 12 18:03:58 2020 +0100 Add back erroneous deletion commit 63b80f6 Author: Luke Lau <[email protected]> Date: Tue May 12 17:58:48 2020 +0100 Update the example server commit 5514e76 Author: Luke Lau <[email protected]> Date: Tue May 12 17:27:11 2020 +0100 Tidy up some stuff in Core, add getVersionedTextDoc When wanting to create textdocumentedits, you need to pass a versioned text doc identifier. But often times the request that you are working with only gives you an unversioned text doc identifier. This is a helper function to convert it to the appropriate version by looking it up in the VFS. commit aedaa2a Merge: 56a2c9e bce18bc Author: Luke Lau <[email protected]> Date: Tue May 12 17:34:29 2020 +0100 Merge branch 'singleton-methods' of github.com:wz1000/haskell-lsp into singleton-methods commit bce18bc Author: Luke Lau <[email protected]> Date: Tue May 12 16:37:21 2020 +0100 Hide LSP ids from the users This changes the send function into two separate functions, where parameters are passed instead of raw messages. That way haskell-lsp can do the bookkeeping work of figuring out the appropriate request id, and we can get rid of MessageFuncs since the user no longer needs to construct messages from scratch. commit 2d65114 Author: Luke Lau <[email protected]> Date: Mon May 11 16:40:55 2020 +0100 Rename old sendFunc -> sendMsg commit f08b599 Author: Luke Lau <[email protected]> Date: Sun May 10 20:43:25 2020 +0100 Fix haddock Was interpreting the pipe as a haddock commit 56a2c9e Author: Luke Lau <[email protected]> Date: Mon May 11 16:40:55 2020 +0100 Rename old sendFunc -> sendMsg commit be92b48 Author: Luke Lau <[email protected]> Date: Sun May 10 20:43:25 2020 +0100 Fix haddock Was interpreting the pipe as a haddock commit cafca98 Author: Luke Lau <[email protected]> Date: Sun May 10 17:44:45 2020 +0100 Make *ResponseHandler newtypes commit a4fbbcf Author: Luke Lau <[email protected]> Date: Sun May 10 17:16:01 2020 +0100 Add explicit type parameter to LookupFunc Needed to build on ghc-8.10 Also some whitespace fixes my editor seemed to throw in automatically commit 2c32c56 Author: Zubin Duggal <[email protected]> Date: Fri May 8 19:13:10 2020 +0530 Add utility functions for parsing server and client messages commit 2d67cb5 Author: Zubin Duggal <[email protected]> Date: Fri May 8 15:46:06 2020 +0530 Rename Message -> Method, Types -> Message, extract LspId into its own module commit c51dc57 Author: Zubin Duggal <[email protected]> Date: Fri May 8 15:03:03 2020 +0530 Make ResponseMessage use Either again commit 4b9341f Author: Zubin Duggal <[email protected]> Date: Fri May 8 14:11:56 2020 +0530 Safer API for IxMap commit f2c617c Author: Zubin Duggal <[email protected]> Date: Fri May 8 13:07:43 2020 +0530 Split out IxMap into new module commit ddd8555 Author: Zubin Duggal <[email protected]> Date: Fri May 8 12:04:35 2020 +0530 move synonyms to new module commit a7ffa3e Author: Zubin Duggal <[email protected]> Date: Fri May 8 11:34:42 2020 +0530 remove capturing and misc spring cleaning commit 8e91bdb Author: Zubin Duggal <[email protected]> Date: Fri May 8 11:07:14 2020 +0530 vastly improve the TH for generating FromJSON method instances commit f6403bf Author: Zubin Duggal <[email protected]> Date: Fri May 8 02:55:51 2020 +0530 Hack together some nasty looking TH to reduce SMethod FromJSON boilerplate commit b9ac067 Author: Zubin Duggal <[email protected]> Date: Fri May 8 01:36:21 2020 +0530 Cleanup Core.hs commit 0c15553 Author: Zubin Duggal <[email protected]> Date: Thu May 7 20:33:04 2020 +0530 fix clientMethodJSON/serverMethodJSON commit 3f28fb2 Merge: c84e4e0 2ff1129 Author: Zubin Duggal <[email protected]> Date: Thu May 7 18:14:23 2020 +0530 Merge branch 'master' of https://github.com/alanz/haskell-lsp into singleton-methods commit c84e4e0 Merge: c194d51 c19ed85 Author: Zubin Duggal <[email protected]> Date: Wed Apr 29 00:00:07 2020 +0530 Merge branch 'master' of https://github.com/alanz/haskell-lsp into singleton-methods commit c194d51 Author: Zubin Duggal <[email protected]> Date: Sat Apr 25 00:05:23 2020 +0530 Redesign methods once more commit bfb3b55 Author: Zubin Duggal <[email protected]> Date: Fri Dec 20 16:23:08 2019 +0530 Fix merge commit a098073 Merge: 4cc2902 5497e9f Author: Zubin Duggal <[email protected]> Date: Tue Dec 17 17:14:40 2019 +0530 Merge branch 'master' of https://github.com/alanz/haskell-lsp into singleton-methods commit 4cc2902 Author: Zubin Duggal <[email protected]> Date: Sat Jul 13 17:01:37 2019 +0530 Dependent types, type safe responses and methods
Currently chewing through the langauge features Done completion, completion resolve, hover, signature help Moving everything in clientcapabilities/servercapabilities into the respective modules. Rewriting things to use makeExtendingDatatype. Deleting a lot of the copied + pasted in parts of the speification as most of them are out of date
See haskell#210 and haskell#211 Also rename Progress to ProgressAmount to avoid clashing with Progress method in haskell-lsp-types Also fix haskell#252, wrapping sendProgress notifications in bracket Also add example func-test for said bug
5011bc9
to
8e6fbb7
Compare
One high-level comment: this PR has data Method (p :: Provenance) (t :: MethodType) where It is not immediately clear what |
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.
Granted, this may look weird for a total stranger to review this request 😅
Actually I was about to start working on a PR to add some documentation on this repo (because when I first tried to hack on HLS a few weeks ago, I got quickly frustrated by the lack of documentation on LSP types) and before starting, I checked open PRs (to ensure this was not already worked on) and I noticed this HUGE PR, which may very well induce many conflicts with any PR I could start hacking.
So long story short, I decided to review this PR, with 0 knowledge of this repo 😁
As such, my questions/remarks are mostly about documentation and style, I hope you don't mind 🙇
Cheers and good luck with this huge PR!
@@ -0,0 +1,21 @@ | |||
# This is a sample hie.yaml file for opening haskell-language-server |
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.
Thank you for providing an hie.yaml
file!
However this leads to weird errors for non-Cabal users, would you mind moving it to hie.yaml.cbl
and also provide a Stack equivalent hie.yaml.stack
? Here's what it should contain:
cradle:
stack:
- path: "./haskell-lsp-types"
component: "haskell-lsp-types:lib"
- path: "./src"
component: "haskell-lsp:lib"
- path: "./test"
component: "haskell-lsp:test:haskell-lsp-test"
- path: "./func-test"
component: "func-test:test:func-test"
- path: "./example/Reactor.hs"
component: "haskell-lsp:exe:lsp-demo-reactor-server"
- path: "./example/Simple.hs"
component: "haskell-lsp:exe:lsp-demo-simple-server"
I copied the hie.yaml.xxx
names from https://github.com/haskell/haskell-language-server
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE ViewPatterns #-} | ||
|
||
module Data.IxMap where |
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.
Maybe this module deserves some documentation, in particular IxOrd
and IxMap
? At least what's their purpose, ideally an example of usage?
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 module should be internal to haskell-lsp and haskell-lsp-types, maybe we should move it to Language.Haskell.LSP.Types.Internal.IxMap
or something
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 it might be useful if users want to make maps keyed on LspId
or RegistrationId
.
parseJSON Null = return (List []) | ||
parseJSON v = List <$> parseJSON v | ||
|
||
data Empty = Empty deriving (Eq,Ord,Show) |
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.
Maybe this also deserves some documentation? If I understand correctly, its main use (compared to ()
) is to change the JSON representation to null
rather than an empty list []
|
||
-- --------------------------------------------------------------------- | ||
|
||
{- |
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.
General question: why remove documentation and links to LSP spec? I think, if anything, that this was pretty useful (though it deserves to be present on more types)
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.
The inline comments were out of date for the most part unfortunately. What I would like to ultimately see however is the specification documentation as haddocks on the types themselves (which we might need https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3330 first!)
Just (fn, write) -> | ||
let revMap = case uriToFilePath (fromNormalizedUri uri) of | ||
Just uri_fp -> Map.insert fn uri_fp $ reverseMap vfs | ||
-- TODO: Does the VFS make sense for URIs which are not files? |
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.
Is this a question for maintainers? Or just a reminder to solve this before merging?
Co-authored-by: Julien Debon <[email protected]>
This PR is a big, breaking change that has spent a long time in the oven. I am requesting reviews while I work to patch upstream packages.
The main motivation behind this is to provide a safe API for constructing and sending LSP requests and responses. The
method
field of request messages is no longer divorced from theparam
field,so as to statically ensure that you provide the correct payload for your messages
The methods are represented on the type level by a GADT tagged by the methods provenance(
FromServer | FromClient
), and its message type (Request | Notification
). At the value level, it is represented by a constructor of a singleton type for the method.These methods are mapped to parameter and response types with the help of two type families,
Using this encoding, you only need to check these two places to know everything
you need about a particular method type
As these are all listed in order and grouped by provenance, correlating with the LSP spec becomes easy.
We ensure the well-formedness of responses by tagging
LspId
with a phantommethod type parameter, which is used in
ResponseMessage
to ensure thatyou are responding to a request with the correct params.
Major changes in
haskell-lsp-types
:Language.Haskell.LSP.Types.Method
RequestMessage
,NotificationMessage
andResponseMessage
updated using theMessageParams
andResponseParams
type families in order to be typesafe as described aboveLspId
moved toLanguage.Haskell.LSP.Types.LspId
Language.Haskell.LSP.Types.Synonyms
Data.IxMap
that helps in dealing with method-tagged ids and response handlers in a type-safe mannerMajor changes in
haskell-lsp
:Capture.hs
@bubba and I came to this conclusion after discussing the state of
lsp-test
.The capturing mechanism in
haskell-lsp
is currently lacking in quite a few ways and even misses some communication with the client.The plan is to add a
lsp-test-conduit
tool to lsp-test that wraps around language servers and accurately capturesinformation independent of
haskell-lsp
Messages.hs
: it is no longer requiredHandlers
type was replaced by a functionJ.SClientMethod m -> Maybe (Handler m)
hh
was slightly altered in order to be generalizable for all requestshandlerMap
now callshh
to handle all request. Any special cases/extra work to be done byhaskell-lsp
for this requestis uniformly handled by generalizing the
changeVFS
parameter thathh
previously accepted.sendFunc
inLspFuncs
was changed to be the typesafeServerMessageFunc
ServerMessageFunc
isSomeServerMessageWithResponse -> IO ()
SomeServerMessageWithResponse
is a type safe way to specify both a message tobe sent from the server to the client as well as forcing you to specify
a handler/callback for the eventual response
ClientResponseHanlder
callback with every message that you can call with a(well-typed) reponse to the message
Suggested reading order:
Language/Haskell/LSP/Types/Method.hs
Language/Haskell/LSP/Types/Message.hs
Language/Haskell/LSP/Types/LspId.hs
These should give you a basic overview of what this patch is trying to accomplish
After this, the changes in
Language/Haskell/LSP/Core.hs
are pretty significantLastly, the following modules contain some new utility code:
Data/IxMap.hs
Language/Haskell/LSP/Types/Utils.hs
The rest of the changes are pretty trivial.
TODO:
lsp-test