module Language.Haskell.Liquid.GHC.SpanStack
(
Span (..)
, SpanStack
, empty, push
, srcSpan
, showSpan
) where
import Prelude hiding (error)
import SrcLoc
import qualified Var
import CoreSyn hiding (Tick, Var)
import Name (getSrcSpan)
import FastString (fsLit)
import Data.Maybe (listToMaybe, fromMaybe)
import Language.Haskell.Liquid.GHC.Misc (tickSrcSpan, showPpr)
newtype SpanStack = SpanStack { unStack :: [(Span, SrcSpan)] }
empty :: SpanStack
empty = SpanStack []
push :: Span -> SpanStack -> SpanStack
push !s stk
| Just sp <- spanSrcSpan s = SpanStack ((s, sp) : unStack stk)
| otherwise = stk
data Span
= Var !Var.Var
| Tick !(Tickish Var.Var)
instance Show Span where
show (Var x) = show x
show (Tick tt) = showPpr tt
srcSpan :: SpanStack -> SrcSpan
srcSpan s = fromMaybe noSpan (mbSrcSpan s)
where
noSpan = showSpan "Yikes! No source information"
mbSrcSpan :: SpanStack -> Maybe SrcSpan
mbSrcSpan = fmap snd . listToMaybe . unStack
spanSrcSpan :: Span -> Maybe SrcSpan
spanSrcSpan = maybeSpan Nothing . go
where
go (Var x) = getSrcSpan x
go (Tick tt) = tickSrcSpan tt
maybeSpan :: Maybe SrcSpan -> SrcSpan -> Maybe SrcSpan
maybeSpan d sp
| isGoodSrcSpan sp = Just sp
| otherwise = d
showSpan :: (Show a) => a -> SrcSpan
showSpan = mkGeneralSrcSpan . fsLit . show