content: {-# LANGUAGE CPP #-}
  {-# LANGUAGE FlexibleContexts #-}
  {-# LANGUAGE RecordWildCards #-}
  
  module HIndent.Ast.Declaration.Bind.GuardedRhs
    ( GuardedRhs
    , mkGuardedRhs
    , mkCaseGuardedRhs
    , mkLambdaGuardedRhs
    , mkMultiWayIfGuardedRhs
    , mkCaseCmdGuardedRhs
    , mkLambdaCmdGuardedRhs
    ) where
  
  import qualified GHC.Types.SrcLoc as GHC
  import HIndent.Ast.Guard
    ( Guard
    , mkCaseCmdGuard
    , mkCaseExprGuard
    , mkExprGuard
    , mkLambdaCmdGuard
    , mkLambdaExprGuard
    , mkMultiWayIfExprGuard
    )
  import HIndent.Ast.NodeComments
  import HIndent.Ast.WithComments
  import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC
  import {-# SOURCE #-} HIndent.Pretty
  import HIndent.Pretty.Combinators
  import HIndent.Pretty.NodeComments
  
  data Context
    = Plain
    | Case
    | Lambda
    | MultiWayIf
    deriving (Eq)
  
  data GuardedRhs = GuardedRhs
    { context :: Context
    , guards :: [WithComments Guard]
    , localBinds :: GHC.HsLocalBinds GHC.GhcPs
    }
  
  instance CommentExtraction GuardedRhs where
    nodeComments _ = NodeComments [] [] []
  
  instance Pretty GuardedRhs where
    pretty' GuardedRhs {..} = do
      mapM_ pretty guards
      case (localBinds, context) of
        (GHC.HsValBinds {}, Case) ->
          indentedBlock $ do
            newline
            string "where " |=> pretty localBinds
        (GHC.HsValBinds epa lr, _) ->
          indentedWithSpace 2
            $ newlinePrefixed
                [ string "where"
                , printCommentsAnd (GHC.L epa lr) (indentedWithSpace 2 . pretty)
                ]
        _ -> return ()
  
  mkGuardedRhs :: GHC.GRHSs GHC.GhcPs (GHC.LHsExpr GHC.GhcPs) -> GuardedRhs
  mkGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = Plain
      , guards = map (fmap mkExprGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  
  mkCaseGuardedRhs :: GHC.GRHSs GHC.GhcPs (GHC.LHsExpr GHC.GhcPs) -> GuardedRhs
  mkCaseGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = Case
      , guards = map (fmap mkCaseExprGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  
  mkLambdaGuardedRhs :: GHC.GRHSs GHC.GhcPs (GHC.LHsExpr GHC.GhcPs) -> GuardedRhs
  mkLambdaGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = Lambda
      , guards = map (fmap mkLambdaExprGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  
  mkMultiWayIfGuardedRhs ::
       GHC.GRHSs GHC.GhcPs (GHC.LHsExpr GHC.GhcPs) -> GuardedRhs
  mkMultiWayIfGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = MultiWayIf
      , guards = map (fmap mkMultiWayIfExprGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  
  mkCaseCmdGuardedRhs :: GHC.GRHSs GHC.GhcPs (GHC.LHsCmd GHC.GhcPs) -> GuardedRhs
  mkCaseCmdGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = Case
      , guards = map (fmap mkCaseCmdGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  
  mkLambdaCmdGuardedRhs ::
       GHC.GRHSs GHC.GhcPs (GHC.LHsCmd GHC.GhcPs) -> GuardedRhs
  mkLambdaCmdGuardedRhs GHC.GRHSs {..} =
    GuardedRhs
      { context = Lambda
      , guards = map (fmap mkLambdaCmdGuard . fromGenLocated) grhssGRHSs
      , localBinds = grhssLocalBinds
      }
  