{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ImplicitParams #-}
module GHC.Stack.Annotation.Experimental (
SomeStackAnnotation(..),
StackAnnotation(..),
ShowAnnotation(..),
StringAnnotation(..),
CallStackAnnotation(..),
annotateStackIO,
annotateStackStringIO,
annotateStackShowIO,
annotateCallStackIO,
annotateStack,
annotateStackString,
annotateStackShow,
annotateCallStack,
) where
import Data.Typeable
import GHC.Exts
import GHC.IO
import GHC.Internal.Stack
import GHC.Internal.Stack.Annotation
data StringAnnotation where
StringAnnotation :: !(Maybe SrcLoc) -> String -> StringAnnotation
instance StackAnnotation StringAnnotation where
displayStackAnnotationShort :: StringAnnotation -> String
displayStackAnnotationShort (StringAnnotation Maybe SrcLoc
_srcLoc String
str) =
String
str
stackAnnotationSourceLocation :: StringAnnotation -> Maybe SrcLoc
stackAnnotationSourceLocation (StringAnnotation Maybe SrcLoc
srcLoc String
_str) =
Maybe SrcLoc
srcLoc
data ShowAnnotation where
ShowAnnotation :: forall a . Show a => !(Maybe SrcLoc) -> a -> ShowAnnotation
instance StackAnnotation ShowAnnotation where
displayStackAnnotationShort :: ShowAnnotation -> String
displayStackAnnotationShort (ShowAnnotation Maybe SrcLoc
_srcLoc a
showAnno) =
a -> String
forall a. Show a => a -> String
show a
showAnno
stackAnnotationSourceLocation :: ShowAnnotation -> Maybe SrcLoc
stackAnnotationSourceLocation (ShowAnnotation Maybe SrcLoc
srcLoc a
_showAnno) =
Maybe SrcLoc
srcLoc
newtype CallStackAnnotation = CallStackAnnotation CallStack
instance Show CallStackAnnotation where
show :: CallStackAnnotation -> String
show (CallStackAnnotation CallStack
cs) = CallStack -> String
prettyCallStack CallStack
cs
instance StackAnnotation CallStackAnnotation where
stackAnnotationSourceLocation :: CallStackAnnotation -> Maybe SrcLoc
stackAnnotationSourceLocation (CallStackAnnotation CallStack
cs) =
CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
cs
displayStackAnnotationShort :: CallStackAnnotation -> String
displayStackAnnotationShort (CallStackAnnotation CallStack
cs) =
CallStack -> String
callStackHeadFunctionName CallStack
cs
callStackHeadSrcLoc :: CallStack -> Maybe SrcLoc
callStackHeadSrcLoc :: CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
cs =
case CallStack -> [(String, SrcLoc)]
getCallStack CallStack
cs of
[] -> Maybe SrcLoc
forall a. Maybe a
Nothing
(String
_, SrcLoc
srcLoc):[(String, SrcLoc)]
_ -> SrcLoc -> Maybe SrcLoc
forall a. a -> Maybe a
Just SrcLoc
srcLoc
callStackHeadFunctionName :: CallStack -> String
callStackHeadFunctionName :: CallStack -> String
callStackHeadFunctionName CallStack
cs =
case CallStack -> [(String, SrcLoc)]
getCallStack CallStack
cs of
[] -> String
"<unknown source location>"
(String
fnName, SrcLoc
_):[(String, SrcLoc)]
_ -> String
fnName
{-# NOINLINE annotateStack #-}
annotateStack :: forall a b. (HasCallStack, Typeable a, StackAnnotation a) => a -> b -> b
annotateStack :: forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> b -> b
annotateStack a
ann b
b = IO b -> b
forall a. IO a -> a
unsafePerformIO (IO b -> b) -> IO b -> b
forall a b. (a -> b) -> a -> b
$
a -> IO b -> IO b
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> IO b -> IO b
annotateStackIO a
ann (b -> IO b
forall a. a -> IO a
evaluate b
b)
{-# NOINLINE annotateCallStack #-}
annotateCallStack :: HasCallStack => b -> b
annotateCallStack :: forall b. HasCallStack => b -> b
annotateCallStack b
b = IO b -> b
forall a. IO a -> a
unsafePerformIO (IO b -> b) -> IO b -> b
forall a b. (a -> b) -> a -> b
$ (HasCallStack => IO b) -> IO b
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => IO b) -> IO b) -> (HasCallStack => IO b) -> IO b
forall a b. (a -> b) -> a -> b
$
IO b -> IO b
forall a. HasCallStack => IO a -> IO a
annotateCallStackIO (b -> IO b
forall a. a -> IO a
evaluate b
b)
annotateStackString :: forall b . HasCallStack => String -> b -> b
annotateStackString :: forall b. HasCallStack => String -> b -> b
annotateStackString String
ann =
StringAnnotation -> b -> b
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> b -> b
annotateStack (Maybe SrcLoc -> String -> StringAnnotation
StringAnnotation (CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
forall (x :: Symbol) a. IP x a => a
?callStack) String
ann)
annotateStackShow :: forall a b . (HasCallStack, Typeable a, Show a) => a -> b -> b
annotateStackShow :: forall a b. (HasCallStack, Typeable a, Show a) => a -> b -> b
annotateStackShow a
ann =
ShowAnnotation -> b -> b
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> b -> b
annotateStack (Maybe SrcLoc -> a -> ShowAnnotation
forall a. Show a => Maybe SrcLoc -> a -> ShowAnnotation
ShowAnnotation (CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
forall (x :: Symbol) a. IP x a => a
?callStack) a
ann)
annotateStackIO :: forall a b . (HasCallStack, Typeable a, StackAnnotation a) => a -> IO b -> IO b
annotateStackIO :: forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> IO b -> IO b
annotateStackIO a
ann (IO State# RealWorld -> (# State# RealWorld, b #)
act) =
(State# RealWorld -> (# State# RealWorld, b #)) -> IO b
(State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, b #)) -> IO b)
-> (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> SomeStackAnnotation
-> (State# RealWorld -> (# State# RealWorld, b #))
-> State# RealWorld
-> (# State# RealWorld, b #)
forall b d a.
b
-> (State# d -> (# State# d, a #)) -> State# d -> (# State# d, a #)
annotateStack# (a -> SomeStackAnnotation
forall a.
(Typeable a, StackAnnotation a) =>
a -> SomeStackAnnotation
SomeStackAnnotation a
ann) State# RealWorld -> (# State# RealWorld, b #)
act State# RealWorld
s
annotateStackStringIO :: forall b . HasCallStack => String -> IO b -> IO b
annotateStackStringIO :: forall b. HasCallStack => String -> IO b -> IO b
annotateStackStringIO String
ann =
StringAnnotation -> IO b -> IO b
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> IO b -> IO b
annotateStackIO (Maybe SrcLoc -> String -> StringAnnotation
StringAnnotation (CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
forall (x :: Symbol) a. IP x a => a
?callStack) String
ann)
annotateStackShowIO :: forall a b . (HasCallStack, Show a) => a -> IO b -> IO b
annotateStackShowIO :: forall a b. (HasCallStack, Show a) => a -> IO b -> IO b
annotateStackShowIO a
ann =
ShowAnnotation -> IO b -> IO b
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> IO b -> IO b
annotateStackIO (Maybe SrcLoc -> a -> ShowAnnotation
forall a. Show a => Maybe SrcLoc -> a -> ShowAnnotation
ShowAnnotation (CallStack -> Maybe SrcLoc
callStackHeadSrcLoc CallStack
forall (x :: Symbol) a. IP x a => a
?callStack) a
ann)
annotateCallStackIO :: HasCallStack => IO a -> IO a
annotateCallStackIO :: forall a. HasCallStack => IO a -> IO a
annotateCallStackIO =
CallStackAnnotation -> IO a -> IO a
forall a b.
(HasCallStack, Typeable a, StackAnnotation a) =>
a -> IO b -> IO b
annotateStackIO (CallStack -> CallStackAnnotation
CallStackAnnotation CallStack
forall (x :: Symbol) a. IP x a => a
?callStack)