{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Rendering of data\/type families.
module Ormolu.Printer.Meat.Declaration.TypeFamily
  ( p_famDecl,
    p_tyFamInstEqn,
  )
where

import Control.Monad
import Data.Maybe (isNothing)
import GHC.Hs
import GHC.Types.Fixity
import GHC.Types.SrcLoc
import Ormolu.Printer.Combinators
import Ormolu.Printer.Meat.Common
import Ormolu.Printer.Meat.Type

p_famDecl :: FamilyStyle -> FamilyDecl GhcPs -> R ()
p_famDecl :: FamilyStyle -> FamilyDecl GhcPs -> R ()
p_famDecl FamilyStyle
style FamilyDecl {fdTyVars :: forall pass. FamilyDecl pass -> LHsQTyVars pass
fdTyVars = HsQTvs {[LHsTyVarBndr () GhcPs]
XHsQTvs GhcPs
hsq_ext :: forall pass. LHsQTyVars pass -> XHsQTvs pass
hsq_explicit :: forall pass. LHsQTyVars pass -> [LHsTyVarBndr () pass]
hsq_explicit :: [LHsTyVarBndr () GhcPs]
hsq_ext :: XHsQTvs GhcPs
..}, Maybe (LInjectivityAnn GhcPs)
FamilyInfo GhcPs
XCFamilyDecl GhcPs
LFamilyResultSig GhcPs
LIdP GhcPs
LexicalFixity
TopLevelFlag
fdTopLevel :: forall pass. FamilyDecl pass -> TopLevelFlag
fdResultSig :: forall pass. FamilyDecl pass -> LFamilyResultSig pass
fdLName :: forall pass. FamilyDecl pass -> LIdP pass
fdInjectivityAnn :: forall pass. FamilyDecl pass -> Maybe (LInjectivityAnn pass)
fdInfo :: forall pass. FamilyDecl pass -> FamilyInfo pass
fdFixity :: forall pass. FamilyDecl pass -> LexicalFixity
fdExt :: forall pass. FamilyDecl pass -> XCFamilyDecl pass
fdInjectivityAnn :: Maybe (LInjectivityAnn GhcPs)
fdResultSig :: LFamilyResultSig GhcPs
fdFixity :: LexicalFixity
fdLName :: LIdP GhcPs
fdTopLevel :: TopLevelFlag
fdInfo :: FamilyInfo GhcPs
fdExt :: XCFamilyDecl GhcPs
..} = do
  Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
mmeqs <- case FamilyInfo GhcPs
fdInfo of
    FamilyInfo GhcPs
DataFamily -> Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
forall a. Maybe a
Nothing Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
-> R ()
-> R (Maybe
        (Maybe
           [GenLocated
              SrcSpanAnnA
              (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]))
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> R ()
txt Text
"data"
    FamilyInfo GhcPs
OpenTypeFamily -> Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
forall a. Maybe a
Nothing Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
-> R ()
-> R (Maybe
        (Maybe
           [GenLocated
              SrcSpanAnnA
              (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]))
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> R ()
txt Text
"type"
    ClosedTypeFamily Maybe [LTyFamInstEqn GhcPs]
eqs -> Maybe
  [GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
-> Maybe
     (Maybe
        [GenLocated
           SrcSpanAnnA
           (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
forall a. a -> Maybe a
Just Maybe
  [GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
Maybe [LTyFamInstEqn GhcPs]
eqs Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
-> R ()
-> R (Maybe
        (Maybe
           [GenLocated
              SrcSpanAnnA
              (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]))
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> R ()
txt Text
"type"
  Text -> R ()
txt (Text -> R ()) -> Text -> R ()
forall a b. (a -> b) -> a -> b
$ case FamilyStyle
style of
    FamilyStyle
Associated -> Text
forall a. Monoid a => a
mempty
    FamilyStyle
Free -> Text
" family"
  let headerSpns :: [SrcSpan]
headerSpns = GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> SrcSpan
forall a e. GenLocated (SrcSpanAnn' a) e -> SrcSpan
getLocA GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName
LIdP GhcPs
fdLName SrcSpan -> [SrcSpan] -> [SrcSpan]
forall a. a -> [a] -> [a]
: (GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs) -> SrcSpan
forall a e. GenLocated (SrcSpanAnn' a) e -> SrcSpan
getLocA (GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs) -> SrcSpan)
-> [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)] -> [SrcSpan]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)]
[LHsTyVarBndr () GhcPs]
hsq_explicit)
      headerAndSigSpns :: [SrcSpan]
headerAndSigSpns = GenLocated SrcSpan (FamilyResultSig GhcPs) -> SrcSpan
forall l e. GenLocated l e -> l
getLoc GenLocated SrcSpan (FamilyResultSig GhcPs)
LFamilyResultSig GhcPs
fdResultSig SrcSpan -> [SrcSpan] -> [SrcSpan]
forall a. a -> [a] -> [a]
: [SrcSpan]
headerSpns
  R () -> R ()
inci (R () -> R ()) -> (R () -> R ()) -> R () -> R ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SrcSpan] -> R () -> R ()
switchLayout [SrcSpan]
headerAndSigSpns (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    R ()
breakpoint
    [SrcSpan] -> R () -> R ()
switchLayout [SrcSpan]
headerSpns (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
      Bool -> Bool -> R () -> [R ()] -> R ()
p_infixDefHelper
        (LexicalFixity -> Bool
isInfix LexicalFixity
fdFixity)
        Bool
True
        (GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> R ()
p_rdrName GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName
LIdP GhcPs
fdLName)
        ((HsTyVarBndr () GhcPs -> R ())
-> GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs) -> R ()
forall l a. HasSrcSpan l => (a -> R ()) -> GenLocated l a -> R ()
located' HsTyVarBndr () GhcPs -> R ()
forall flag.
IsInferredTyVarBndr flag =>
HsTyVarBndr flag GhcPs -> R ()
p_hsTyVarBndr (GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs) -> R ())
-> [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)] -> [R ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)]
[LHsTyVarBndr () GhcPs]
hsq_explicit)
    let resultSig :: Maybe (R ())
resultSig = GenLocated SrcSpan (FamilyResultSig GhcPs) -> Maybe (R ())
p_familyResultSigL GenLocated SrcSpan (FamilyResultSig GhcPs)
LFamilyResultSig GhcPs
fdResultSig
    Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Maybe (R ()) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (R ())
resultSig Bool -> Bool -> Bool
&& Maybe (GenLocated SrcSpan (InjectivityAnn GhcPs)) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (GenLocated SrcSpan (InjectivityAnn GhcPs))
Maybe (LInjectivityAnn GhcPs)
fdInjectivityAnn) R ()
space
    R () -> R ()
inci (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
      Maybe (R ()) -> R ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ Maybe (R ())
resultSig
      R ()
space
      Maybe (GenLocated SrcSpan (InjectivityAnn GhcPs))
-> (GenLocated SrcSpan (InjectivityAnn GhcPs) -> R ()) -> R ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe (GenLocated SrcSpan (InjectivityAnn GhcPs))
Maybe (LInjectivityAnn GhcPs)
fdInjectivityAnn ((InjectivityAnn GhcPs -> R ())
-> GenLocated SrcSpan (InjectivityAnn GhcPs) -> R ()
forall l a. HasSrcSpan l => (a -> R ()) -> GenLocated l a -> R ()
located' InjectivityAnn GhcPs -> R ()
p_injectivityAnn)
  case Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
mmeqs of
    Maybe
  (Maybe
     [GenLocated
        SrcSpanAnnA
        (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))])
Nothing -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    Just Maybe
  [GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
meqs -> do
      R () -> R ()
inci (R () -> R ()) -> (R () -> R ()) -> R () -> R ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SrcSpan] -> R () -> R ()
switchLayout [SrcSpan]
headerAndSigSpns (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
        R ()
breakpoint
        Text -> R ()
txt Text
"where"
      case Maybe
  [GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
meqs of
        Maybe
  [GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
Nothing -> do
          R ()
space
          Text -> R ()
txt Text
".."
        Just [GenLocated
   SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
eqs -> do
          R ()
newline
          R ()
-> (GenLocated
      SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))
    -> R ())
-> [GenLocated
      SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
-> R ()
forall a. R () -> (a -> R ()) -> [a] -> R ()
sep R ()
newline ((FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)) -> R ())
-> GenLocated
     SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))
-> R ()
forall l a. HasSrcSpan l => (a -> R ()) -> GenLocated l a -> R ()
located' (R () -> R ()
inci (R () -> R ())
-> (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)) -> R ())
-> FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs))
-> R ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)) -> R ()
TyFamInstEqn GhcPs -> R ()
p_tyFamInstEqn)) [GenLocated
   SrcSpanAnnA (FamEqn GhcPs (GenLocated SrcSpanAnnA (HsType GhcPs)))]
