{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types #-}

#if MIN_VERSION_base(4,8,1)
#define HAS_SOURCE_LOCATIONS
{-# LANGUAGE ImplicitParams #-}
#endif

module Data.WithLocation where

#ifdef HAS_SOURCE_LOCATIONS
#if !(MIN_VERSION_base(4,9,0))
import           GHC.SrcLoc
#endif
import           GHC.Stack
#endif

#ifdef HAS_SOURCE_LOCATIONS
type WithLocation a = (?loc :: CallStack) => a
#else
type WithLocation a = a
#endif

data Location = Location {
  Location -> String
locationPackage :: String
, Location -> String
locationModule :: String
, Location -> String
locationFile :: FilePath
, Location -> Int
locationLine :: Int
, Location -> Int
locationColumn :: Int
} deriving (Location -> Location -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Location -> Location -> Bool
$c/= :: Location -> Location -> Bool
== :: Location -> Location -> Bool
$c== :: Location -> Location -> Bool
Eq, Eq Location
Location -> Location -> Bool
Location -> Location -> Ordering
Location -> Location -> Location
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 :: Location -> Location -> Location
$cmin :: Location -> Location -> Location
max :: Location -> Location -> Location
$cmax :: Location -> Location -> Location
>= :: Location -> Location -> Bool
$c>= :: Location -> Location -> Bool
> :: Location -> Location -> Bool
$c> :: Location -> Location -> Bool
<= :: Location -> Location -> Bool
$c<= :: Location -> Location -> Bool
< :: Location -> Location -> Bool
$c< :: Location -> Location -> Bool
compare :: Location -> Location -> Ordering
$ccompare :: Location -> Location -> Ordering
Ord, Int -> Location -> ShowS
[Location] -> ShowS
Location -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Location] -> ShowS
$cshowList :: [Location] -> ShowS
show :: Location -> String
$cshow :: Location -> String
showsPrec :: Int -> Location -> ShowS
$cshowsPrec :: Int -> Location -> ShowS
Show)

location :: WithLocation (Maybe Location)
#ifdef HAS_SOURCE_LOCATIONS
location :: WithLocation (Maybe Location)
location = case forall a. [a] -> [a]
reverse (CallStack -> [(String, SrcLoc)]
getCallStack ?loc::CallStack
?loc) of
  (String
_, SrcLoc
loc) : [(String, SrcLoc)]
_ -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ String -> String -> String -> Int -> Int -> Location
Location (SrcLoc -> String
srcLocPackage SrcLoc
loc) (SrcLoc -> String
srcLocModule SrcLoc
loc) (SrcLoc -> String
srcLocFile SrcLoc
loc) (SrcLoc -> Int
srcLocStartLine SrcLoc
loc) (SrcLoc -> Int
srcLocStartCol SrcLoc
loc)
  [] -> forall a. Maybe a
Nothing
#else
location = Nothing
#endif