X-Git-Url: http://git.lukelau.me/?a=blobdiff_plain;f=src%2FLanguage%2FHaskell%2FLSP%2FTest.hs;h=7e87fcb3b915756b7057a71d0b511eb626b2b588;hb=bd2ac7da01645dc111a6912be661bc13b7f9340f;hp=1c425fb89cc49aa0af526b99ab7d5753d261a679;hpb=23447141213d07c7d290574f5fd6e8c58b346c8f;p=lsp-test.git diff --git a/src/Language/Haskell/LSP/Test.hs b/src/Language/Haskell/LSP/Test.hs index 1c425fb..7e87fcb 100644 --- a/src/Language/Haskell/LSP/Test.hs +++ b/src/Language/Haskell/LSP/Test.hs @@ -37,8 +37,9 @@ module Language.Haskell.LSP.Test , module Language.Haskell.LSP.Test.Parsing -- * Utilities -- | Quick helper functions for common tasks. - -- ** Initialization + -- ** Lifecycle , initializeResponse + , exitServer -- ** Documents , openDoc , openDoc' @@ -94,7 +95,6 @@ import qualified Data.Text.IO as T import Data.Aeson import Data.Default import qualified Data.HashMap.Strict as HashMap -import Data.IORef import qualified Data.Map as Map import Data.Maybe import Language.Haskell.LSP.Types @@ -138,8 +138,7 @@ runSessionWithConfig :: SessionConfig -- ^ Configuration options for the session -> Session a -- ^ The session to run. -> IO a runSessionWithConfig config serverExe caps rootDir session = do - -- We use this IORef to make exception non-fatal when the server is supposed to shutdown. - exitOk <- newIORef False + pid <- getCurrentProcessID absRootDir <- canonicalizePath rootDir @@ -151,8 +150,7 @@ runSessionWithConfig config serverExe caps rootDir session = do (Just TraceOff) Nothing withServer serverExe (logStdErr config) $ \serverIn serverOut _ -> - runSessionWithHandles serverIn serverOut (\h c -> catchWhenTrue exitOk $ listenServer h c) config caps rootDir $ do - + runSessionWithHandles serverIn serverOut listenServer config caps rootDir exitServer $ do -- Wrap the session around initialize and shutdown calls initRspMsg <- request Initialize initializeParams :: Session InitializeResponse @@ -160,7 +158,6 @@ runSessionWithConfig config serverExe caps rootDir session = do initRspVar <- initRsp <$> ask liftIO $ putMVar initRspVar initRspMsg - sendNotification Initialized InitializedParams case lspConfig config of @@ -169,23 +166,10 @@ runSessionWithConfig config serverExe caps rootDir session = do -- Run the actual test result <- session - - liftIO $ atomicWriteIORef exitOk True - sendNotification Exit ExitParams - return result where - catchWhenTrue :: IORef Bool -> IO () -> IO () - catchWhenTrue exitOk a = - a `catch` (\e -> do - x <- readIORef exitOk - unless x $ throw (e :: SomeException)) - - -- | Listens to the server output, makes sure it matches the record and - -- signals any semaphores - -- Note that on Windows, we cannot kill a thread stuck in getNextMessage. - -- So we have to wait for the exit notification to kill the process first - -- and then getNextMessage will fail. + -- | Listens to the server output until the shutdown ack, + -- makes sure it matches the record and signals any semaphores listenServer :: Handle -> SessionContext -> IO () listenServer serverOut context = do msgBytes <- getNextMessage serverOut @@ -195,13 +179,15 @@ runSessionWithConfig config serverExe caps rootDir session = do let msg = decodeFromServerMsg reqMap msgBytes writeChan (messageChan context) (ServerMessage msg) - listenServer serverOut context + case msg of + (RspShutdown _) -> return () + _ -> listenServer serverOut context -- | The current text contents of a document. documentContents :: TextDocumentIdentifier -> Session T.Text documentContents doc = do vfs <- vfs <$> get - let file = vfs Map.! (doc ^. uri) + let file = vfs Map.! toNormalizedUri (doc ^. uri) return $ Rope.toText $ Language.Haskell.LSP.VFS._text file -- | Parses an ApplyEditRequest, checks that it is for the passed document @@ -435,7 +421,7 @@ getCodeActionContext doc = do -- | Returns the current diagnostics that have been sent to the client. -- Note that this does not wait for more to come in. getCurrentDiagnostics :: TextDocumentIdentifier -> Session [Diagnostic] -getCurrentDiagnostics doc = fromMaybe [] . Map.lookup (doc ^. uri) . curDiagnostics <$> get +getCurrentDiagnostics doc = fromMaybe [] . Map.lookup (toNormalizedUri $ doc ^. uri) . curDiagnostics <$> get -- | Executes a command. executeCommand :: Command -> Session () @@ -464,7 +450,7 @@ getVersionedDoc :: TextDocumentIdentifier -> Session VersionedTextDocumentIdenti getVersionedDoc (TextDocumentIdentifier uri) = do fs <- vfs <$> get let ver = - case fs Map.!? uri of + case fs Map.!? toNormalizedUri uri of Just (VirtualFile v _ _) -> Just v _ -> Nothing return (VersionedTextDocumentIdentifier uri ver) @@ -589,3 +575,7 @@ getCodeLenses tId = do rsp <- request TextDocumentCodeLens (CodeLensParams tId) :: Session CodeLensResponse case getResponseResult rsp of List res -> pure res + +-- | Exit the server after request its shutdown +exitServer :: Session() +exitServer = request_ Shutdown (Nothing :: Maybe Value) >> sendNotification Exit ExitParams