eqs

p_familyResultSigL ::
  Located (FamilyResultSig GhcPs) ->
  Maybe (R ())
p_familyResultSigL :: GenLocated SrcSpan (FamilyResultSig GhcPs) -> Maybe (R ())
p_familyResultSigL (L SrcSpan
_ FamilyResultSig GhcPs
a) = case FamilyResultSig GhcPs
a of
  NoSig XNoSig GhcPs
NoExtField -> Maybe (R ())
forall a. Maybe a
Nothing
  KindSig XCKindSig GhcPs
NoExtField LHsKind GhcPs
k -> R () -> Maybe (R ())
forall a. a -> Maybe a
Just (R () -> Maybe (R ())) -> R () -> Maybe (R ())
forall a b. (a -> b) -> a -> b
$ do
    Text -> R ()
txt Text
"::"
    R ()
breakpoint
    GenLocated SrcSpanAnnA (HsType GhcPs)
-> (HsType GhcPs -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located GenLocated SrcSpanAnnA (HsType GhcPs)
LHsKind GhcPs
k HsType GhcPs -> R ()
p_hsType
  TyVarSig XTyVarSig GhcPs
NoExtField LHsTyVarBndr () GhcPs
bndr -> R () -> Maybe (R ())
forall a. a -> Maybe a
Just (R () -> Maybe (R ())) -> R () -> Maybe (R ())
forall a b. (a -> b) -> a -> b
$ do
    R ()
equals
    R ()
breakpoint
    GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)
