on 163bbc9 help sign in
86 lines 2.8 kB history raw
1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# LANGUAGE OverloadedStrings #-}
6-- | Types and functions for working with source code locations.
7module Development.IDE.Types.Location
8 ( Location(..)
9 , noFilePath
10 , noRange
11 , Position(..)
12 , Range(..)
13 , Uri(..)
14 , NormalizedUri
15 , LSP.toNormalizedUri
16 , LSP.fromNormalizedUri
17 , NormalizedFilePath
18 , fromUri
19 , toNormalizedFilePath
20 , fromNormalizedFilePath
21 , filePathToUri
22 , filePathToUri'
23 , uriToFilePath'
24 ) where
26import Language.Haskell.LSP.Types (Location(..), Range(..), Position(..))
29import Control.DeepSeq
30import Data.Maybe as Maybe
31import Data.Hashable
32import Data.String
33import System.FilePath
34import qualified Language.Haskell.LSP.Types as LSP
35import Language.Haskell.LSP.Types as LSP (
36 filePathToUri
37 , NormalizedUri(..)
38 , Uri(..)
39 , toNormalizedUri
40 , fromNormalizedUri
41 )
44-- | Newtype wrapper around FilePath that always has normalized slashes.
45newtype NormalizedFilePath = NormalizedFilePath FilePath
46 deriving (Eq, Ord, Show, Hashable, NFData)
48instance IsString NormalizedFilePath where
49 fromString = toNormalizedFilePath
51toNormalizedFilePath :: FilePath -> NormalizedFilePath
52toNormalizedFilePath "" = NormalizedFilePath ""
53toNormalizedFilePath fp = NormalizedFilePath $ normalise' fp
54 where
55 -- We do not use System.FilePath’s normalise here since that
56 -- also normalises things like the case of the drive letter
57 -- which NormalizedUri does not normalise so we get VFS lookup failures.
58 normalise' :: FilePath -> FilePath
59 normalise' = map (\c -> if isPathSeparator c then pathSeparator else c)
61fromNormalizedFilePath :: NormalizedFilePath -> FilePath
62fromNormalizedFilePath (NormalizedFilePath fp) = fp
64-- | We use an empty string as a filepath when we don’t have a file.
65-- However, haskell-lsp doesn’t support that in uriToFilePath and given
66-- that it is not a valid filepath it does not make sense to upstream a fix.
67-- So we have our own wrapper here that supports empty filepaths.
68uriToFilePath' :: Uri -> Maybe FilePath
69uriToFilePath' uri
70 | uri == filePathToUri "" = Just ""
71 | otherwise = LSP.uriToFilePath uri
73filePathToUri' :: NormalizedFilePath -> NormalizedUri
74filePathToUri' = toNormalizedUri . filePathToUri . fromNormalizedFilePath
77fromUri :: LSP.NormalizedUri -> NormalizedFilePath
78fromUri = toNormalizedFilePath . fromMaybe noFilePath . uriToFilePath' . fromNormalizedUri
81noFilePath :: FilePath
82noFilePath = "<unknown>"
84-- A dummy range to use when range is unknown
85noRange :: Range
86noRange = Range (Position 0 0) (Position 100000 0)