hnix-0.13.1: src/Nix/Render/Frame.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
-- | Code for rendering/representation of the messages packaged with their context (Frames).
module Nix.Render.Frame where
import Prelude hiding ( Comparison )
import Nix.Utils
import Data.Fix ( Fix(..) )
import Nix.Eval
import Nix.Exec
import Nix.Expr
import Nix.Frames
import Nix.Normal
import Nix.Options
import Nix.Pretty
import Nix.Render
import Nix.Thunk
import Nix.Value
import Prettyprinter hiding ( list )
import qualified Text.Show as Text
import Text.Megaparsec.Pos ( sourcePosPretty)
#ifdef MIN_VERSION_pretty_show
import qualified Text.Show.Pretty as PS
#endif
renderFrames
:: forall v t f e m ann
. ( MonadReader e m
, Has e Options
, MonadFile m
, MonadCitedThunks t f m
, Typeable v
)
=> Frames
-> m (Doc ann)
renderFrames [] = stub
renderFrames (x : xs) = do
opts :: Options <- asks (view hasLens)
frames <- if
| verbose opts <= ErrorsOnly -> renderFrame @v @t @f x
| verbose opts <= Informational -> do
f <- renderFrame @v @t @f x
pure $ concatMap go (reverse xs) <> f
| otherwise -> concat <$> traverse (renderFrame @v @t @f) (reverse (x : xs))
pure $
list
mempty
vsep
frames
where
go :: NixFrame -> [Doc ann]
go f =
maybe
mempty
(\ pos -> ["While evaluating at " <> pretty (sourcePosPretty pos) <> colon])
(framePos @v @m f)
framePos
:: forall v (m :: * -> *)
. (Typeable m, Typeable v)
=> NixFrame
-> Maybe SourcePos
framePos (NixFrame _ f)
| Just (e :: EvalFrame m v) <- fromException f = case e of
EvaluatingExpr _ (AnnE (SrcSpan beg _) _) -> pure beg
_ -> Nothing
| otherwise = Nothing
renderFrame
:: forall v t f e m ann
. ( MonadReader e m
, Has e Options
, MonadFile m
, MonadCitedThunks t f m
, Typeable v
)
=> NixFrame
-> m [Doc ann]
renderFrame (NixFrame level f)
| Just (e :: EvalFrame m v) <- fromException f = renderEvalFrame level e
| Just (e :: ThunkLoop ) <- fromException f = renderThunkLoop level e
| Just (e :: ValueFrame t f m ) <- fromException f = renderValueFrame level e
| Just (e :: NormalLoop t f m ) <- fromException f = renderNormalLoop level e
| Just (e :: ExecFrame t f m ) <- fromException f = renderExecFrame level e
| Just (e :: ErrorCall ) <- fromException f = pure [pretty (Text.show e)]
| Just (e :: SynHoleInfo m v) <- fromException f = pure [pretty (Text.show e)]
| otherwise = fail $ "Unrecognized frame: " <> show f
wrapExpr :: NExprF r -> NExpr
wrapExpr x = Fix (Fix (NSym "<?>") <$ x)
renderEvalFrame
:: (MonadReader e m, Has e Options, MonadFile m)
=> NixLevel
-> EvalFrame m v
-> m [Doc ann]
renderEvalFrame level f =
do
opts :: Options <- asks (view hasLens)
case f of
EvaluatingExpr scope e@(AnnE ann _) ->
do
let
scopeInfo =
bool
mempty
[pretty $ Text.show scope]
(showScopes opts)
fmap
(\x -> scopeInfo <> [x])
$ renderLocation ann =<<
renderExpr level "While evaluating" "Expression" e
ForcingExpr _scope e@(AnnE ann _) | thunks opts ->
fmap
(: mempty)
$ renderLocation ann =<<
renderExpr level "While forcing thunk from" "Forcing thunk" e
Calling name ann ->
fmap
(: mempty)
$ renderLocation ann $
"While calling builtins." <> pretty name
SynHole synfo ->
sequence $
let e@(AnnE ann _) = _synHoleInfo_expr synfo in
[ renderLocation ann =<<
renderExpr level "While evaluating" "Syntactic Hole" e
, pure $ pretty $ Text.show $ _synHoleInfo_scope synfo
]
ForcingExpr _ _ -> stub
renderExpr
:: (MonadReader e m, Has e Options, MonadFile m)
=> NixLevel
-> Text
-> Text
-> NExprLoc
-> m (Doc ann)
renderExpr _level longLabel shortLabel e@(AnnE _ x) = do
opts :: Options <- asks (view hasLens)
let rendered
| verbose opts >= DebugInfo =
#ifdef MIN_VERSION_pretty_show
pretty (PS.ppShow (stripAnnotation e))
#else
pretty (show (stripAnnotation e))
#endif
| verbose opts >= Chatty = prettyNix (stripAnnotation e)
| otherwise = prettyNix (Fix (Fix (NSym "<?>") <$ x))
pure $
bool
(pretty shortLabel <> fillSep [": ", rendered])
(vsep [pretty (longLabel <> ":\n>>>>>>>>"), indent 2 rendered, "<<<<<<<<"])
(verbose opts >= Chatty)
renderValueFrame
:: forall e t f m ann
. (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)
=> NixLevel
-> ValueFrame t f m
-> m [Doc ann]
renderValueFrame level = fmap (: mempty) . \case
ForcingThunk _t -> pure "ForcingThunk" -- jww (2019-03-18): NYI
ConcerningValue _v -> pure "ConcerningValue"
Comparison _ _ -> pure "Comparing"
Addition _ _ -> pure "Adding"
Division _ _ -> pure "Dividing"
Multiplication _ _ -> pure "Multiplying"
Coercion x y -> pure
$ mconcat [desc, pretty (describeValue x), " to ", pretty (describeValue y)]
where
desc =
bool
"While coercing "
"Cannot coerce "
(level <= Error)
CoercionToJson v ->
("CoercionToJson " <>) <$> renderValue level "" "" v
CoercionFromJson _j -> pure "CoercionFromJson"
Expectation t v ->
(msg <>) <$> renderValue @_ @t @f @m level "" "" v
where
msg = "Expected " <> pretty (describeValue t) <> ", but saw "
renderValue
:: forall e t f m ann
. (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)
=> NixLevel
-> Text
-> Text
-> NValue t f m
-> m (Doc ann)
renderValue _level _longLabel _shortLabel v = do
opts :: Options <- asks (view hasLens)
bool
prettyNValue
prettyNValueProv
(values opts)
<$> removeEffects v
renderExecFrame
:: (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)
=> NixLevel
-> ExecFrame t f m
-> m [Doc ann]
renderExecFrame level =
\case
Assertion ann v ->
fmap
(: mempty)
(do
d <- renderValue level "" "" v
renderLocation ann $ fillSep ["Assertion failed:", d]
)
renderThunkLoop
:: (MonadReader e m, Has e Options, MonadFile m, Show (ThunkId m))
=> NixLevel
-> ThunkLoop
-> m [Doc ann]
renderThunkLoop _level = pure . (: mempty) . \case
ThunkLoop n -> pretty $ "Infinite recursion in thunk " <> n
renderNormalLoop
:: (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)
=> NixLevel
-> NormalLoop t f m
-> m [Doc ann]
renderNormalLoop level =
fmap
(: mempty)
. \case
NormalLoop v ->
("Infinite recursion during normalization forcing " <>) <$> renderValue level "" "" v