Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 9261086

Browse files
authored
Merge pull request #1316 from haskell/upgrade-lsp-0.15
Upgrade to haskell-lsp 0.15
2 parents ee421cf + 0afad05 commit 9261086

19 files changed

+110
-75
lines changed

haskell-ide-engine.cabal

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ library
7070
, gitrev >= 1.1
7171
, haddock-api
7272
, haddock-library
73-
, haskell-lsp == 0.14.*
74-
, haskell-lsp-types == 0.14.*
73+
, haskell-lsp == 0.15.*
74+
, haskell-lsp-types == 0.15.*
7575
, haskell-src-exts
7676
, hie-plugin-api
7777
, hlint (>= 2.0.11 && < 2.1.18) || >= 2.1.22
@@ -192,7 +192,7 @@ test-suite unit-test
192192
, filepath
193193
, free
194194
, haskell-ide-engine
195-
, haskell-lsp-types
195+
, haskell-lsp-types >= 0.15.0.0
196196
, hie-test-utils
197197
, hie-plugin-api
198198
, hoogle > 5.0.11
@@ -278,10 +278,10 @@ test-suite func-test
278278
, data-default
279279
, directory
280280
, filepath
281-
, lsp-test >= 0.5.2
281+
, lsp-test >= 0.6.0.0
282282
, haskell-ide-engine
283-
, haskell-lsp-types == 0.14.*
284-
, haskell-lsp == 0.14.*
283+
, haskell-lsp-types == 0.15.*
284+
, haskell-lsp == 0.15.*
285285
, hie-test-utils
286286
, hie-plugin-api
287287
, hspec

hie-plugin-api/Haskell/Ide/Engine/Config.hs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@ import Language.Haskell.LSP.Types
88

99
-- ---------------------------------------------------------------------
1010

11-
-- | Callback from haskell-lsp core to convert the generic message to the
12-
-- specific one for hie
11+
-- | Given a DidChangeConfigurationNotification message, this function returns the parsed
12+
-- Config object if possible.
1313
getConfigFromNotification :: DidChangeConfigurationNotification -> Either T.Text Config
1414
getConfigFromNotification (NotificationMessage _ _ (DidChangeConfigurationParams p)) =
1515
case fromJSON p of
1616
Success c -> Right c
1717
Error err -> Left $ T.pack err
1818

19+
-- | Given an InitializeRequest message, this function returns the parsed
20+
-- Config object if possible. Otherwise, it returns the default configuration
21+
getInitialConfig :: InitializeRequest -> Either T.Text Config
22+
getInitialConfig (RequestMessage _ _ _ InitializeParams{_initializationOptions = Nothing }) = Right def
23+
getInitialConfig (RequestMessage _ _ _ InitializeParams{_initializationOptions = Just opts}) =
24+
case fromJSON opts of
25+
Success c -> Right c
26+
Error err -> Left $ T.pack err
27+
1928
-- ---------------------------------------------------------------------
2029

2130
data Config =