-> (HsTyVarBndr () GhcPs -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)
LHsTyVarBndr () GhcPs
bndr HsTyVarBndr () GhcPs -> R ()
forall flag.
IsInferredTyVarBndr flag =>
HsTyVarBndr flag GhcPs -> R ()
p_hsTyVarBndr

p_injectivityAnn :: InjectivityAnn GhcPs -> R ()
p_injectivityAnn :: InjectivityAnn GhcPs -> R ()
p_injectivityAnn (InjectivityAnn XCInjectivityAnn GhcPs
_ LIdP GhcPs
a [LIdP GhcPs]
bs) = do
  Text -> R ()
txt Text
"|"
  R ()
space
  GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> R ()
p_rdrName GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName
LIdP GhcPs
a
  R ()
space
  Text -> R ()
txt Text
"->"
  R ()
space
  R ()
-> (GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> R ())
-> [GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName]
-> R ()
forall a. R () -> (a -> R ()) -> [a] -> R ()
sep R ()
space GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> R ()
p_rdrName [GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName]
[LIdP GhcPs]
bs

p_tyFamInstEqn :: TyFamInstEqn GhcPs -> R ()
p_tyFamInstEqn :: TyFamInstEqn GhcPs -> R ()
p_tyFamInstEqn FamEqn {HsTyPats GhcPs
XCFamEqn GhcPs (LHsKind GhcPs)
LIdP GhcPs
LHsKind GhcPs
LexicalFixity
HsOuterFamEqnTyVarBndrs GhcPs
feqn_tycon :: forall pass rhs. FamEqn pass rhs -> LIdP pass
feqn_rhs :: forall pass rhs. FamEqn pass rhs -> rhs
feqn_pats :: forall pass rhs. FamEqn pass rhs -> HsTyPats pass
feqn_fixity :: forall pass rhs. FamEqn pass rhs -> LexicalFixity
feqn_ext :: forall pass rhs. FamEqn pass rhs -> XCFamEqn pass rhs
feqn_bndrs :: forall pass rhs. FamEqn pass rhs -> HsOuterFamEqnTyVarBndrs pass
feqn_rhs :: LHsKind GhcPs
feqn_fixity :: LexicalFixity
feqn_pats :: HsTyPats GhcPs
feqn_bndrs :: HsOuterFamEqnTyVarBndrs GhcPs
feqn_tycon :: LIdP GhcPs
feqn_ext :: XCFamEqn GhcPs (LHsKind GhcPs)
..} = do
  case HsOuterFamEqnTyVarBndrs GhcPs
feqn_bndrs of
    HsOuterImplicit XHsOuterImplicit GhcPs
