{-# LANGUAGE DeriveAnyClass #-}
module Language.PureScript.AST.SourcePos where
import Prelude
import Codec.Serialise (Serialise)
import Control.DeepSeq (NFData)
import Data.Aeson ((.=), (.:))
import Data.Text (Text)
import GHC.Generics (Generic)
import Language.PureScript.Comments (Comment)
import Data.Aeson qualified as A
import Data.Text qualified 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
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
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
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
Ord, 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 -> ()
forall a. (a -> ()) -> NFData a
rnf :: SourcePos -> ()
$crnf :: SourcePos -> ()
NFData, [SourcePos] -> Encoding
SourcePos -> Encoding
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 :: forall s. Decoder s [SourcePos]
$cdecodeList :: forall s. Decoder s [SourcePos]
encodeList :: [SourcePos] -> Encoding
$cencodeList :: [SourcePos] -> Encoding
decode :: forall s. 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 " forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosLine SourcePos
sp)) forall a. Semigroup a => a -> a -> a
<>
Text
", column " forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (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 (forall a. Show a => a -> String
show (SourcePos -> Int
sourcePosLine SourcePos
sp)) forall a. Semigroup a => a -> a -> a
<>
Text
":" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (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
..} =
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] <- forall a. FromJSON a => Value -> Parser a
A.parseJSON Value
arr
forall (m :: * -> *) a. Monad m => a -> m a
return 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
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
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
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
Ord, 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 -> ()
forall a. (a -> ()) -> NFData a
rnf :: SourceSpan -> ()
$crnf :: SourceSpan -> ()
NFData, [SourceSpan] -> Encoding
SourceSpan -> Encoding
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 :: forall s. Decoder s [SourceSpan]
$cdecodeList :: forall s. Decoder s [SourceSpan]
encodeList :: [SourceSpan] -> Encoding
$cencodeList :: [SourceSpan] -> Encoding
decode :: forall s. 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
"(" forall a. Semigroup a => a -> a -> a
<>
SourcePos -> Text
displaySourcePos (SourceSpan -> SourcePos
spanStart SourceSpan
sp) forall a. Semigroup a => a -> a -> a
<> Text
" - " forall a. Semigroup a => a -> a -> a
<>
SourcePos -> Text
displaySourcePos (SourceSpan -> SourcePos
spanEnd SourceSpan
sp) 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) forall a. Semigroup a => a -> a -> a
<> 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)) forall a. Semigroup a => a -> a -> a
<> Text
":" forall a. Semigroup a => a -> a -> a
<>
SourceSpan -> Text
displayStartEndPosShort SourceSpan
sp forall a. Semigroup a => a -> a -> a
<> 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 [ Key
"name" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= String
spanName
, Key
"start" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= SourcePos
spanStart
, Key
"end" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= SourcePos
spanEnd
]
instance A.FromJSON SourceSpan where
parseJSON :: Value -> Parser SourceSpan
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"SourceSpan" forall a b. (a -> b) -> a -> b
$ \Object
o ->
String -> SourcePos -> SourcePos -> SourceSpan
SourceSpan forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name" forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"start" forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"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 -> ((# #) -> r) -> ((# #) -> r) -> r
NullSourceSpan = SourceSpan "" (SourcePos 0 0) (SourcePos 0 0)
pattern NullSourceAnn :: SourceAnn
pattern $bNullSourceAnn :: SourceAnn
$mNullSourceAnn :: forall {r}. SourceAnn -> ((# #) -> r) -> ((# #) -> r) -> r
NullSourceAnn = (NullSourceSpan, [])
nonEmptySpan :: SourceAnn -> Maybe SourceSpan
nonEmptySpan :: SourceAnn -> Maybe SourceSpan
nonEmptySpan (SourceSpan
NullSourceSpan, [Comment]
_) = forall a. Maybe a
Nothing
nonEmptySpan (SourceSpan
ss, [Comment]
_) = 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 (forall a. Ord a => a -> a -> a
min SourcePos
s1 SourcePos
s2) (forall a. Ord a => a -> a -> a
max SourcePos
e1 SourcePos
e2)
where
n :: String
n | String
n1 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, [])