{-# LANGUAGE DeriveAnyClass #-}
module Language.PureScript.AST.SourcePos where
import Prelude.Compat
import Codec.Serialise (Serialise)
import Control.DeepSeq (NFData)
import Data.Aeson ((.=), (.:))
import Data.Text (Text)
import GHC.Generics (Generic)
import Language.PureScript.Comments
import qualified Data.Aeson as A
import qualified Data.Text as T
import System.FilePath (makeRelative)
type SourceAnn = (SourceSpan, [Comment])
data SourcePos = SourcePos
{ SourcePos -> Int
sourcePosLine :: Int
, SourcePos -> Int
sourcePosColumn :: Int
} deriving (Int -> SourcePos -> ShowS
[SourcePos] -> ShowS
SourcePos -> String
(Int -> SourcePos -> ShowS)
-> (SourcePos -> String)
-> ([SourcePos] -> ShowS)
-> Show SourcePos
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SourcePos] -> ShowS
$cshowList :: [SourcePos] -> ShowS
show :: SourcePos -> String
$cshow :: SourcePos -> String
showsPrec :: Int -> SourcePos -> ShowS
$cshowsPrec :: Int -> SourcePos -> ShowS
Show, SourcePos -> SourcePos -> Bool
(SourcePos -> SourcePos -> Bool)
-> (SourcePos -> SourcePos -> Bool) -> Eq SourcePos
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SourcePos -> SourcePos -> Bool
$c/= :: SourcePos -> SourcePos -> Bool
== :: SourcePos -> SourcePos -> Bool
$c== :: SourcePos -> SourcePos -> Bool
Eq, Eq SourcePos
Eq SourcePos
-> (SourcePos -> SourcePos -> Ordering)
-> (SourcePos -> SourcePos -> Bool)
-> (SourcePos -> SourcePos -> Bool)
-> (SourcePos -> SourcePos -> Bool)
-> (SourcePos -> SourcePos -> Bool)
-> (SourcePos -> SourcePos -> SourcePos)
-> (SourcePos -> SourcePos -> SourcePos)
-> Ord SourcePos
SourcePos -> SourcePos -> Bool
SourcePos -> SourcePos -> Ordering
SourcePos -> SourcePos -> SourcePos
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SourcePos -> SourcePos -> SourcePos
$cmin :: SourcePos -> SourcePos -> SourcePos
max :: SourcePos -> SourcePos -> SourcePos
$cmax :: SourcePos -> SourcePos -> SourcePos
>= :: SourcePos -> SourcePos -> Bool
$c>= :: SourcePos -> SourcePos -> Bool
> :: SourcePos -> SourcePos -> Bool
$c> :: SourcePos -> SourcePos -> Bool
<= :: SourcePos -> SourcePos -> Bool
$c<= :: SourcePos -> SourcePos -> Bool
< :: SourcePos -> SourcePos -> Bool
$c< :: SourcePos -> SourcePos -> Bool
compare :: SourcePos -> SourcePos -> Ordering
$ccompare :: SourcePos -> SourcePos -> Ordering
$cp1Ord :: Eq SourcePos
Ord, (forall x. SourcePos -> Rep SourcePos x)
-> (forall x. Rep SourcePos x -> SourcePos) -> Generic SourcePos
forall x. Rep SourcePos x -> SourcePos
forall x. SourcePos -> Rep SourcePos x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SourcePos x -> SourcePos
$cfrom :: forall x. SourcePos -> Rep SourcePos x
Generic, SourcePos -> ()
(SourcePos -> ()) -> NFData SourcePos
forall a. (a -> ()) -> NFData a
rnf :: SourcePos -> ()
$crnf :: SourcePos -> ()
NFData, [SourcePos] -> Encoding
SourcePos -> Encoding
(SourcePos -> Encoding)
-> (forall s. Decoder s SourcePos)
-> ([SourcePos] -> Encoding)
-> (forall s. Decoder s [SourcePos])
-> Serialise SourcePos
forall s. Decoder s [SourcePos]
forall s. Decoder s SourcePos
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
decodeList :: Decoder s [SourcePos]
$cdecodeList :: forall s. Decoder s [SourcePos]
encodeList :: [SourcePos] -> Encoding
$cencodeList :: [SourcePos] -> Encoding
decode :: Decoder s SourcePos
$cdecode :: forall s. Decoder s SourcePos
encode :: SourcePos -> Encoding
$cencode :: SourcePos -> Encoding
Serialise)
displaySourcePos :: SourcePos -> Text
displaySourcePos :: SourcePos -> Text
displaySourcePos SourcePos
sp =
Text
"line " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosLine SourcePos
sp)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text
", column " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosColumn SourcePos
sp))
displaySourcePosShort :: SourcePos -> Text
displaySourcePosShort :: SourcePos -> Text
displaySourcePosShort SourcePos
sp =
String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosLine SourcePos
sp)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosColumn SourcePos
sp))
instance A.ToJSON SourcePos where
toJSON :: SourcePos -> Value
toJSON SourcePos{Int
sourcePosColumn :: Int
sourcePosLine :: Int
sourcePosColumn :: SourcePos -> Int
sourcePosLine :: SourcePos -> Int
..} =
[Int] -> Value
forall a. ToJSON a => a -> Value
A.toJSON [Int
sourcePosLine, Int
sourcePosColumn]
instance A.FromJSON SourcePos where
parseJSON :: Value -> Parser SourcePos
parseJSON Value
arr = do
[Int
line, Int
col] <- Value -> Parser [Int]
forall a. FromJSON a => Value -> Parser a
A.parseJSON Value
arr
SourcePos -> Parser SourcePos
forall (m :: * -> *) a. Monad m => a -> m a
return (SourcePos -> Parser SourcePos) -> SourcePos -> Parser SourcePos
forall a b. (a -> b) -> a -> b
$ Int -> Int -> SourcePos
SourcePos Int
line Int
col
data SourceSpan = SourceSpan
{ SourceSpan -> String
spanName :: String
, SourceSpan -> SourcePos
spanStart :: SourcePos
, SourceSpan -> SourcePos
spanEnd :: SourcePos
} deriving (Int -> SourceSpan -> ShowS
[SourceSpan] -> ShowS
SourceSpan -> String
(Int -> SourceSpan -> ShowS)
-> (SourceSpan -> String)
-> ([SourceSpan] -> ShowS)
-> Show SourceSpan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SourceSpan] -> ShowS
$cshowList :: [SourceSpan] -> ShowS
show :: SourceSpan -> String
$cshow :: SourceSpan -> String
showsPrec :: Int -> SourceSpan -> ShowS
$cshowsPrec :: Int -> SourceSpan -> ShowS
Show, SourceSpan -> SourceSpan -> Bool
(SourceSpan -> SourceSpan -> Bool)
-> (SourceSpan -> SourceSpan -> Bool) -> Eq SourceSpan
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SourceSpan -> SourceSpan -> Bool
$c/= :: SourceSpan -> SourceSpan -> Bool
== :: SourceSpan -> SourceSpan -> Bool
$c== :: SourceSpan -> SourceSpan -> Bool
Eq, Eq SourceSpan
Eq SourceSpan
-> (SourceSpan -> SourceSpan -> Ordering)
-> (SourceSpan -> SourceSpan -> Bool)
-> (SourceSpan -> SourceSpan -> Bool)
-> (SourceSpan -> SourceSpan -> Bool)
-> (SourceSpan -> SourceSpan -> Bool)
-> (SourceSpan -> SourceSpan -> SourceSpan)
-> (SourceSpan -> SourceSpan -> SourceSpan)
-> Ord SourceSpan
SourceSpan -> SourceSpan -> Bool
SourceSpan -> SourceSpan -> Ordering
SourceSpan -> SourceSpan -> SourceSpan
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SourceSpan -> SourceSpan -> SourceSpan
$cmin :: SourceSpan -> SourceSpan -> SourceSpan
max :: SourceSpan -> SourceSpan -> SourceSpan
$cmax :: SourceSpan -> SourceSpan -> SourceSpan
>= :: SourceSpan -> SourceSpan -> Bool
$c>= :: SourceSpan -> SourceSpan -> Bool
> :: SourceSpan -> SourceSpan -> Bool
$c> :: SourceSpan -> SourceSpan -> Bool
<= :: SourceSpan -> SourceSpan -> Bool
$c<= :: SourceSpan -> SourceSpan -> Bool
< :: SourceSpan -> SourceSpan -> Bool
$c< :: SourceSpan -> SourceSpan -> Bool
compare :: SourceSpan -> SourceSpan -> Ordering
$ccompare :: SourceSpan -> SourceSpan -> Ordering
$cp1Ord :: Eq SourceSpan
Ord, (forall x. SourceSpan -> Rep SourceSpan x)
-> (forall x. Rep SourceSpan x -> SourceSpan) -> Generic SourceSpan
forall x. Rep SourceSpan x -> SourceSpan
forall x. SourceSpan -> Rep SourceSpan x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SourceSpan x -> SourceSpan
$cfrom :: forall x. SourceSpan -> Rep SourceSpan x
Generic, SourceSpan -> ()
(SourceSpan -> ()) -> NFData SourceSpan
forall a. (a -> ()) -> NFData a
rnf :: SourceSpan -> ()
$crnf :: SourceSpan -> ()
NFData, [SourceSpan] -> Encoding
SourceSpan -> Encoding
(SourceSpan -> Encoding)
-> (forall s. Decoder s SourceSpan)
-> ([SourceSpan] -> Encoding)
-> (forall s. Decoder s [SourceSpan])
-> Serialise SourceSpan
forall s. Decoder s [SourceSpan]
forall s. Decoder s SourceSpan
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
decodeList :: Decoder s [SourceSpan]
$cdecodeList :: forall s. Decoder s [SourceSpan]
encodeList :: [SourceSpan] -> Encoding
$cencodeList :: [SourceSpan] -> Encoding
decode :: Decoder s SourceSpan
$cdecode :: forall s. Decoder s SourceSpan
encode :: SourceSpan -> Encoding
$cencode :: SourceSpan -> Encoding
Serialise)
displayStartEndPos :: SourceSpan -> Text
displayStartEndPos :: SourceSpan -> Text
displayStartEndPos SourceSpan
sp =
Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
SourcePos -> Text
displaySourcePos (SourceSpan -> SourcePos
spanStart SourceSpan
sp) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
SourcePos -> Text
displaySourcePos (SourceSpan -> SourcePos
spanEnd SourceSpan
sp) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
displayStartEndPosShort :: SourceSpan -> Text
displayStartEndPosShort :: SourceSpan -> Text
displayStartEndPosShort SourceSpan
sp =
SourcePos -> Text
displaySourcePosShort (SourceSpan -> SourcePos
spanStart SourceSpan
sp) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
SourcePos -> Text
displaySourcePosShort (SourceSpan -> SourcePos
spanEnd SourceSpan
sp)
displaySourceSpan :: FilePath -> SourceSpan -> Text
displaySourceSpan :: String -> SourceSpan -> Text
displaySourceSpan String
relPath SourceSpan
sp =
String -> Text
T.pack (String -> ShowS
makeRelative String
relPath (SourceSpan -> String
spanName SourceSpan
sp)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
SourceSpan -> Text
displayStartEndPosShort SourceSpan
sp Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
SourceSpan -> Text
displayStartEndPos SourceSpan
sp
instance A.ToJSON SourceSpan where
toJSON :: SourceSpan -> Value
toJSON SourceSpan{String
SourcePos
spanEnd :: SourcePos
spanStart :: SourcePos
spanName :: String
spanEnd :: SourceSpan -> SourcePos
spanStart :: SourceSpan -> SourcePos
spanName :: SourceSpan -> String
..} =
[Pair] -> Value
A.object [ Text
"name" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
spanName
, Text
"start" Text -> SourcePos -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SourcePos
spanStart
, Text
"end" Text -> SourcePos -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SourcePos
spanEnd
]
instance A.FromJSON SourceSpan where
parseJSON :: Value -> Parser SourceSpan
parseJSON = String
-> (Object -> Parser SourceSpan) -> Value -> Parser SourceSpan
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"SourceSpan" ((Object -> Parser SourceSpan) -> Value -> Parser SourceSpan)
-> (Object -> Parser SourceSpan) -> Value -> Parser SourceSpan
forall a b. (a -> b) -> a -> b
$ \Object
o ->
String -> SourcePos -> SourcePos -> SourceSpan
SourceSpan (String -> SourcePos -> SourcePos -> SourceSpan)
-> Parser String -> Parser (SourcePos -> SourcePos -> SourceSpan)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"name" Parser (SourcePos -> SourcePos -> SourceSpan)
-> Parser SourcePos -> Parser (SourcePos -> SourceSpan)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
Object
o Object -> Text -> Parser SourcePos
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"start" Parser (SourcePos -> SourceSpan)
-> Parser SourcePos -> Parser SourceSpan
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
Object
o Object -> Text -> Parser SourcePos
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"end"
internalModuleSourceSpan :: String -> SourceSpan
internalModuleSourceSpan :: String -> SourceSpan
internalModuleSourceSpan String
name = String -> SourcePos -> SourcePos -> SourceSpan
SourceSpan String
name (Int -> Int -> SourcePos
SourcePos Int
0 Int
0) (Int -> Int -> SourcePos
SourcePos Int
0 Int
0)
nullSourceSpan :: SourceSpan
nullSourceSpan :: SourceSpan
nullSourceSpan = String -> SourceSpan
internalModuleSourceSpan String
""
nullSourceAnn :: SourceAnn
nullSourceAnn :: SourceAnn
nullSourceAnn = (SourceSpan
nullSourceSpan, [])
pattern NullSourceSpan :: SourceSpan
pattern $bNullSourceSpan :: SourceSpan
$mNullSourceSpan :: forall r. SourceSpan -> (Void# -> r) -> (Void# -> r) -> r
NullSourceSpan = SourceSpan "" (SourcePos 0 0) (SourcePos 0 0)
pattern NullSourceAnn :: SourceAnn
pattern $bNullSourceAnn :: SourceAnn
$mNullSourceAnn :: forall r. SourceAnn -> (Void# -> r) -> (Void# -> r) -> r
NullSourceAnn = (NullSourceSpan, [])
nonEmptySpan :: SourceAnn -> Maybe SourceSpan
nonEmptySpan :: SourceAnn -> Maybe SourceSpan
nonEmptySpan (SourceSpan
NullSourceSpan, [Comment]
_) = Maybe SourceSpan
forall a. Maybe a
Nothing
nonEmptySpan (SourceSpan
ss, [Comment]
_) = SourceSpan -> Maybe SourceSpan
forall a. a -> Maybe a
Just SourceSpan
ss
widenSourceSpan :: SourceSpan -> SourceSpan -> SourceSpan
widenSourceSpan :: SourceSpan -> SourceSpan -> SourceSpan
widenSourceSpan SourceSpan
NullSourceSpan SourceSpan
b = SourceSpan
b
widenSourceSpan SourceSpan
a SourceSpan
NullSourceSpan = SourceSpan
a
widenSourceSpan (SourceSpan String
n1 SourcePos
s1 SourcePos
e1) (SourceSpan String
n2 SourcePos
s2 SourcePos
e2) =
String -> SourcePos -> SourcePos -> SourceSpan
SourceSpan String
n (SourcePos -> SourcePos -> SourcePos
forall a. Ord a => a -> a -> a
min SourcePos
s1 SourcePos
s2) (SourcePos -> SourcePos -> SourcePos
forall a. Ord a => a -> a -> a
max SourcePos
e1 SourcePos
e2)
where
n :: String
n | String
n1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" = String
n2
| Bool
otherwise = String
n1
widenSourceAnn :: SourceAnn -> SourceAnn -> SourceAnn
widenSourceAnn :: SourceAnn -> SourceAnn -> SourceAnn
widenSourceAnn (SourceSpan
s1, [Comment]
_) (SourceSpan
s2, [Comment]
_) = (SourceSpan -> SourceSpan -> SourceSpan
widenSourceSpan SourceSpan
s1 SourceSpan
s2, [])