From: Luke Lau Date: Thu, 28 Jun 2018 23:59:57 +0000 (+0100) Subject: Correct VFS behaviour X-Git-Url: http://git.lukelau.me/?p=opengl.git;a=commitdiff_plain;h=3581d880c87b59cc4c856aee83f77fea9a38890b Correct VFS behaviour Also update tests for next commit of hie in import-code-actions branch --- diff --git a/src/Language/Haskell/LSP/Test/Exceptions.hs b/src/Language/Haskell/LSP/Test/Exceptions.hs index 25db584..c130702 100644 --- a/src/Language/Haskell/LSP/Test/Exceptions.hs +++ b/src/Language/Haskell/LSP/Test/Exceptions.hs @@ -2,6 +2,8 @@ module Language.Haskell.LSP.Test.Exceptions where import Control.Exception import Language.Haskell.LSP.Messages +import Data.Aeson +import qualified Data.ByteString.Lazy.Char8 as B data SessionException = TimeoutException | UnexpectedMessageException String FromServerMessage @@ -19,8 +21,9 @@ instance Show SessionException where "Last message accepted: " ++ show lastMsg show (ReplayOutOfOrderException received expected) = "Replay is out of order:\n" ++ - "Received from server:" ++ show received ++ "\n" ++ - "Expected one of: " ++ concatMap show expected + -- Print json so its a bit easier to update the session logs + "Received from server:\n" ++ B.unpack (encode received) ++ "\n" ++ + "Expected one of:\n" ++ unlines (map (B.unpack . encode) expected) show UnexpectedDiagnosticsException = "Unexpectedly received diagnostics from the server." show (IncorrectApplyEditRequestException msgStr) = "ApplyEditRequest didn't contain document, instead received:\n" ++ msgStr diff --git a/src/Language/Haskell/LSP/Test/Session.hs b/src/Language/Haskell/LSP/Test/Session.hs index b38d1b7..0553160 100644 --- a/src/Language/Haskell/LSP/Test/Session.hs +++ b/src/Language/Haskell/LSP/Test/Session.hs @@ -40,7 +40,7 @@ import qualified Data.HashMap.Strict as HashMap import Data.Maybe import Language.Haskell.LSP.Messages import Language.Haskell.LSP.TH.ClientCapabilities -import Language.Haskell.LSP.Types +import Language.Haskell.LSP.Types hiding (error) import Language.Haskell.LSP.VFS import Language.Haskell.LSP.Test.Compat import Language.Haskell.LSP.Test.Decoding @@ -179,13 +179,22 @@ runSessionWithHandles serverIn serverOut serverHandler config rootDir session = processTextChanges :: FromServerMessage -> SessionProcessor () processTextChanges (ReqApplyWorkspaceEdit r) = do - changeParams <- case r ^. params . edit . documentChanges of - Just (List cs) -> mapM applyTextDocumentEdit cs + + allChangeParams <- case r ^. params . edit . documentChanges of + Just (List cs) -> do + mapM_ (checkIfNeedsOpened . (^. textDocument . uri)) cs + return $ map getParams cs Nothing -> case r ^. params . edit . changes of - Just cs -> concat <$> mapM (uncurry applyChange) (HashMap.toList cs) - Nothing -> return [] + Just cs -> do + mapM_ checkIfNeedsOpened (HashMap.keys cs) + return $ concatMap (uncurry getChangeParams) (HashMap.toList cs) + Nothing -> error "No changes!" - let groupedParams = groupBy (\a b -> (a ^. textDocument == b ^. textDocument)) changeParams + oldVFS <- vfs <$> lift State.get + newVFS <- liftIO $ changeFromServerVFS oldVFS r + lift $ State.modify (\s -> s { vfs = newVFS }) + + let groupedParams = groupBy (\a b -> (a ^. textDocument == b ^. textDocument)) allChangeParams mergedParams = map mergeParams groupedParams ctx <- lift $ lift Reader.ask @@ -196,14 +205,13 @@ processTextChanges (ReqApplyWorkspaceEdit r) = do msg = NotificationMessage "2.0" TextDocumentDidChange p liftIO $ B.hPut h $ addHeader (encode msg) - where applyTextDocumentEdit (TextDocumentEdit docId (List edits)) = do + where checkIfNeedsOpened uri = do oldVFS <- vfs <$> lift State.get ctx <- lift $ lift Reader.ask - -- if its not open, open it - unless ((docId ^. uri) `Map.member` oldVFS) $ do - let fp = fromJust $ uriToFilePath (docId ^. uri) + unless (uri `Map.member` oldVFS) $ do + let fp = fromJust $ uriToFilePath uri contents <- liftIO $ T.readFile fp let item = TextDocumentItem (filePathToUri fp) "" 0 contents msg = NotificationMessage "2.0" TextDocumentDidOpen (DidOpenTextDocumentParams item) @@ -213,21 +221,15 @@ processTextChanges (ReqApplyWorkspaceEdit r) = do newVFS <- liftIO $ openVFS oldVFS msg lift $ State.modify (\s -> s { vfs = newVFS }) - -- we might have updated it above - oldVFS <- vfs <$> lift State.get - + getParams (TextDocumentEdit docId (List edits)) = let changeEvents = map (\e -> TextDocumentContentChangeEvent (Just (e ^. range)) Nothing (e ^. newText)) edits - params = DidChangeTextDocumentParams docId (List changeEvents) - newVFS <- liftIO $ changeVFS oldVFS (fmClientDidChangeTextDocumentNotification params) - lift $ State.modify (\s -> s { vfs = newVFS }) - - return params + in DidChangeTextDocumentParams docId (List changeEvents) textDocumentVersions uri = map (VersionedTextDocumentIdentifier uri) [0..] textDocumentEdits uri edits = map (\(v, e) -> TextDocumentEdit v (List [e])) $ zip (textDocumentVersions uri) edits - applyChange uri (List edits) = mapM applyTextDocumentEdit (textDocumentEdits uri (reverse edits)) + getChangeParams uri (List edits) = map getParams (textDocumentEdits uri (reverse edits)) mergeParams :: [DidChangeTextDocumentParams] -> DidChangeTextDocumentParams mergeParams params = let events = concat (toList (map (toList . (^. contentChanges)) params)) diff --git a/stack.yaml b/stack.yaml index f02f337..92c3ba0 100644 --- a/stack.yaml +++ b/stack.yaml @@ -5,8 +5,8 @@ packages: extra-deps: - github: Bubba/haskell-lsp-client commit: b7cf14eb48837a73032e867dab90db1708220c66 - - github: alanz/haskell-lsp - commit: 5f60fb1cbe09e7026201577ad76fa95116008131 + - github: Bubba/haskell-lsp + commit: 4c705c23cac58b4f6535474acc61d054230b6699 subdirs: - . - ./haskell-lsp-types diff --git a/test/data/renamePass/session.log b/test/data/renamePass/session.log index 4cf5766..0e845c1 100644 --- a/test/data/renamePass/session.log +++ b/test/data/renamePass/session.log @@ -11,7 +11,7 @@ {"tag":"FromClient","contents":["2018-06-03T04:08:40.844374Z",{"tag":"ReqDocumentSymbols","contents":{"jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs"}},"method":"textDocument/documentSymbol","id":25}}]} {"tag":"FromServer","contents":["2018-06-03T04:08:40.859268Z",{"tag":"RspDocumentSymbols","contents":{"result":[{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":3,"character":0},"end":{"line":3,"character":4}}},"kind":12,"name":"main"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":7,"character":5},"end":{"line":7,"character":9}}},"kind":5,"name":"Item"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":8,"character":5},"end":{"line":8,"character":10}}},"kind":5,"name":"Items"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":10,"character":5},"end":{"line":10,"character":12}}},"kind":5,"name":"Command"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":10,"character":15},"end":{"line":10,"character":19}}},"kind":9,"containerName":"Command","name":"Quit"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":11,"character":15},"end":{"line":11,"character":27}}},"kind":9,"containerName":"Command","name":"DisplayItems"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":12,"character":15},"end":{"line":12,"character":22}}},"kind":9,"containerName":"Command","name":"AddItem"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":13,"character":15},"end":{"line":13,"character":25}}},"kind":9,"containerName":"Command","name":"RemoveItem"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":14,"character":15},"end":{"line":14,"character":19}}},"kind":9,"containerName":"Command","name":"Help"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":16,"character":5},"end":{"line":16,"character":10}}},"kind":5,"name":"Error"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":19,"character":0},"end":{"line":19,"character":12}}},"kind":12,"name":"parseCommand"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":28,"character":0},"end":{"line":28,"character":7}}},"kind":12,"name":"addItem"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":31,"character":0},"end":{"line":31,"character":12}}},"kind":12,"name":"displayItems"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":34,"character":0},"end":{"line":34,"character":10}}},"kind":12,"name":"removeItem"},{"location":{"uri":"file:///Users/luke/Desktop/simple.hs","range":{"start":{"line":41,"character":0},"end":{"line":41,"character":16}}},"kind":12,"name":"interactWithUser"}],"jsonrpc":"2.0","id":25}}]} {"tag":"FromClient","contents":["2018-06-03T04:08:46.24927Z",{"tag":"ReqRename","contents":{"jsonrpc":"2.0","params":{"newName":"arseCommand","textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs"},"position":{"line":19,"character":0}},"method":"textDocument/rename","id":32}}]} -{"tag":"FromServer","contents":["2018-06-03T04:08:46.528715Z",{"tag":"RspRename","contents":{"result":{"changes":{"file:///Users/luke/Desktop/simple.hs":[{"range":{"start":{"line":43,"character":0},"end":{"line":43,"character":27}},"newText":" case arseCommand line of"},{"range":{"start":{"line":18,"character":0},"end":{"line":19,"character":38}},"newText":"arseCommand :: String -> Either Error Command\narseCommand line = case words line of"}]}},"jsonrpc":"2.0","id":32}}]} +{"tag":"FromServer","contents":["2018-06-03T04:08:46.528715Z",{"tag":"RspRename","contents":{"result":{"documentChanges":[{"edits":[{"range":{"start":{"line":43,"character":0},"end":{"line":43,"character":27}},"newText":" case arseCommand line of"},{"range":{"start":{"line":18,"character":0},"end":{"line":19,"character":38}},"newText":"arseCommand :: String -> Either Error Command\narseCommand line = case words line of"}],"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs","version":0}}],"changes":{"file:///Users/luke/Desktop/simple.hs":[{"range":{"start":{"line":43,"character":0},"end":{"line":43,"character":27}},"newText":" case arseCommand line of"},{"range":{"start":{"line":18,"character":0},"end":{"line":19,"character":38}},"newText":"arseCommand :: String -> Either Error Command\narseCommand line = case words line of"}]}},"jsonrpc":"2.0","id":32}}]} {"tag":"FromClient","contents":["2018-06-03T04:08:48.300837Z",{"tag":"NotDidChangeTextDocument","contents":{"jsonrpc":"2.0","params":{"contentChanges":[{"text":"module Main where\n\nmain :: IO ()\nmain = do\n let initialList = []\n interactWithUser initialList\n\ntype Item = String\ntype Items = [Item]\n\ndata Command = Quit\n | DisplayItems\n | AddItem String\n | RemoveItem Int\n | Help\n\ntype Error = String\n\narseCommand :: String -> Either Error Command\narseCommand line = case words line of\n [\"quit\"] -> Right Quit\n [\"items\"] -> Right DisplayItems\n \"add\" : item -> Right $ AddItem $ unwords item\n \"remove\" : i -> Right $ RemoveItem $ read $ unwords i\n [\"help\"] -> Right Help\n _ -> Left \"Unknown command\"\n\naddItem :: Item -> Items -> Items\naddItem = (:)\n\ndisplayItems :: Items -> String\ndisplayItems = unlines . map (\"- \" ++)\n\nremoveItem :: Int -> Items -> Either Error Items\nremoveItem i items\n | i < 0 || i >= length items = Left \"Out of range\"\n | otherwise = Right result\n where (front, back) = splitAt (i + 1) items\n result = init front ++ back\n\ninteractWithUser :: Items -> IO ()\ninteractWithUser items = do\n line <- getLine\n case arseCommand line of\n Right DisplayItems -> do\n putStrLn $ displayItems items\n interactWithUser items\n\n Right (AddItem item) -> do\n let newItems = addItem item items\n putStrLn \"Added\"\n interactWithUser newItems\n\n Right (RemoveItem i) ->\n case removeItem i items of\n Right newItems -> do\n putStrLn $ \"Removed \" ++ items !! i\n interactWithUser newItems\n Left err -> do\n putStrLn err\n interactWithUser items\n\n\n Right Quit -> return ()\n\n Right Help -> do\n putStrLn \"Commands:\"\n putStrLn \"help\"\n putStrLn \"items\"\n putStrLn \"add\"\n putStrLn \"quit\"\n interactWithUser items\n\n Left err -> do\n putStrLn $ \"Error: \" ++ err\n interactWithUser items\n"}],"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs","version":1}},"method":"textDocument/didChange"}}]} {"tag":"FromServer","contents":["2018-06-03T04:08:48.357517Z",{"tag":"NotPublishDiagnostics","contents":{"jsonrpc":"2.0","params":{"uri":"file:///Users/luke/Desktop/simple.hs","diagnostics":[]},"method":"textDocument/publishDiagnostics"}}]} {"tag":"FromServer","contents":["2018-06-03T04:08:48.397078Z",{"tag":"NotPublishDiagnostics","contents":{"jsonrpc":"2.0","params":{"uri":"file:///Users/luke/Desktop/simple.hs","diagnostics":[]},"method":"textDocument/publishDiagnostics"}}]}