{-# LANGUAGE ImplicitParams #-}
module Debug.Provenance.Callback (
Callback
, callback
, invokeCallback
, HasCallStack
) where
import Data.Maybe (fromMaybe)
import GHC.Stack
import Debug.Provenance.Internal
newtype Callback m a b = Wrap (Callback_ CallStack m a b)
callback :: HasCallStack => (HasCallStack => a -> m b) -> Callback m a b
callback :: forall a (m :: * -> *) b.
HasCallStack =>
(HasCallStack => a -> m b) -> Callback m a b
callback HasCallStack => a -> m b
callbackFn = Callback_ CallStack m a b -> Callback m a b
forall (m :: * -> *) a b.
Callback_ CallStack m a b -> Callback m a b
Wrap (CallSite -> (HasCallStack => a -> m b) -> Callback_ CallStack m a b
forall cs (m :: * -> *) a b.
CallSite -> ((?callStack::cs) => a -> m b) -> Callback_ cs m a b
callback_ CallSite
HasCallStack => CallSite
callSite a -> m b
HasCallStack => a -> m b
callbackFn)
invokeCallback :: HasCallStack => Callback m a b -> a -> m b
invokeCallback :: forall (m :: * -> *) a b.
HasCallStack =>
Callback m a b -> a -> m b
invokeCallback (Wrap Callback_ CallStack m a b
cb) a
a =
CallStack -> a -> m b
callbackFunction (CallStack -> CallStack
aux CallStack
HasCallStack => CallStack
callStack) a
a
where
Callback_{CallStack -> a -> m b
callbackFunction :: CallStack -> a -> m b
callbackFunction :: forall cs (m :: * -> *) a b. Callback_ cs m a b -> cs -> a -> m b
callbackFunction, CallSite
callbackDefSite :: CallSite
callbackDefSite :: forall cs (m :: * -> *) a b. Callback_ cs m a b -> CallSite
callbackDefSite} = Callback_ CallStack m a b
cb
aux :: CallStack -> CallStack
aux :: CallStack -> CallStack
aux = ([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> CallStack -> CallStack
mapCallSites (([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> CallStack -> CallStack)
-> ([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> CallStack
-> CallStack
forall a b. (a -> b) -> a -> b
$ \[([Char], SrcLoc)]
cs ->
case [([Char], SrcLoc)]
cs of
([Char]
_, SrcLoc
loc):[([Char], SrcLoc)]
cs' ->
( [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [
[Char]
"invoking callback defined at "
, [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"{unknown}" (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$
CallSite -> Maybe [Char]
callSiteCaller CallSite
callbackDefSite
, [Char] -> (SrcLoc -> [Char]) -> Maybe SrcLoc -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"" (\SrcLoc
l -> [Char]
" (" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ SrcLoc -> [Char]
briefSrcLoc SrcLoc
l [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")") (Maybe SrcLoc -> [Char]) -> Maybe SrcLoc -> [Char]
forall a b. (a -> b) -> a -> b
$
CallSite -> Maybe SrcLoc
callSiteSrcLoc CallSite
callbackDefSite
]
, SrcLoc
loc
)
([Char], SrcLoc) -> [([Char], SrcLoc)] -> [([Char], SrcLoc)]
forall a. a -> [a] -> [a]
: [([Char], SrcLoc)]
cs'
[] ->
[Char] -> [([Char], SrcLoc)]
forall a. HasCallStack => [Char] -> a
error ([Char] -> [([Char], SrcLoc)]) -> [Char] -> [([Char], SrcLoc)]
forall a b. (a -> b) -> a -> b
$ [Char]
"invokeCallback: unexpected CallStack"
{-# NOINLINE callback #-}
{-# NOINLINE invokeCallback #-}
data Callback_ cs m a b = Callback_ {
forall cs (m :: * -> *) a b. Callback_ cs m a b -> cs -> a -> m b
callbackFunction :: !(cs -> a -> m b)
, forall cs (m :: * -> *) a b. Callback_ cs m a b -> CallSite
callbackDefSite :: !CallSite
}
callback_ :: forall cs m a b.
CallSite
-> ((?callStack :: cs) => a -> m b)
-> Callback_ cs m a b
callback_ :: forall cs (m :: * -> *) a b.
CallSite -> ((?callStack::cs) => a -> m b) -> Callback_ cs m a b
callback_ CallSite
defSite (?callStack::cs) => a -> m b
f = (cs -> a -> m b) -> CallSite -> Callback_ cs m a b
forall cs (m :: * -> *) a b.
(cs -> a -> m b) -> CallSite -> Callback_ cs m a b
Callback_ (((?callStack::cs) => a -> m b) -> cs -> a -> m b
forall cs a. ((?callStack::cs) => a) -> cs -> a
mkExplicit a -> m b
(?callStack::cs) => a -> m b
f) CallSite
defSite
mkExplicit :: ((?callStack :: cs) => a) -> (cs -> a)
mkExplicit :: forall cs a. ((?callStack::cs) => a) -> cs -> a
mkExplicit (?callStack::cs) => a
f cs
cs = let ?callStack = cs
?callStack::cs
cs in a
(?callStack::cs) => a
f
{-# NOINLINE callback_ #-}
{-# NOINLINE mkExplicit #-}
mapCallSites ::
([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> CallStack -> CallStack
mapCallSites :: ([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> CallStack -> CallStack
mapCallSites [([Char], SrcLoc)] -> [([Char], SrcLoc)]
f = [([Char], SrcLoc)] -> CallStack
fromCallSiteList ([([Char], SrcLoc)] -> CallStack)
-> (CallStack -> [([Char], SrcLoc)]) -> CallStack -> CallStack
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([Char], SrcLoc)] -> [([Char], SrcLoc)]
f ([([Char], SrcLoc)] -> [([Char], SrcLoc)])
-> (CallStack -> [([Char], SrcLoc)])
-> CallStack
-> [([Char], SrcLoc)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CallStack -> [([Char], SrcLoc)]
getCallStack