module Outputable (
Outputable(..), OutputableBndr(..),
SDoc, runSDoc, initSDocContext,
docToSDoc, sdocWithPprDebug,
interppSP, interpp'SP,
pprQuotedList, pprWithCommas, quotedListWithOr, quotedListWithNor,
pprWithBars,
empty, isEmpty, nest,
char,
text, ftext, ptext, ztext,
int, intWithCommas, integer, float, double, rational, doublePrec,
parens, cparen, brackets, braces, quotes, quote,
doubleQuotes, angleBrackets, paBrackets,
semi, comma, colon, dcolon, space, equals, dot, vbar,
arrow, larrow, darrow, arrowt, larrowt, arrowtt, larrowtt,
lparen, rparen, lbrack, rbrack, lbrace, rbrace, underscore,
blankLine, forAllLit, kindStar, bullet,
(<>), (<+>), hcat, hsep,
($$), ($+$), vcat,
sep, cat,
fsep, fcat,
hang, hangNotEmpty, punctuate, ppWhen, ppUnless,
speakNth, speakN, speakNOf, plural, isOrAre, doOrDoes,
unicodeSyntax,
coloured, keyword,
printSDoc, printSDocLn, printForUser, printForUserPartWay,
printForC, bufLeftRenderSDoc,
pprCode, mkCodeStyle,
showSDoc, showSDocUnsafe, showSDocOneLine,
showSDocForUser, showSDocDebug, showSDocDump, showSDocDumpOneLine,
showSDocUnqual, showPpr,
renderWithStyle,
pprInfixVar, pprPrefixVar,
pprHsChar, pprHsString, pprHsBytes,
primFloatSuffix, primCharSuffix, primWordSuffix, primDoubleSuffix,
primInt64Suffix, primWord64Suffix, primIntSuffix,
pprPrimChar, pprPrimInt, pprPrimWord, pprPrimInt64, pprPrimWord64,
pprFastFilePath,
BindingSite(..),
PprStyle, CodeStyle(..), PrintUnqualified(..),
QueryQualifyName, QueryQualifyModule, QueryQualifyPackage,
reallyAlwaysQualify, reallyAlwaysQualifyNames,
alwaysQualify, alwaysQualifyNames, alwaysQualifyModules,
neverQualify, neverQualifyNames, neverQualifyModules,
alwaysQualifyPackages, neverQualifyPackages,
QualifyName(..), queryQual,
sdocWithDynFlags, sdocWithPlatform,
getPprStyle, withPprStyle, withPprStyleDoc, setStyleColoured,
pprDeeper, pprDeeperList, pprSetDepth,
codeStyle, userStyle, debugStyle, dumpStyle, asmStyle,
ifPprDebug, qualName, qualModule, qualPackage,
mkErrStyle, defaultErrStyle, defaultDumpStyle, mkDumpStyle, defaultUserStyle,
mkUserStyle, cmdlineParserStyle, Depth(..),
pprPanic, pprSorry, assertPprPanic, pprPgmError,
pprTrace, pprTraceDebug, pprTraceIt, warnPprTrace, pprSTrace,
trace, pgmError, panic, sorry, assertPanic,
pprDebugAndThen, callStackDoc
) where
import DynFlags( DynFlags, hasPprDebug, hasNoDebugOutput,
targetPlatform, pprUserLength, pprCols,
useUnicode, useUnicodeSyntax,
shouldUseColor, unsafeGlobalDynFlags )
import Module( UnitId, Module, ModuleName, moduleName )
import OccName( OccName )
import BufWrite (BufHandle)
import FastString
import qualified Pretty
import Util
import Platform
import qualified PprColour as Col
import Pretty ( Doc, Mode(..) )
import Panic
import GHC.Serialized
import GHC.LanguageExtensions (Extension)
import Control.Exception (finally)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Char
import qualified Data.Map as M
import Data.Int
import qualified Data.IntMap as IM
import Data.Set (Set)
import qualified Data.Set as Set
import Data.String
import Data.Word
import System.IO ( Handle )
import System.FilePath
import Text.Printf
import Numeric (showFFloat)
import Data.Graph (SCC(..))
import Data.List (intersperse)
import GHC.Fingerprint
import GHC.Show ( showMultiLineString )
data PprStyle
= PprUser PrintUnqualified Depth Coloured
| PprDump PrintUnqualified
| PprDebug
| PprCode CodeStyle
data CodeStyle = CStyle
| AsmStyle
data Depth = AllTheWay
| PartWay Int
data Coloured
= Uncoloured
| Coloured
data PrintUnqualified = QueryQualify {
queryQualifyName :: QueryQualifyName,
queryQualifyModule :: QueryQualifyModule,
queryQualifyPackage :: QueryQualifyPackage
}
type QueryQualifyName = Module -> OccName -> QualifyName
type QueryQualifyModule = Module -> Bool
type QueryQualifyPackage = UnitId -> Bool
data QualifyName
= NameUnqual
| NameQual ModuleName
| NameNotInScope1
| NameNotInScope2
instance Outputable QualifyName where
ppr NameUnqual = text "NameUnqual"
ppr (NameQual _mod) = text "NameQual"
ppr NameNotInScope1 = text "NameNotInScope1"
ppr NameNotInScope2 = text "NameNotInScope2"
reallyAlwaysQualifyNames :: QueryQualifyName
reallyAlwaysQualifyNames _ _ = NameNotInScope2
alwaysQualifyNames :: QueryQualifyName
alwaysQualifyNames m _ = NameQual (moduleName m)
neverQualifyNames :: QueryQualifyName
neverQualifyNames _ _ = NameUnqual
alwaysQualifyModules :: QueryQualifyModule
alwaysQualifyModules _ = True
neverQualifyModules :: QueryQualifyModule
neverQualifyModules _ = False
alwaysQualifyPackages :: QueryQualifyPackage
alwaysQualifyPackages _ = True
neverQualifyPackages :: QueryQualifyPackage
neverQualifyPackages _ = False
reallyAlwaysQualify, alwaysQualify, neverQualify :: PrintUnqualified
reallyAlwaysQualify
= QueryQualify reallyAlwaysQualifyNames
alwaysQualifyModules
alwaysQualifyPackages
alwaysQualify = QueryQualify alwaysQualifyNames
alwaysQualifyModules
alwaysQualifyPackages
neverQualify = QueryQualify neverQualifyNames
neverQualifyModules
neverQualifyPackages
defaultUserStyle :: DynFlags -> PprStyle
defaultUserStyle dflags = mkUserStyle dflags neverQualify AllTheWay
defaultDumpStyle :: DynFlags -> PprStyle
defaultDumpStyle dflags
| hasPprDebug dflags = PprDebug
| otherwise = PprDump neverQualify
mkDumpStyle :: DynFlags -> PrintUnqualified -> PprStyle
mkDumpStyle dflags print_unqual
| hasPprDebug dflags = PprDebug
| otherwise = PprDump print_unqual
defaultErrStyle :: DynFlags -> PprStyle
defaultErrStyle dflags = mkErrStyle dflags neverQualify
mkErrStyle :: DynFlags -> PrintUnqualified -> PprStyle
mkErrStyle dflags qual =
mkUserStyle dflags qual (PartWay (pprUserLength dflags))
cmdlineParserStyle :: DynFlags -> PprStyle
cmdlineParserStyle dflags = mkUserStyle dflags alwaysQualify AllTheWay
mkUserStyle :: DynFlags -> PrintUnqualified -> Depth -> PprStyle
mkUserStyle dflags unqual depth
| hasPprDebug dflags = PprDebug
| otherwise = PprUser unqual depth Uncoloured
setStyleColoured :: Bool -> PprStyle -> PprStyle
setStyleColoured col style =
case style of
PprUser q d _ -> PprUser q d c
_ -> style
where
c | col = Coloured
| otherwise = Uncoloured
instance Outputable PprStyle where
ppr (PprUser {}) = text "user-style"
ppr (PprCode {}) = text "code-style"
ppr (PprDump {}) = text "dump-style"
ppr (PprDebug {}) = text "debug-style"
newtype SDoc = SDoc { runSDoc :: SDocContext -> Doc }
data SDocContext = SDC
{ sdocStyle :: !PprStyle
, sdocLastColour :: !Col.PprColour
, sdocDynFlags :: !DynFlags
}
instance IsString SDoc where
fromString = text
initSDocContext :: DynFlags -> PprStyle -> SDocContext
initSDocContext dflags sty = SDC
{ sdocStyle = sty
, sdocLastColour = Col.colReset
, sdocDynFlags = dflags
}
withPprStyle :: PprStyle -> SDoc -> SDoc
withPprStyle sty d = SDoc $ \ctxt -> runSDoc d ctxt{sdocStyle=sty}
withPprStyleDoc :: DynFlags -> PprStyle -> SDoc -> Doc
withPprStyleDoc dflags sty d = runSDoc d (initSDocContext dflags sty)
sdocWithPprDebug :: (Bool -> SDoc) -> SDoc
sdocWithPprDebug f = sdocWithDynFlags $ \dflags -> f (hasPprDebug dflags)
pprDeeper :: SDoc -> SDoc
pprDeeper d = SDoc $ \ctx -> case ctx of
SDC{sdocStyle=PprUser _ (PartWay 0) _} -> Pretty.text "..."
SDC{sdocStyle=PprUser q (PartWay n) c} ->
runSDoc d ctx{sdocStyle = PprUser q (PartWay (n1)) c}
_ -> runSDoc d ctx
pprDeeperList :: ([SDoc] -> SDoc) -> [SDoc] -> SDoc
pprDeeperList f ds
| null ds = f []
| otherwise = SDoc work
where
work ctx@SDC{sdocStyle=PprUser q (PartWay n) c}
| n==0 = Pretty.text "..."
| otherwise =
runSDoc (f (go 0 ds)) ctx{sdocStyle = PprUser q (PartWay (n1)) c}
where
go _ [] = []
go i (d:ds) | i >= n = [text "...."]
| otherwise = d : go (i+1) ds
work other_ctx = runSDoc (f ds) other_ctx
pprSetDepth :: Depth -> SDoc -> SDoc
pprSetDepth depth doc = SDoc $ \ctx ->
case ctx of
SDC{sdocStyle=PprUser q _ c} ->
runSDoc doc ctx{sdocStyle = PprUser q depth c}
_ ->
runSDoc doc ctx
getPprStyle :: (PprStyle -> SDoc) -> SDoc
getPprStyle df = SDoc $ \ctx -> runSDoc (df (sdocStyle ctx)) ctx
sdocWithDynFlags :: (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags f = SDoc $ \ctx -> runSDoc (f (sdocDynFlags ctx)) ctx
sdocWithPlatform :: (Platform -> SDoc) -> SDoc
sdocWithPlatform f = sdocWithDynFlags (f . targetPlatform)
qualName :: PprStyle -> QueryQualifyName
qualName (PprUser q _ _) mod occ = queryQualifyName q mod occ
qualName (PprDump q) mod occ = queryQualifyName q mod occ
qualName _other mod _ = NameQual (moduleName mod)
qualModule :: PprStyle -> QueryQualifyModule
qualModule (PprUser q _ _) m = queryQualifyModule q m
qualModule (PprDump q) m = queryQualifyModule q m
qualModule _other _m = True
qualPackage :: PprStyle -> QueryQualifyPackage
qualPackage (PprUser q _ _) m = queryQualifyPackage q m
qualPackage (PprDump q) m = queryQualifyPackage q m
qualPackage _other _m = True
queryQual :: PprStyle -> PrintUnqualified
queryQual s = QueryQualify (qualName s)
(qualModule s)
(qualPackage s)
codeStyle :: PprStyle -> Bool
codeStyle (PprCode _) = True
codeStyle _ = False
asmStyle :: PprStyle -> Bool
asmStyle (PprCode AsmStyle) = True
asmStyle _other = False
dumpStyle :: PprStyle -> Bool
dumpStyle (PprDump {}) = True
dumpStyle _other = False
debugStyle :: PprStyle -> Bool
debugStyle PprDebug = True
debugStyle _other = False
userStyle :: PprStyle -> Bool
userStyle (PprUser {}) = True
userStyle _other = False
ifPprDebug :: SDoc -> SDoc
ifPprDebug d = SDoc $ \ctx ->
case ctx of
SDC{sdocStyle=PprDebug} -> runSDoc d ctx
_ -> Pretty.empty
printSDoc :: Mode -> DynFlags -> Handle -> PprStyle -> SDoc -> IO ()
printSDoc mode dflags handle sty doc =
Pretty.printDoc_ mode cols handle (runSDoc doc ctx)
`finally`
Pretty.printDoc_ mode cols handle
(runSDoc (coloured Col.colReset empty) ctx)
where
cols = pprCols dflags
ctx = initSDocContext dflags sty
printSDocLn :: Mode -> DynFlags -> Handle -> PprStyle -> SDoc -> IO ()
printSDocLn mode dflags handle sty doc =
printSDoc mode dflags handle sty (doc $$ text "")
printForUser :: DynFlags -> Handle -> PrintUnqualified -> SDoc -> IO ()
printForUser dflags handle unqual doc
= printSDocLn PageMode dflags handle
(mkUserStyle dflags unqual AllTheWay) doc
printForUserPartWay :: DynFlags -> Handle -> Int -> PrintUnqualified -> SDoc
-> IO ()
printForUserPartWay dflags handle d unqual doc
= printSDocLn PageMode dflags handle
(mkUserStyle dflags unqual (PartWay d)) doc
printForC :: DynFlags -> Handle -> SDoc -> IO ()
printForC dflags handle doc =
printSDocLn LeftMode dflags handle (PprCode CStyle) doc
bufLeftRenderSDoc :: DynFlags -> BufHandle -> PprStyle -> SDoc -> IO ()
bufLeftRenderSDoc dflags bufHandle sty doc =
Pretty.bufLeftRender bufHandle (runSDoc doc (initSDocContext dflags sty))
pprCode :: CodeStyle -> SDoc -> SDoc
pprCode cs d = withPprStyle (PprCode cs) d
mkCodeStyle :: CodeStyle -> PprStyle
mkCodeStyle = PprCode
showSDoc :: DynFlags -> SDoc -> String
showSDoc dflags sdoc = renderWithStyle dflags sdoc (defaultUserStyle dflags)
showSDocUnsafe :: SDoc -> String
showSDocUnsafe sdoc = showSDoc unsafeGlobalDynFlags sdoc
showPpr :: Outputable a => DynFlags -> a -> String
showPpr dflags thing = showSDoc dflags (ppr thing)
showSDocUnqual :: DynFlags -> SDoc -> String
showSDocUnqual dflags sdoc = showSDoc dflags sdoc
showSDocForUser :: DynFlags -> PrintUnqualified -> SDoc -> String
showSDocForUser dflags unqual doc
= renderWithStyle dflags doc (mkUserStyle dflags unqual AllTheWay)
showSDocDump :: DynFlags -> SDoc -> String
showSDocDump dflags d = renderWithStyle dflags d (defaultDumpStyle dflags)
showSDocDebug :: DynFlags -> SDoc -> String
showSDocDebug dflags d = renderWithStyle dflags d PprDebug
renderWithStyle :: DynFlags -> SDoc -> PprStyle -> String
renderWithStyle dflags sdoc sty
= let s = Pretty.style{ Pretty.mode = PageMode,
Pretty.lineLength = pprCols dflags }
in Pretty.renderStyle s $ runSDoc sdoc (initSDocContext dflags sty)
showSDocOneLine :: DynFlags -> SDoc -> String
showSDocOneLine dflags d
= let s = Pretty.style{ Pretty.mode = OneLineMode,
Pretty.lineLength = pprCols dflags } in
Pretty.renderStyle s $
runSDoc d (initSDocContext dflags (defaultUserStyle dflags))
showSDocDumpOneLine :: DynFlags -> SDoc -> String
showSDocDumpOneLine dflags d
= let s = Pretty.style{ Pretty.mode = OneLineMode,
Pretty.lineLength = irrelevantNCols } in
Pretty.renderStyle s $
runSDoc d (initSDocContext dflags (defaultDumpStyle dflags))
irrelevantNCols :: Int
irrelevantNCols = 1
isEmpty :: DynFlags -> SDoc -> Bool
isEmpty dflags sdoc = Pretty.isEmpty $ runSDoc sdoc dummySDocContext
where dummySDocContext = initSDocContext dflags PprDebug
docToSDoc :: Doc -> SDoc
docToSDoc d = SDoc (\_ -> d)
empty :: SDoc
char :: Char -> SDoc
text :: String -> SDoc
ftext :: FastString -> SDoc
ptext :: LitString -> SDoc
ztext :: FastZString -> SDoc
int :: Int -> SDoc
integer :: Integer -> SDoc
float :: Float -> SDoc
double :: Double -> SDoc
rational :: Rational -> SDoc
empty = docToSDoc $ Pretty.empty
char c = docToSDoc $ Pretty.char c
text s = docToSDoc $ Pretty.text s
ftext s = docToSDoc $ Pretty.ftext s
ptext s = docToSDoc $ Pretty.ptext s
ztext s = docToSDoc $ Pretty.ztext s
int n = docToSDoc $ Pretty.int n
integer n = docToSDoc $ Pretty.integer n
float n = docToSDoc $ Pretty.float n
double n = docToSDoc $ Pretty.double n
rational n = docToSDoc $ Pretty.rational n
doublePrec :: Int -> Double -> SDoc
doublePrec p n = text (showFFloat (Just p) n "")
parens, braces, brackets, quotes, quote,
paBrackets, doubleQuotes, angleBrackets :: SDoc -> SDoc
parens d = SDoc $ Pretty.parens . runSDoc d
braces d = SDoc $ Pretty.braces . runSDoc d
brackets d = SDoc $ Pretty.brackets . runSDoc d
quote d = SDoc $ Pretty.quote . runSDoc d
doubleQuotes d = SDoc $ Pretty.doubleQuotes . runSDoc d
angleBrackets d = char '<' <> d <> char '>'
paBrackets d = text "[:" <> d <> text ":]"
cparen :: Bool -> SDoc -> SDoc
cparen b d = SDoc $ Pretty.maybeParens b . runSDoc d
quotes d =
sdocWithDynFlags $ \dflags ->
if useUnicode dflags
then char '‘' <> d <> char '’'
else SDoc $ \sty ->
let pp_d = runSDoc d sty
str = show pp_d
in case (str, snocView str) of
(_, Just (_, '\'')) -> pp_d
('\'' : _, _) -> pp_d
_other -> Pretty.quotes pp_d
semi, comma, colon, equals, space, dcolon, underscore, dot, vbar :: SDoc
arrow, larrow, darrow, arrowt, larrowt, arrowtt, larrowtt :: SDoc
lparen, rparen, lbrack, rbrack, lbrace, rbrace, blankLine :: SDoc
blankLine = docToSDoc $ Pretty.text ""
dcolon = unicodeSyntax (char '∷') (docToSDoc $ Pretty.text "::")
arrow = unicodeSyntax (char '→') (docToSDoc $ Pretty.text "->")
larrow = unicodeSyntax (char '←') (docToSDoc $ Pretty.text "<-")
darrow = unicodeSyntax (char '⇒') (docToSDoc $ Pretty.text "=>")
arrowt = unicodeSyntax (char '⤚') (docToSDoc $ Pretty.text ">-")
larrowt = unicodeSyntax (char '⤙') (docToSDoc $ Pretty.text "-<")
arrowtt = unicodeSyntax (char '⤜') (docToSDoc $ Pretty.text ">>-")
larrowtt = unicodeSyntax (char '⤛') (docToSDoc $ Pretty.text "-<<")
semi = docToSDoc $ Pretty.semi
comma = docToSDoc $ Pretty.comma
colon = docToSDoc $ Pretty.colon
equals = docToSDoc $ Pretty.equals
space = docToSDoc $ Pretty.space
underscore = char '_'
dot = char '.'
vbar = char '|'
lparen = docToSDoc $ Pretty.lparen
rparen = docToSDoc $ Pretty.rparen
lbrack = docToSDoc $ Pretty.lbrack
rbrack = docToSDoc $ Pretty.rbrack
lbrace = docToSDoc $ Pretty.lbrace
rbrace = docToSDoc $ Pretty.rbrace
forAllLit :: SDoc
forAllLit = unicodeSyntax (char '∀') (text "forall")
kindStar :: SDoc
kindStar = unicodeSyntax (char '★') (char '*')
bullet :: SDoc
bullet = unicode (char '•') (char '*')
unicodeSyntax :: SDoc -> SDoc -> SDoc
unicodeSyntax unicode plain = sdocWithDynFlags $ \dflags ->
if useUnicode dflags && useUnicodeSyntax dflags
then unicode
else plain
unicode :: SDoc -> SDoc -> SDoc
unicode unicode plain = sdocWithDynFlags $ \dflags ->
if useUnicode dflags
then unicode
else plain
nest :: Int -> SDoc -> SDoc
(<>) :: SDoc -> SDoc -> SDoc
(<+>) :: SDoc -> SDoc -> SDoc
($$) :: SDoc -> SDoc -> SDoc
($+$) :: SDoc -> SDoc -> SDoc
nest n d = SDoc $ Pretty.nest n . runSDoc d
(<>) d1 d2 = SDoc $ \sty -> (Pretty.<>) (runSDoc d1 sty) (runSDoc d2 sty)
(<+>) d1 d2 = SDoc $ \sty -> (Pretty.<+>) (runSDoc d1 sty) (runSDoc d2 sty)
($$) d1 d2 = SDoc $ \sty -> (Pretty.$$) (runSDoc d1 sty) (runSDoc d2 sty)
($+$) d1 d2 = SDoc $ \sty -> (Pretty.$+$) (runSDoc d1 sty) (runSDoc d2 sty)
hcat :: [SDoc] -> SDoc
hsep :: [SDoc] -> SDoc
vcat :: [SDoc] -> SDoc
sep :: [SDoc] -> SDoc
cat :: [SDoc] -> SDoc
fsep :: [SDoc] -> SDoc
fcat :: [SDoc] -> SDoc
hcat ds = SDoc $ \sty -> Pretty.hcat [runSDoc d sty | d <- ds]
hsep ds = SDoc $ \sty -> Pretty.hsep [runSDoc d sty | d <- ds]
vcat ds = SDoc $ \sty -> Pretty.vcat [runSDoc d sty | d <- ds]
sep ds = SDoc $ \sty -> Pretty.sep [runSDoc d sty | d <- ds]
cat ds = SDoc $ \sty -> Pretty.cat [runSDoc d sty | d <- ds]
fsep ds = SDoc $ \sty -> Pretty.fsep [runSDoc d sty | d <- ds]
fcat ds = SDoc $ \sty -> Pretty.fcat [runSDoc d sty | d <- ds]
hang :: SDoc
-> Int
-> SDoc
-> SDoc
hang d1 n d2 = SDoc $ \sty -> Pretty.hang (runSDoc d1 sty) n (runSDoc d2 sty)
hangNotEmpty :: SDoc -> Int -> SDoc -> SDoc
hangNotEmpty d1 n d2 =
SDoc $ \sty -> Pretty.hangNotEmpty (runSDoc d1 sty) n (runSDoc d2 sty)
punctuate :: SDoc
-> [SDoc]
-> [SDoc]
punctuate _ [] = []
punctuate p (d:ds) = go d ds
where
go d [] = [d]
go d (e:es) = (d <> p) : go e es
ppWhen, ppUnless :: Bool -> SDoc -> SDoc
ppWhen True doc = doc
ppWhen False _ = empty
ppUnless True _ = empty
ppUnless False doc = doc
coloured :: Col.PprColour -> SDoc -> SDoc
coloured col@(Col.PprColour c) sdoc =
sdocWithDynFlags $ \dflags ->
if shouldUseColor dflags
then SDoc $ \ctx@SDC{ sdocLastColour = Col.PprColour lc } ->
case ctx of
SDC{ sdocStyle = PprUser _ _ Coloured } ->
let ctx' = ctx{ sdocLastColour = col } in
Pretty.zeroWidthText (cReset ++ c)
Pretty.<> runSDoc sdoc ctx'
Pretty.<> Pretty.zeroWidthText (cReset ++ lc)
_ -> runSDoc sdoc ctx
else sdoc
where Col.PprColour cReset = Col.colReset
keyword :: SDoc -> SDoc
keyword = coloured Col.colBold
class Outputable a where
ppr :: a -> SDoc
pprPrec :: Rational -> a -> SDoc
ppr = pprPrec 0
pprPrec _ = ppr
instance Outputable Char where
ppr c = text [c]
instance Outputable Bool where
ppr True = text "True"
ppr False = text "False"
instance Outputable Ordering where
ppr LT = text "LT"
ppr EQ = text "EQ"
ppr GT = text "GT"
instance Outputable Int32 where
ppr n = integer $ fromIntegral n
instance Outputable Int64 where
ppr n = integer $ fromIntegral n
instance Outputable Int where
ppr n = int n
instance Outputable Word16 where
ppr n = integer $ fromIntegral n
instance Outputable Word32 where
ppr n = integer $ fromIntegral n
instance Outputable Word where
ppr n = integer $ fromIntegral n
instance Outputable () where
ppr _ = text "()"
instance (Outputable a) => Outputable [a] where
ppr xs = brackets (fsep (punctuate comma (map ppr xs)))
instance (Outputable a) => Outputable (Set a) where
ppr s = braces (fsep (punctuate comma (map ppr (Set.toList s))))
instance (Outputable a, Outputable b) => Outputable (a, b) where
ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
instance Outputable a => Outputable (Maybe a) where
ppr Nothing = text "Nothing"
ppr (Just x) = text "Just" <+> ppr x
instance (Outputable a, Outputable b) => Outputable (Either a b) where
ppr (Left x) = text "Left" <+> ppr x
ppr (Right y) = text "Right" <+> ppr y
instance (Outputable a, Outputable b, Outputable c) => Outputable (a, b, c) where
ppr (x,y,z) =
parens (sep [ppr x <> comma,
ppr y <> comma,
ppr z ])
instance (Outputable a, Outputable b, Outputable c, Outputable d) =>
Outputable (a, b, c, d) where
ppr (a,b,c,d) =
parens (sep [ppr a <> comma,
ppr b <> comma,
ppr c <> comma,
ppr d])
instance (Outputable a, Outputable b, Outputable c, Outputable d, Outputable e) =>
Outputable (a, b, c, d, e) where
ppr (a,b,c,d,e) =
parens (sep [ppr a <> comma,
ppr b <> comma,
ppr c <> comma,
ppr d <> comma,
ppr e])
instance (Outputable a, Outputable b, Outputable c, Outputable d, Outputable e, Outputable f) =>
Outputable (a, b, c, d, e, f) where
ppr (a,b,c,d,e,f) =
parens (sep [ppr a <> comma,
ppr b <> comma,
ppr c <> comma,
ppr d <> comma,
ppr e <> comma,
ppr f])
instance (Outputable a, Outputable b, Outputable c, Outputable d, Outputable e, Outputable f, Outputable g) =>
Outputable (a, b, c, d, e, f, g) where
ppr (a,b,c,d,e,f,g) =
parens (sep [ppr a <> comma,
ppr b <> comma,
ppr c <> comma,
ppr d <> comma,
ppr e <> comma,
ppr f <> comma,
ppr g])
instance Outputable FastString where
ppr fs = ftext fs
instance (Outputable key, Outputable elt) => Outputable (M.Map key elt) where
ppr m = ppr (M.toList m)
instance (Outputable elt) => Outputable (IM.IntMap elt) where
ppr m = ppr (IM.toList m)
instance Outputable Fingerprint where
ppr (Fingerprint w1 w2) = text (printf "%016x%016x" w1 w2)
instance Outputable a => Outputable (SCC a) where
ppr (AcyclicSCC v) = text "NONREC" $$ (nest 3 (ppr v))
ppr (CyclicSCC vs) = text "REC" $$ (nest 3 (vcat (map ppr vs)))
instance Outputable Serialized where
ppr (Serialized the_type bytes) = int (length bytes) <+> text "of type" <+> text (show the_type)
instance Outputable Extension where
ppr = text . show
data BindingSite
= LambdaBind
| CaseBind
| CasePatBind
| LetBind
class Outputable a => OutputableBndr a where
pprBndr :: BindingSite -> a -> SDoc
pprBndr _b x = ppr x
pprPrefixOcc, pprInfixOcc :: a -> SDoc
bndrIsJoin_maybe :: a -> Maybe Int
bndrIsJoin_maybe _ = Nothing
pprHsChar :: Char -> SDoc
pprHsChar c | c > '\x10ffff' = char '\\' <> text (show (fromIntegral (ord c) :: Word32))
| otherwise = text (show c)
pprHsString :: FastString -> SDoc
pprHsString fs = vcat (map text (showMultiLineString (unpackFS fs)))
pprHsBytes :: ByteString -> SDoc
pprHsBytes bs = let escaped = concatMap escape $ BS.unpack bs
in vcat (map text (showMultiLineString escaped)) <> char '#'
where escape :: Word8 -> String
escape w = let c = chr (fromIntegral w)
in if isAscii c
then [c]
else '\\' : show w
primCharSuffix, primFloatSuffix, primIntSuffix :: SDoc
primDoubleSuffix, primWordSuffix, primInt64Suffix, primWord64Suffix :: SDoc
primCharSuffix = char '#'
primFloatSuffix = char '#'
primIntSuffix = char '#'
primDoubleSuffix = text "##"
primWordSuffix = text "##"
primInt64Suffix = text "L#"
primWord64Suffix = text "L##"
pprPrimChar :: Char -> SDoc
pprPrimInt, pprPrimWord, pprPrimInt64, pprPrimWord64 :: Integer -> SDoc
pprPrimChar c = pprHsChar c <> primCharSuffix
pprPrimInt i = integer i <> primIntSuffix
pprPrimWord w = integer w <> primWordSuffix
pprPrimInt64 i = integer i <> primInt64Suffix
pprPrimWord64 w = integer w <> primWord64Suffix
pprPrefixVar :: Bool -> SDoc -> SDoc
pprPrefixVar is_operator pp_v
| is_operator = parens pp_v
| otherwise = pp_v
pprInfixVar :: Bool -> SDoc -> SDoc
pprInfixVar is_operator pp_v
| is_operator = pp_v
| otherwise = char '`' <> pp_v <> char '`'
pprFastFilePath :: FastString -> SDoc
pprFastFilePath path = text $ normalise $ unpackFS path
pprWithCommas :: (a -> SDoc)
-> [a]
-> SDoc
pprWithCommas pp xs = fsep (punctuate comma (map pp xs))
pprWithBars :: (a -> SDoc)
-> [a]
-> SDoc
pprWithBars pp xs = fsep (intersperse vbar (map pp xs))
interppSP :: Outputable a => [a] -> SDoc
interppSP xs = sep (map ppr xs)
interpp'SP :: Outputable a => [a] -> SDoc
interpp'SP xs = sep (punctuate comma (map ppr xs))
pprQuotedList :: Outputable a => [a] -> SDoc
pprQuotedList = quotedList . map ppr
quotedList :: [SDoc] -> SDoc
quotedList xs = hsep (punctuate comma (map quotes xs))
quotedListWithOr :: [SDoc] -> SDoc
quotedListWithOr xs@(_:_:_) = quotedList (init xs) <+> text "or" <+> quotes (last xs)
quotedListWithOr xs = quotedList xs
quotedListWithNor :: [SDoc] -> SDoc
quotedListWithNor xs@(_:_:_) = quotedList (init xs) <+> text "nor" <+> quotes (last xs)
quotedListWithNor xs = quotedList xs
intWithCommas :: Integral a => a -> SDoc
intWithCommas n
| n < 0 = char '-' <> intWithCommas (n)
| q == 0 = int (fromIntegral r)
| otherwise = intWithCommas q <> comma <> zeroes <> int (fromIntegral r)
where
(q,r) = n `quotRem` 1000
zeroes | r >= 100 = empty
| r >= 10 = char '0'
| otherwise = text "00"
speakNth :: Int -> SDoc
speakNth 1 = text "first"
speakNth 2 = text "second"
speakNth 3 = text "third"
speakNth 4 = text "fourth"
speakNth 5 = text "fifth"
speakNth 6 = text "sixth"
speakNth n = hcat [ int n, text suffix ]
where
suffix | n <= 20 = "th"
| last_dig == 1 = "st"
| last_dig == 2 = "nd"
| last_dig == 3 = "rd"
| otherwise = "th"
last_dig = n `rem` 10
speakN :: Int -> SDoc
speakN 0 = text "none"
speakN 1 = text "one"
speakN 2 = text "two"
speakN 3 = text "three"
speakN 4 = text "four"
speakN 5 = text "five"
speakN 6 = text "six"
speakN n = int n
speakNOf :: Int -> SDoc -> SDoc
speakNOf 0 d = text "no" <+> d <> char 's'
speakNOf 1 d = text "one" <+> d
speakNOf n d = speakN n <+> d <> char 's'
plural :: [a] -> SDoc
plural [_] = empty
plural _ = char 's'
isOrAre :: [a] -> SDoc
isOrAre [_] = text "is"
isOrAre _ = text "are"
doOrDoes :: [a] -> SDoc
doOrDoes [_] = text "does"
doOrDoes _ = text "do"
callStackDoc :: HasCallStack => SDoc
callStackDoc =
hang (text "Call stack:") 4 (vcat $ map text $ lines prettyCurrentCallStack)
pprPanic :: HasCallStack => String -> SDoc -> a
pprPanic s doc = panicDoc s (doc $$ callStackDoc)
pprSorry :: String -> SDoc -> a
pprSorry = sorryDoc
pprPgmError :: String -> SDoc -> a
pprPgmError = pgmErrorDoc
pprTraceDebug :: String -> SDoc -> a -> a
pprTraceDebug str doc x
| debugIsOn && hasPprDebug unsafeGlobalDynFlags = pprTrace str doc x
| otherwise = x
pprTrace :: String -> SDoc -> a -> a
pprTrace str doc x
| hasNoDebugOutput unsafeGlobalDynFlags = x
| otherwise =
pprDebugAndThen unsafeGlobalDynFlags trace (text str) doc x
pprTraceIt :: Outputable a => String -> a -> a
pprTraceIt desc x = pprTrace desc (ppr x) x
pprSTrace :: HasCallStack => SDoc -> a -> a
pprSTrace doc = pprTrace "" (doc $$ callStackDoc)
warnPprTrace :: Bool -> String -> Int -> SDoc -> a -> a
warnPprTrace _ _ _ _ x | not debugIsOn = x
warnPprTrace _ _file _line _msg x
| hasNoDebugOutput unsafeGlobalDynFlags = x
warnPprTrace False _file _line _msg x = x
warnPprTrace True file line msg x
= pprDebugAndThen unsafeGlobalDynFlags trace heading msg x
where
heading = hsep [text "WARNING: file", text file <> comma, text "line", int line]
assertPprPanic :: HasCallStack => String -> Int -> SDoc -> a
assertPprPanic _file _line msg
= pprPanic "ASSERT failed!" doc
where
doc = sep [ msg, callStackDoc ]
pprDebugAndThen :: DynFlags -> (String -> a) -> SDoc -> SDoc -> a
pprDebugAndThen dflags cont heading pretty_msg
= cont (showSDocDump dflags doc)
where
doc = sep [heading, nest 2 pretty_msg]