hie-plugin-api/Haskell/Ide/Engine/Ghc.hs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
module Haskell.Ide.Engine.Ghc
1212
(
1313
setTypecheckedModule
14-
, Diagnostics
14+
, Diagnostics(..)
1515
, AdditionalErrs
1616
, cabalModuleGraphs
1717
, makeRevRedirMapFunc
@@ -21,9 +21,11 @@ import Bag
2121
import Control.Monad.IO.Class
2222
import Data.IORef
2323
import qualified Data.Map.Strict as Map
24-
import Data.Monoid ((<>))
24+
import Data.Semigroup ((<>), Semigroup)
2525
import qualified Data.Set as Set
2626
import qualified Data.Text as T
27+
import qualified Data.Aeson
28+
import Data.Coerce
2729
import ErrUtils
2830

2931
import qualified GhcModCore as GM ( withDynFlags
@@ -45,10 +47,24 @@ import GHC
4547
import IOEnv as G
4648
import HscTypes
4749
import Outputable (renderWithStyle)
50+
import Language.Haskell.LSP.Types ( NormalizedUri(..), toNormalizedUri )
4851

4952
-- ---------------------------------------------------------------------
5053

51-
type Diagnostics = Map.Map Uri (Set.Set Diagnostic)
54+
newtype Diagnostics = Diagnostics (Map.Map NormalizedUri (Set.Set Diagnostic))
55+
deriving (Show, Eq)
56+
57+
instance Semigroup Diagnostics where
58+
Diagnostics d1 <> Diagnostics d2 = Diagnostics (d1 <> d2)
59+
60+
instance Monoid Diagnostics where
61+
mappend = (<>)
62+
mempty = Diagnostics mempty
63+
64+
instance Data.Aeson.ToJSON Diagnostics where
65+
toJSON (Diagnostics d) = Data.Aeson.toJSON
66+
(Map.mapKeys coerce d :: Map.Map T.Text (Set.Set Diagnostic))
67+
5268
type AdditionalErrs = [T.Text]
5369

5470
-- ---------------------------------------------------------------------
@@ -68,10 +84,9 @@ logDiag rfm eref dref df _reason sev spn style msg = do
6884
let msgTxt = T.pack $ renderWithStyle df msg style
6985
case eloc of
7086
Right (Location uri range) -> do
71-
let update = Map.insertWith Set.union uri l
72-
where l = Set.singleton diag
87+
let update = Map.insertWith Set.union (toNormalizedUri uri) (Set.singleton diag)
7388
diag = Diagnostic range (Just $ lspSev sev) Nothing (Just "ghcmod") msgTxt Nothing
74-
modifyIORef' dref update
89+
modifyIORef' dref (\(Diagnostics d) -> Diagnostics $ update d)
7590
Left _ -> do
7691
modifyIORef' eref (msgTxt:)
7792
return ()
@@ -109,9 +124,11 @@ srcErrToDiag df rfm se = do
109124
(m,es) <- processMsgs xs
110125
case res of
111126
Right (uri, diag) ->
112-
return (Map.insertWith Set.union uri (Set.singleton diag) m, es)
127+
return (Map.insertWith Set.union (toNormalizedUri uri) (Set.singleton diag) m, es)
113128
Left e -> return (m, e:es)
114-
processMsgs errMsgs
129+
130+
(diags, errs) <- processMsgs errMsgs
131+
return (Diagnostics diags, errs)
115132

116133
-- ---------------------------------------------------------------------
117134

@@ -121,11 +138,14 @@ myWrapper :: GM.IOish m
121138
-> GM.GmlT m (Diagnostics, AdditionalErrs)
122139
myWrapper rfm action = do
123140
env <- getSession
124-
diagRef <- liftIO $ newIORef Map.empty
141+
diagRef <- liftIO $ newIORef mempty
125142
errRef <- liftIO $ newIORef []
126143
let setLogger df = df { log_action = logDiag rfm errRef diagRef }
127144
setDeferTypedHoles = setGeneralFlag' Opt_DeferTypedHoles
128-
ghcErrRes msg = (Map.empty, [T.pack msg])
145+
146+
ghcErrRes :: String -> (Diagnostics, AdditionalErrs)
147+
ghcErrRes msg = (mempty, [T.pack msg])
148+
129149
handlers = errorHandlers ghcErrRes (srcErrToDiag (hsc_dflags env) rfm )
130150
action' = do
131151
GM.withDynFlags (setLogger . setDeferTypedHoles) action
@@ -167,20 +187,20 @@ setTypecheckedModule uri =
167187
debugm $ "setTypecheckedModule: file mapping state is: " ++ show fileMap
168188
rfm <- GM.mkRevRedirMapFunc
169189
let
170-
ghcErrRes msg = ((Map.empty, [T.pack msg]),Nothing,Nothing)
190+
ghcErrRes msg = ((Diagnostics Map.empty, [T.pack msg]),Nothing,Nothing)
171191
progTitle = "Typechecking " <> T.pack (takeFileName fp)
172192
debugm "setTypecheckedModule: before ghc-mod"
173193
-- TODO:AZ: loading this one module may/should trigger loads of any
174194
-- other modules which currently have a VFS entry. Need to make
175195
-- sure that their diagnostics are reported, and their module
176196
-- cache entries are updated.
177197
-- TODO: Are there any hooks we can use to report back on the progress?
178-
((diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches
198+
((Diagnostics diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches
179199
(GM.getModulesGhc' (myWrapper rfm) fp)
180200
(errorHandlers ghcErrRes (return . ghcErrRes . show))
181201
debugm "setTypecheckedModule: after ghc-mod"
182202

183-
canonUri <- canonicalizeUri uri
203+
canonUri <- toNormalizedUri <$> canonicalizeUri uri
184204
let diags = Map.insertWith Set.union canonUri Set.empty diags'
185205
diags2 <- case (mpm,mtm) of
186206
(Just pm, Nothing) -> do
@@ -212,7 +232,7 @@ setTypecheckedModule uri =
212232
let d = Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing
213233
return $ Map.insertWith Set.union canonUri (Set.singleton d) diags
214234

215-
return $ IdeResultOk (diags2,errs)
235+
return $ IdeResultOk (Diagnostics diags2,errs)
216236

217237
-- ---------------------------------------------------------------------
218238

hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ import Language.Haskell.LSP.Types ( Command(..)
155155
, WorkspaceEdit(..)
156156
, filePathToUri
157157
, uriToFilePath
158+
, toNormalizedUri
158159
)
159160

160161
import Language.Haskell.LSP.VFS ( VirtualFile(..) )
@@ -410,7 +411,7 @@ getVirtualFile :: (MonadIde m, MonadIO m) => Uri -> m (Maybe VirtualFile)
410411
getVirtualFile uri = do
411412
mlf <- ideEnvLspFuncs <$> getIdeEnv
412413
case mlf of
413-
Just lf -> liftIO $ Core.getVirtualFileFunc lf uri
414+
Just lf -> liftIO $ Core.getVirtualFileFunc lf (toNormalizedUri uri)
414415
Nothing -> return Nothing
415416

416417
getConfig :: (MonadIde m, MonadIO m) => m Config

hie-plugin-api/hie-plugin-api.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ library
4545
, ghc
4646
, ghc-mod-core >= 5.9.0.0
4747
, ghc-project-types >= 5.9.0.0
48-
, haskell-lsp == 0.14.*
48+
, haskell-lsp == 0.15.*
4949
, hslogger
5050
, monad-control
5151
, mtl

src/Haskell/Ide/Engine/LSP/CodeActions.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ handleCodeActionReq :: TrackingNumber -> J.CodeActionRequest -> R ()
3232
handleCodeActionReq tn req = do
3333

3434
vfsFunc <- asksLspFuncs Core.getVirtualFileFunc
35-
docVersion <- fmap _version <$> liftIO (vfsFunc docUri)
35+
docVersion <- fmap _version <$> liftIO (vfsFunc (J.toNormalizedUri docUri))
3636
let docId = J.VersionedTextDocumentIdentifier docUri docVersion
3737

3838
let getProvider p = pluginCodeActionProvider p <*> return (pluginId p)

src/Haskell/Ide/Engine/Transport/LspStdio.hs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ data DiagnosticsRequest = DiagnosticsRequest
9393
, trackingNumber :: TrackingNumber
9494
-- ^ The tracking identifier for this request
9595

96-
, file :: J.Uri
96+
, file :: Uri
9797
-- ^ The file that was change and needs to be checked
9898

9999
, documentVersion :: J.TextDocumentVersion
@@ -118,7 +118,7 @@ run scheduler _origDir plugins captureFp = flip E.catches handlers $ do
118118
rin <- atomically newTChan :: IO (TChan ReactorInput)
119119
commandIds <- allLspCmdIds plugins
120120

121-
let dp lf = do
121+
let onStartup lf = do
122122
diagIn <- atomically newTChan
123123
let react = runReactor lf scheduler diagnosticProviders hps sps fps plugins
124124
reactorFunc = react $ reactor rin diagIn
@@ -175,8 +175,11 @@ run scheduler _origDir plugins captureFp = flip E.catches handlers $ do
175175
fps :: Map.Map PluginId FormattingProvider
176176
fps = Map.mapMaybe pluginFormattingProvider $ ipMap plugins
177177

178+
initCallbacks :: Core.InitializeCallbacks Config
179+
initCallbacks = Core.InitializeCallbacks getInitialConfig getConfigFromNotification onStartup
180+
178181
flip E.finally finalProc $ do
179-
CTRL.run (getConfigFromNotification, dp) (hieHandlers rin) (hieOptions commandIds) captureFp
182+
CTRL.run initCallbacks (hieHandlers rin) (hieOptions commandIds) captureFp
180183
where
181184
handlers = [E.Handler ioExcept, E.Handler someExcept]
182185
finalProc = L.removeAllHandlers
@@ -199,7 +202,7 @@ configVal field = field <$> getClientConfig
199202
getPrefixAtPos :: (MonadIO m, MonadReader REnv m)
200203
=> Uri -> Position -> m (Maybe Hie.PosPrefixInfo)
201204
getPrefixAtPos uri pos = do
202-
mvf <- liftIO =<< asksLspFuncs Core.getVirtualFileFunc <*> pure uri
205+
mvf <- liftIO =<< asksLspFuncs Core.getVirtualFileFunc <*> pure (J.toNormalizedUri uri)
203206
case mvf of
204207
Just vf -> VFS.getCompletionPrefix pos vf
205208
Nothing -> return Nothing
@@ -214,7 +217,7 @@ mapFileFromVfs tn vtdi = do
214217
let uri = vtdi ^. J.uri
215218
ver = fromMaybe 0 (vtdi ^. J.version)
216219
vfsFunc <- asksLspFuncs Core.getVirtualFileFunc
217-
mvf <- liftIO $ vfsFunc uri
220+
mvf <- liftIO $ vfsFunc (J.toNormalizedUri uri)
218221
case (mvf, uriToFilePath uri) of
219222
(Just (VFS.VirtualFile _ yitext _), Just fp) -> do
220223
let text' = Rope.toString yitext
@@ -308,7 +311,7 @@ updatePositionMap uri changes = pluginGetFile "updatePositionMap: " uri $ \file
308311
-- ---------------------------------------------------------------------
309312

310313
publishDiagnostics :: (MonadIO m, MonadReader REnv m)
311-
=> Int -> J.Uri -> J.TextDocumentVersion -> DiagnosticsBySource -> m ()
314+
=> Int -> J.NormalizedUri -> J.TextDocumentVersion -> DiagnosticsBySource -> m ()
312315
publishDiagnostics maxToSend uri' mv diags = do
313316
lf <- asks lspFuncs
314317
liftIO $ Core.publishDiagnosticsFunc lf maxToSend uri' mv diags
@@ -797,7 +800,7 @@ reactor inp diagIn = do
797800
withDocumentContents :: J.LspId -> J.Uri -> (T.Text -> R ()) -> R ()
798801
withDocumentContents reqId uri f = do
799802
vfsFunc <- asksLspFuncs Core.getVirtualFileFunc
800-
mvf <- liftIO $ vfsFunc uri
803+
mvf <- liftIO $ vfsFunc (J.toNormalizedUri uri)
801804
lf <- asks lspFuncs
802805
case mvf of
803806
Nothing -> liftIO $
@@ -838,7 +841,7 @@ queueDiagnosticsRequest
838841
:: TChan DiagnosticsRequest -- ^ The channel to publish the diagnostics requests to
839842
-> DiagnosticTrigger
840843
-> TrackingNumber
841-
-> J.Uri
844+
-> Uri
842845
-> J.TextDocumentVersion
843846
-> R ()
844847
queueDiagnosticsRequest diagIn dt tn uri mVer =
@@ -869,11 +872,11 @@ requestDiagnostics DiagnosticsRequest{trigger, file, trackingNumber, documentVer
869872
maxToSend = maxNumberOfProblems clientConfig
870873
sendOne (fileUri,ds') = do
871874
debugm $ "LspStdio.sendone:(fileUri,ds')=" ++ show(fileUri,ds')
872-
publishDiagnosticsIO maxToSend fileUri Nothing (Map.fromList [(Just pid,SL.toSortedList ds')])
875+
publishDiagnosticsIO maxToSend (J.toNormalizedUri fileUri) Nothing (Map.fromList [(Just pid,SL.toSortedList ds')])
873876

874877
sendEmpty = do
875878
debugm "LspStdio.sendempty"
876-
publishDiagnosticsIO maxToSend file Nothing (Map.fromList [(Just pid,SL.toSortedList [])])
879+
publishDiagnosticsIO maxToSend (J.toNormalizedUri file) Nothing (Map.fromList [(Just pid,SL.toSortedList [])])
877880

878881
-- fv = case documentVersion of
879882
-- Nothing -> Nothing
@@ -901,26 +904,28 @@ requestDiagnostics DiagnosticsRequest{trigger, file, trackingNumber, documentVer
901904
when enabled $ makeRequest reql
902905

903906
-- | get hlint and GHC diagnostics and loads the typechecked module into the cache
904-
requestDiagnosticsNormal :: TrackingNumber -> J.Uri -> J.TextDocumentVersion -> R ()
907+
requestDiagnosticsNormal :: TrackingNumber -> Uri -> J.TextDocumentVersion -> R ()
905908
requestDiagnosticsNormal tn file mVer = do
906909
clientConfig <- getClientConfig
907910
let
908911
ver = fromMaybe 0 mVer
909912

910913
-- | If there is a GHC error, flush the hlint diagnostics
911914
-- TODO: Just flush the parse error diagnostics
912-
sendOneGhc :: J.DiagnosticSource -> (Uri, [Diagnostic]) -> R ()
915+
sendOneGhc :: J.DiagnosticSource -> (J.NormalizedUri, [Diagnostic]) -> R ()
913916
sendOneGhc pid (fileUri,ds) = do
914917
if any (hasSeverity J.DsError) ds
915918
then publishDiagnostics maxToSend fileUri Nothing
916919
(Map.fromList [(Just "hlint",SL.toSortedList []),(Just pid,SL.toSortedList ds)])
917920
else sendOne pid (fileUri,ds)
921+
918922
sendOne pid (fileUri,ds) = do
919923
publishDiagnostics maxToSend fileUri Nothing (Map.fromList [(Just pid,SL.toSortedList ds)])
924+
920925
hasSeverity :: J.DiagnosticSeverity -> J.Diagnostic -> Bool
921926
hasSeverity sev (J.Diagnostic _ (Just s) _ _ _ _) = s == sev
922927
hasSeverity _ _ = False
923-
sendEmpty = publishDiagnostics maxToSend file Nothing (Map.fromList [(Just "ghcmod",SL.toSortedList [])])
928+
sendEmpty = publishDiagnostics maxToSend (J.toNormalizedUri file) Nothing (Map.fromList [(Just "ghcmod",SL.toSortedList [])])
924929
maxToSend = maxNumberOfProblems clientConfig
925930

926931
let sendHlint = hlintOn clientConfig
@@ -929,13 +934,13 @@ requestDiagnosticsNormal tn file mVer = do
929934
let reql = GReq tn (Just file) (Just (file,ver)) Nothing callbackl
930935
$ ApplyRefact.lintCmd' file
931936
callbackl (PublishDiagnosticsParams fp (List ds))
932-
= sendOne "hlint" (fp, ds)
937+
= sendOne "hlint" (J.toNormalizedUri fp, ds)
933938
makeRequest reql
934939

935940
-- get GHC diagnostics and loads the typechecked module into the cache
936941
let reqg = GReq tn (Just file) (Just (file,ver)) Nothing callbackg
937942
$ HIE.setTypecheckedModule file
938-
callbackg (pd, errs) = do
943+
callbackg (HIE.Diagnostics pd, errs) = do
939944
forM_ errs $ \e -> do
940945
reactorSend $ NotShowMessage $
941946
fmServerShowMessageNotification J.MtError

stack-8.2.2.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ extra-deps:
2020
- ghc-exactprint-0.5.8.2
2121
- haddock-api-2.18.1
2222
- haddock-library-1.4.4
23-
- haskell-lsp-0.14.0.0
24-
- haskell-lsp-types-0.14.0.1
23+
- haskell-lsp-0.15.0.0
24+
- haskell-lsp-types-0.15.0.0
2525
- haskell-src-exts-1.21.0
2626
- haskell-src-exts-util-0.2.5
2727
- hlint-2.1.17 # last hlint supporting GHC 8.2
2828
- hoogle-5.0.17.9
2929
- hsimport-0.8.8
30-
- lsp-test-0.5.4.0
30+
- lsp-test-0.6.0.0
3131
- monad-dijkstra-0.1.1.2
3232
- pretty-show-1.8.2
3333
- rope-utf16-splay-0.3.1.0

stack-8.4.2.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ extra-deps:
1919
- ghc-lib-parser-8.8.0.20190424
2020
- haddock-api-2.20.0
2121
- haddock-library-1.6.0
22-
- haskell-lsp-0.14.0.0
23-
- haskell-lsp-types-0.14.0.1
22+
- haskell-lsp-0.15.0.0
23+
- haskell-lsp-types-0.15.0.0
2424
- haskell-src-exts-1.21.0
2525
- haskell-src-exts-util-0.2.5
2626
- hlint-2.1.24
2727
- hoogle-5.0.17.9
2828
- hsimport-0.10.0
29-
- lsp-test-0.5.4.0
29+
- lsp-test-0.6.0.0
3030
- monad-dijkstra-0.1.1.2
3131
- pretty-show-1.8.2
3232
- rope-utf16-splay-0.3.1.0

0 commit comments

Comments
 (0)