NoExtField -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    HsOuterExplicit XHsOuterExplicit GhcPs ()
_ [LHsTyVarBndr () (NoGhcTc GhcPs)]
bndrs -> do
      ForAllVisibility
-> (HsTyVarBndr () GhcPs -> R ())
-> [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)]
-> R ()
forall a. ForAllVisibility -> (a -> R ()) -> [LocatedA a] -> R ()
p_forallBndrs ForAllVisibility
ForAllInvis HsTyVarBndr () GhcPs -> R ()
forall flag.
IsInferredTyVarBndr flag =>
HsTyVarBndr flag GhcPs -> R ()
p_hsTyVarBndr [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)]
[LHsTyVarBndr () (NoGhcTc GhcPs)]
bndrs
      R ()
breakpoint
  let atLeastOneBndr :: Bool
atLeastOneBndr = case HsOuterFamEqnTyVarBndrs GhcPs
feqn_bndrs of
        HsOuterImplicit XHsOuterImplicit GhcPs
NoExtField -> Bool
False
        HsOuterExplicit XHsOuterExplicit GhcPs ()
_ [LHsTyVarBndr () (NoGhcTc GhcPs)]
bndrs -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [GenLocated SrcSpanAnnA (HsTyVarBndr () GhcPs)]
[LHsTyVarBndr () (NoGhcTc GhcPs)]
bndrs
  Bool -> R () -> R ()
inciIf Bool
atLeastOneBndr (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    let famLhsSpn :: [SrcSpan]
famLhsSpn = GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> SrcSpan
forall a e. GenLocated (SrcSpanAnn' a) e -> SrcSpan
getLocA GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName
LIdP GhcPs
feqn_tycon SrcSpan -> [SrcSpan] -> [SrcSpan]
forall a. a -> [a] -> [a]
: (HsArg
   (GenLocated SrcSpanAnnA (HsType GhcPs))
   (GenLocated SrcSpanAnnA (HsType GhcPs))
 -> SrcSpan)
-> [HsArg
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (GenLocated SrcSpanAnnA (HsType GhcPs))]
-> [SrcSpan]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HsArg
  (GenLocated SrcSpanAnnA (HsType GhcPs))
  (GenLocated SrcSpanAnnA (HsType GhcPs))
-> SrcSpan
forall (pass :: Pass). LHsTypeArg (GhcPass pass) -> SrcSpan
lhsTypeArgSrcSpan [HsArg
   (GenLocated SrcSpanAnnA (HsType GhcPs))
   (GenLocated SrcSpanAnnA (HsType GhcPs))]
HsTyPats GhcPs
feqn_pats
    [SrcSpan] -> R () -> R ()
switchLayout [SrcSpan]
famLhsSpn (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$
      Bool -> Bool -> R () -> [R ()] -> R ()
p_infixDefHelper
        (LexicalFixity -> Bool
isInfix LexicalFixity
feqn_fixity)
        Bool
True
        (GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName -> R ()
p_rdrName GenLocated (SrcSpanAnn' (EpAnn NameAnn)) RdrName
LIdP GhcPs
feqn_tycon)
        (HsArg
  (GenLocated SrcSpanAnnA (HsType GhcPs))
  (GenLocated SrcSpanAnnA (HsType GhcPs))
-> R ()
LHsTypeArg GhcPs -> R ()
p_lhsTypeArg (HsArg
   (GenLocated SrcSpanAnnA (HsType GhcPs))
   (GenLocated SrcSpanAnnA (HsType GhcPs))
 -> R ())
-> [HsArg
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (GenLocated SrcSpanAnnA (HsType GhcPs))]
-> [R ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [HsArg
   (GenLocated SrcSpanAnnA (HsType GhcPs))
   (GenLocated SrcSpanAnnA (HsType GhcPs))]
HsTyPats GhcPs
feqn_pats)
    R ()
space
    R ()
equals
    R ()
breakpoint
    R () -> R ()
inci (GenLocated SrcSpanAnnA (HsType GhcPs)
-> (HsType GhcPs -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located GenLocated SrcSpanAnnA (HsType GhcPs)
LHsKind GhcPs
feqn_rhs HsType GhcPs -> R ()
p_hsType)

----------------------------------------------------------------------------
-- Helpers

isInfix :: LexicalFixity -> Bool
isInfix :: LexicalFixity -> Bool
isInfix = \case
  LexicalFixity
Infix -> Bool
True
  LexicalFixity
Prefix -> Bool
False