on master help sign in
Normalize percent-encoding in URIs (#1603)

This implements step 1. from #1507 and also adds a test that uses an insane percent-encoding to verify that we can handle that. I also tested this in the IDE on Windows and Linux.

commit3fd52a88ab95f47da4d8b7f6247b91c09166d69b authorMoritz Kiefer <moritz.kiefer@purelyfunctional.org> dateWed 12 Jun 2019, 15:20 (7 years ago) parent35e2d88
4 files changed+19−23
src/Development/IDE/Functions/GHCError.hs+1−1 src/Development/IDE/State/FileStore.hs+3−3 src/Development/IDE/State/Shake.hs+1−1 src/Development/IDE/Types/Diagnostics.hs+14−18
src/Development/IDE/Functions/GHCError.hs+1−1
@@ -78,7 +78,7 @@ srcSpanToFilename (RealSrcSpan real) = FS.unpackFS $ srcSpanFile real
7878
7979srcSpanToLocation :: SrcSpan -> Location
8080srcSpanToLocation src =
81− Location (D.filePathToUri' $ srcSpanToFilename src) (srcSpanToRange src)
81+ Location (fromNormalizedUri $ D.filePathToUri' $ srcSpanToFilename src) (srcSpanToRange src)
8282
8383-- | Convert a GHC severity to a DAML compiler Severity. Severities below
8484-- "Warning" level are dropped (returning Nothing).
src/Development/IDE/State/FileStore.hs+3−3
@@ -43,9 +43,9 @@ import Language.Haskell.LSP.VFS
4343-- the builtin VFS without spawning up an LSP server. To be able to test things
4444-- like `setBufferModified` we abstract over the VFS implementation.
4545data VFSHandle = VFSHandle
46− { getVirtualFile :: Uri -> IO (Maybe VirtualFile)
47− , setVirtualFileContents :: Uri -> T.Text -> IO ()
48− , removeVirtualFile :: Uri -> IO ()
46+ { getVirtualFile :: NormalizedUri -> IO (Maybe VirtualFile)
47+ , setVirtualFileContents :: NormalizedUri -> T.Text -> IO ()
48+ , removeVirtualFile :: NormalizedUri -> IO ()
4949 }
5050
5151instance IsIdeGlobal VFSHandle
src/Development/IDE/State/Shake.hs+1−1
@@ -403,7 +403,7 @@ publishDiagnosticsNotification :: FilePath -> [Diagnostic] -> LSP.FromServerMess
403403publishDiagnosticsNotification fp diags =
404404 LSP.NotPublishDiagnostics $
405405 LSP.NotificationMessage "2.0" LSP.TextDocumentPublishDiagnostics $
406− LSP.PublishDiagnosticsParams (filePathToUri' fp) (List diags)
406+ LSP.PublishDiagnosticsParams (fromNormalizedUri $ filePathToUri' fp) (List diags)
407407
408408setPriority :: (Enum a) => a -> Action ()
409409setPriority p =
src/Development/IDE/Types/Diagnostics.hs+14−18
@@ -18,6 +18,9 @@ module Development.IDE.Types.Diagnostics (
1818 List(..),
1919 StoreItem(..),
2020 Uri(..),
21+ NormalizedUri,
22+ LSP.toNormalizedUri,
23+ LSP.fromNormalizedUri,
2124 noLocation,
2225 noRange,
2326 noFilePath,
@@ -47,7 +50,6 @@ import qualified Data.Map as Map
4750import qualified Data.Text as T
4851import Data.Text.Prettyprint.Doc.Syntax
4952import qualified Data.SortedList as SL
50−import Network.URI (escapeURIString)
5153import qualified Text.PrettyPrint.Annotated.HughesPJClass as Pretty
5254import qualified Language.Haskell.LSP.Types as LSP
5355import Language.Haskell.LSP.Types as LSP (
@@ -56,7 +58,10 @@ import Language.Haskell.LSP.Types as LSP (
5658 , filePathToUri
5759 , List(..)
5860 , DiagnosticRelatedInformation(..)
61+ , NormalizedUri(..)
5962 , Uri(..)
63+ , toNormalizedUri
64+ , fromNormalizedUri
6065 )
6166import Language.Haskell.LSP.Diagnostics
6267
@@ -68,20 +73,11 @@ import Development.IDE.Types.Location
6873-- So we have our own wrapper here that supports empty filepaths.
6974uriToFilePath' :: Uri -> Maybe FilePath
7075uriToFilePath' uri
71− | uri == filePathToUri' "" = Just ""
76+ | uri == filePathToUri "" = Just ""
7277 | otherwise = LSP.uriToFilePath uri
7378
74−-- TODO This is a temporary hack: VSCode escapes ':' in URIs while haskell-lsp’s filePathToUri doesn't.
75−-- This causes issues since haskell-lsp stores the original URI in the VFS while we roundtrip once via
76−-- uriToFilePath' and filePathToUri before we look it up again. At that point : will be unescaped in the URI
77−-- so the lookup fails. The long-term solution here is to avoid roundtripping URIs but that is a larger task
78−-- so for now we have our own version of filePathToUri that does escape colons.
79−filePathToUri' :: FilePath -> Uri
80−filePathToUri' fp =
81− case T.stripPrefix "file:" (getUri uri) of
82− Just suffix -> Uri $ T.pack $ "file:" <> escapeURIString (/= ':') (T.unpack suffix)
83− Nothing -> uri
84− where uri = filePathToUri fp
79+filePathToUri' :: FilePath -> NormalizedUri
80+filePathToUri' fp = toNormalizedUri $ filePathToUri fp
8581
8682ideErrorText :: FilePath -> T.Text -> FileDiagnostic
8783ideErrorText fp = errorDiag fp "Ide Error"
@@ -200,10 +196,10 @@ setStageDiagnostics fp timeM stage diags (ProjectDiagnostics ds) =
200196 ProjectDiagnostics $ updateDiagnostics ds uri timeM diagsBySource
201197 where
202198 diagsBySource = Map.singleton (Just $ T.pack $ show stage) (SL.toSortedList diags)
203− uri = filePathToUri fp
199+ uri = filePathToUri' fp
204200
205−fromUri :: LSP.Uri -> FilePath
206−fromUri = fromMaybe noFilePath . uriToFilePath'
201+fromUri :: LSP.NormalizedUri -> FilePath
202+fromUri = fromMaybe noFilePath . uriToFilePath' . fromNormalizedUri
207203
208204getAllDiagnostics ::
209205 ProjectDiagnostics stage ->
@@ -217,7 +213,7 @@ getFileDiagnostics ::
217213 [LSP.Diagnostic]
218214getFileDiagnostics fp ds =
219215 maybe [] getDiagnosticsFromStore $
220− Map.lookup (filePathToUri fp) $
216+ Map.lookup (filePathToUri' fp) $
221217 getStore ds
222218
223219filterDiagnostics ::
@@ -226,5 +222,5 @@ filterDiagnostics ::
226222 ProjectDiagnostics stage
227223filterDiagnostics keep =
228224 ProjectDiagnostics .
229− Map.filterWithKey (\uri _ -> maybe True keep $ uriToFilePath' uri) .
225+ Map.filterWithKey (\uri _ -> maybe True keep $ uriToFilePath' $ fromNormalizedUri uri) .
230226 getStore