{-# LANGUAGE CPP #-}
module GHC.SourceGen.Pat.Internal where

import GHC.Hs.Pat (Pat(..))
#if MIN_VERSION_ghc(9,0,0)
import GHC.Hs.Type (HsConDetails(..))
import GHC.Types.SrcLoc (unLoc)
#else
import GHC.Hs.Type (HsConDetails(..))
import SrcLoc (unLoc)
#endif

import GHC.SourceGen.Lit.Internal (litNeedsParen, overLitNeedsParen)
import GHC.SourceGen.Syntax.Internal

-- Note: GHC>=8.6 inserts parentheses automatically when pretty-printing patterns.
-- When we stop supporting lower versions, we may be able to simplify this.
parenthesize :: Pat' -> Pat'
parenthesize :: Pat' -> Pat'
parenthesize Pat'
p
    | Pat' -> Bool
needsPar Pat'
p = Pat' -> Pat'
parPat Pat'
p
    | Bool
otherwise = Pat'
p


needsPar :: Pat' -> Bool
#if MIN_VERSION_ghc(8,6,0)
needsPar :: Pat' -> Bool
needsPar (LitPat XLitPat GhcPs
_ HsLit GhcPs
l) = HsLit GhcPs -> Bool
litNeedsParen HsLit GhcPs
l
needsPar (NPat XNPat GhcPs
_ XRec GhcPs (HsOverLit GhcPs)
l Maybe (SyntaxExpr GhcPs)
_ SyntaxExpr GhcPs
_) = HsOverLit GhcPs -> Bool
overLitNeedsParen (HsOverLit GhcPs -> Bool) -> HsOverLit GhcPs -> Bool
forall a b. (a -> b) -> a -> b
$ GenLocated (SrcAnn NoEpAnns) (HsOverLit GhcPs) -> HsOverLit GhcPs
forall l e. GenLocated l e -> e
unLoc XRec GhcPs (HsOverLit GhcPs)
GenLocated (SrcAnn NoEpAnns) (HsOverLit GhcPs)
l
#else
needsPar (LitPat l) = litNeedsParen l
needsPar (NPat l _ _ _) = overLitNeedsParen $ unLoc l
#endif
#if MIN_VERSION_ghc(9,2,0)
needsPar (ConPat XConPat GhcPs
_ XRec GhcPs (ConLikeP GhcPs)
_ (PrefixCon [HsConPatTyArg (NoGhcTc GhcPs)]
_ [LPat GhcPs]
xs)) = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GenLocated SrcSpanAnnA Pat'] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LPat GhcPs]
[GenLocated SrcSpanAnnA Pat']
xs
#elif MIN_VERSION_ghc(9,0,0)
needsPar (ConPat _ _ (PrefixCon xs)) = not $ null xs
#else
needsPar (ConPatIn _ (PrefixCon xs)) = not $ null xs
#endif
#if MIN_VERSION_ghc(9,0,0)
needsPar (ConPat XConPat GhcPs
_ XRec GhcPs (ConLikeP GhcPs)
_ (InfixCon LPat GhcPs
_ LPat GhcPs
_)) = Bool
True
#else
needsPar (ConPatIn _ (InfixCon _ _)) = True
needsPar ConPatOut{} = True
#endif
#if MIN_VERSION_ghc(8,6,0)
needsPar SigPat{} = Bool
True
#else
needsPar SigPatIn{} = True
needsPar SigPatOut{} = True
#endif
needsPar Pat'
_ = Bool
False

parPat :: Pat' -> Pat'
#if MIN_VERSION_ghc(9,4,0)
parPat :: Pat' -> Pat'
parPat Pat'
p = (EpAnn NoEpAnns
 -> GenLocated TokenLocation (HsToken "(")
 -> GenLocated SrcSpanAnnA Pat'
 -> GenLocated TokenLocation (HsToken ")")
 -> Pat')
-> GenLocated TokenLocation (HsToken "(")
-> GenLocated SrcSpanAnnA Pat'
-> GenLocated TokenLocation (HsToken ")")
-> Pat'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XParPat GhcPs
-> LHsToken "(" GhcPs -> LPat GhcPs -> LHsToken ")" GhcPs -> Pat'
EpAnn NoEpAnns
-> GenLocated TokenLocation (HsToken "(")
-> GenLocated SrcSpanAnnA Pat'
-> GenLocated TokenLocation (HsToken ")")
-> Pat'
forall p.
XParPat p -> LHsToken "(" p -> LPat p -> LHsToken ")" p -> Pat p
ParPat GenLocated TokenLocation (HsToken "(")
forall (t :: Symbol). GenLocated TokenLocation (HsToken t)
mkToken (Pat' -> LPat GhcPs
builtPat Pat'
p) GenLocated TokenLocation (HsToken ")")
forall (t :: Symbol). GenLocated TokenLocation (HsToken t)
mkToken
#else
parPat = withEpAnnNotUsed ParPat . builtPat
#endif