Fix formatting requests sending misversioned didChange notifications 0.11.0.3
authorLuke Lau <luke_lau@icloud.com>
Mon, 27 Jul 2020 12:19:07 +0000 (13:19 +0100)
committerLuke Lau <luke_lau@icloud.com>
Mon, 27 Jul 2020 12:19:07 +0000 (13:19 +0100)
Inside updateState, if a WorkspaceEdit with just the changes field was
set then it would send back didChange notifications where all the
document versions started from 0. This fixes it to actually take the
current version inside the VFS before sending it back

lsp-test.cabal
src/Language/Haskell/LSP/Test.hs
src/Language/Haskell/LSP/Test/Session.hs

index ecc05342061caa95905773a2f7decc5e10d3fa46..25154d036065fbb397d2e5c76e155ce190252265 100644 (file)
@@ -1,5 +1,5 @@
 name:                lsp-test
-version:             0.11.0.2
+version:             0.11.0.3
 synopsis:            Functional test framework for LSP servers.
 description:
   A test framework for writing tests against
index 200dbb84807856959a2dfe0bf92faa8947eb8958..dbfc8012973e0165ce97a9c508b440f380b1371e 100644 (file)
@@ -664,6 +664,7 @@ formatRange doc opts range = do
 applyTextEdits :: TextDocumentIdentifier -> List TextEdit -> Session ()
 applyTextEdits doc edits =
   let wEdit = WorkspaceEdit (Just (HashMap.singleton (doc ^. uri) edits)) Nothing
+      -- Send a dummy message to updateState so it can do bookkeeping
       req = RequestMessage "" (IdInt 0) WorkspaceApplyEdit (ApplyWorkspaceEditParams wEdit)
   in updateState (ReqApplyWorkspaceEdit req)
 
index 2a0eb08c0f6cdb604894ea46220081ba91864240..4b1793f28312986437bae1c8e4e8ff32c1cead5d 100644 (file)
@@ -308,15 +308,18 @@ updateState (NotPublishDiagnostics n) = do
 
 updateState (ReqApplyWorkspaceEdit r) = do
 
+  -- First, prefer the versioned documentChanges field
   allChangeParams <- case r ^. params . edit . documentChanges of
     Just (List cs) -> do
       mapM_ (checkIfNeedsOpened . (^. textDocument . uri)) cs
       return $ map getParams cs
+    -- Then fall back to the changes field
     Nothing -> case r ^. params . edit . changes of
       Just cs -> do
         mapM_ checkIfNeedsOpened (HashMap.keys cs)
-        return $ concatMap (uncurry getChangeParams) (HashMap.toList cs)
-      Nothing -> error "No changes!"
+        concat <$> mapM (uncurry getChangeParams) (HashMap.toList cs)
+      Nothing ->
+        error "WorkspaceEdit contains neither documentChanges nor changes!"
 
   modifyM $ \s -> do
     newVFS <- liftIO $ changeFromServerVFS (vfs s) r
@@ -360,11 +363,20 @@ updateState (ReqApplyWorkspaceEdit r) = do
           let changeEvents = map (\e -> TextDocumentContentChangeEvent (Just (e ^. range)) Nothing (e ^. newText)) edits
             in DidChangeTextDocumentParams docId (List changeEvents)
 
-        textDocumentVersions uri = map (VersionedTextDocumentIdentifier uri . Just) [0..]
+        -- For a uri returns an infinite list of versions [n,n+1,n+2,...]
+        -- where n is the current version
+        textDocumentVersions uri = do
+          m <- vfsMap . vfs <$> get
+          let curVer = fromMaybe 0 $
+                _lsp_version <$> m Map.!? (toNormalizedUri uri)
+          pure $ map (VersionedTextDocumentIdentifier uri . Just) [curVer..]
 
-        textDocumentEdits uri edits = map (\(v, e) -> TextDocumentEdit v (List [e])) $ zip (textDocumentVersions uri) edits
+        textDocumentEdits uri edits = do
+          vers <- textDocumentVersions uri
+          pure $ map (\(v, e) -> TextDocumentEdit v (List [e])) $ zip vers edits
 
-        getChangeParams uri (List edits) = map getParams (textDocumentEdits uri (reverse edits))
+        getChangeParams uri (List edits) =
+          map <$> pure getParams <*> textDocumentEdits uri (reverse edits)
 
         mergeParams :: [DidChangeTextDocumentParams] -> DidChangeTextDocumentParams
         mergeParams params = let events = concat (toList (map (toList . (^. contentChanges)) params))