-- Copyright 2019 Google LLC
--
-- Use of this source code is governed by a BSD-style
-- license that can be found in the LICENSE file or at
-- https://developers.google.com/open-source/licenses/bsd

{-# LANGUAGE CPP #-}
-- | This module overloads some combinators so they can be used in
-- different contexts: for expressions, types and/or patterns.
module GHC.SourceGen.Overloaded
    ( Par(..)
    , App(..)
    , HasTuple(..)
    , tuple
    , unboxedTuple
    , HasList(..)
    , Var(..)
    , BVar(..)
    ) where

import GHC.Hs.Type
    ( HsType(..)
    , HsTyVarBndr(..)
    )
import GHC.Hs (IE(..), IEWrappedName(..)
#if MIN_VERSION_ghc(9,6,0)
    , noExtField
#endif
    )
#if !MIN_VERSION_ghc(8,6,0)
import PlaceHolder(PlaceHolder(..))
#endif

import GHC.Hs
    ( HsExpr(..)
    , Pat(..)
    , HsTupArg(..)
    , HsTupleSort(..)
    )
#if MIN_VERSION_ghc(9,0,0)
import GHC.Types.Basic (Boxity(..))
import GHC.Core.DataCon (dataConName)
import GHC.Types.Name.Reader (nameRdrName)
import GHC.Builtin.Types (consDataCon_RDR, nilDataCon, unitDataCon)
import GHC.Types.Var (Specificity(..))
#else
import BasicTypes (Boxity(..))
import DataCon (dataConName)
import RdrName (nameRdrName)
import TysWiredIn (consDataCon_RDR, nilDataCon, unitDataCon)
#endif

import GHC.SourceGen.Expr.Internal
import GHC.SourceGen.Name.Internal
import GHC.SourceGen.Syntax.Internal
import GHC.SourceGen.Type.Internal

-- | A class for wrapping terms in parentheses.
class Par e where
    par :: e -> e

instance Par HsExpr' where
#if MIN_VERSION_ghc(9,4,0)
    par :: HsExpr' -> HsExpr'
par HsExpr'
p = (EpAnn NoEpAnns
 -> GenLocated TokenLocation (HsToken "(")
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> GenLocated TokenLocation (HsToken ")")
 -> HsExpr')
-> GenLocated TokenLocation (HsToken "(")
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated TokenLocation (HsToken ")")
-> HsExpr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XPar GhcPs
-> LHsToken "(" GhcPs
-> LHsExpr GhcPs
-> LHsToken ")" GhcPs
-> HsExpr'
EpAnn NoEpAnns
-> GenLocated TokenLocation (HsToken "(")
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated TokenLocation (HsToken ")")
-> HsExpr'
forall p.
XPar p -> LHsToken "(" p -> LHsExpr p -> LHsToken ")" p -> HsExpr p
HsPar GenLocated TokenLocation (HsToken "(")
forall (t :: Symbol). GenLocated TokenLocation (HsToken t)
mkToken (HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsExpr'
p) GenLocated TokenLocation (HsToken ")")
forall (t :: Symbol). GenLocated TokenLocation (HsToken t)
mkToken
#else
    par = withEpAnnNotUsed HsPar . mkLocated
#endif

instance Par Pat' where
#if MIN_VERSION_ghc(9,4,0)
    par :: Pat' -> Pat'
par Pat'
p = (EpAnn NoEpAnns
 -> GenLocated TokenLocation (HsToken "(")
 -> GenLocated (SrcSpanAnn AnnListItem) Pat'
 -> GenLocated TokenLocation (HsToken ")")
 -> Pat')
-> GenLocated TokenLocation (HsToken "(")
-> GenLocated (SrcSpanAnn AnnListItem) 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 (SrcSpanAnn AnnListItem) 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
    par = withEpAnnNotUsed ParPat . builtPat
#endif

instance Par HsType' where
    par :: HsType' -> HsType'
par = (EpAnn AnnParen
 -> GenLocated (SrcSpanAnn AnnListItem) HsType' -> HsType')
-> GenLocated (SrcSpanAnn AnnListItem) HsType' -> HsType'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XParTy GhcPs -> LHsType GhcPs -> HsType'
EpAnn AnnParen
-> GenLocated (SrcSpanAnn AnnListItem) HsType' -> HsType'
forall pass. XParTy pass -> LHsType pass -> HsType pass
HsParTy (GenLocated (SrcSpanAnn AnnListItem) HsType' -> HsType')
-> (HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType')
-> HsType'
-> HsType'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated

-- | A class for term application.
--
-- These functions may add additional parentheses to the AST.
-- GHC's pretty-printing functions expect those parentheses
-- to already be present, because GHC preserves parentheses when it
-- parses the AST from a source file.
class App e where
    -- | Prefix-apply a term:
    --
    -- > f x
    -- > =====
    -- > var "f" @@ var "x"
    --
    -- > (+) x
    -- > =====
    -- > var "+" @@ var "x"
    --
    -- Also parenthesizes the right-hand side in order to preserve its
    -- semantics when pretty-printed, but tries to do so only when
    -- necessary:
    --
    -- > f x y
    -- > =====
    -- > var "f" @@ var "x" @@ var "y"
    -- > -- equivalently:
    -- > (var "f" @@ var "x") @@ var "y"
    --
    -- > f (g x)
    -- > =====
    -- > var "f" @@ (var "g" @@ var "x")
    --
    -- > f (g x)
    -- > =====
    -- > var "f" @@ par (var "g" @@ par (var "x"))
    (@@) :: e -> e -> e

    -- | Infix-apply an operator or function.
    --
    -- For example:
    --
    -- > x + y
    -- > =====
    -- > op (var "x") "+" (var "y")
    --
    -- Also parenthesizes the right-hand side in order to preserve its
    -- semantics when pretty-printed, but tries to do so only when necessary:
    --
    -- > f x + g y
    -- > =====
    -- > op (var "f" @@ var "x") "+" (var "g" @@ var "y")
    --
    -- > x + (y + z)
    -- > =====
    -- > op (var "x") "+" (op (var "y") "+" (var "z"))
    --
    -- > f x `plus` g y
    -- > =====
    -- > op (var "f" @@ var "x") "plus" (var "g" @@ var "y")
    op :: e -> RdrNameStr -> e -> e
infixl 2 @@

instance App HsExpr' where
    op :: HsExpr' -> RdrNameStr -> HsExpr' -> HsExpr'
op HsExpr'
x RdrNameStr
o HsExpr'
y
        = (EpAnn [AddEpAnn]
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> HsExpr')
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> HsExpr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XOpApp GhcPs
-> LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs -> HsExpr'
EpAnn [AddEpAnn]
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> HsExpr'
forall p.
XOpApp p -> LHsExpr p -> LHsExpr p -> LHsExpr p -> HsExpr p
OpApp
            (LHsExpr GhcPs -> LHsExpr GhcPs
parenthesizeExprForOp (LHsExpr GhcPs -> LHsExpr GhcPs) -> LHsExpr GhcPs -> LHsExpr GhcPs
forall a b. (a -> b) -> a -> b
$ HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsExpr'
x)
            (HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated (HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr')
-> HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a b. (a -> b) -> a -> b
$ RdrNameStr -> HsExpr'
forall a. Var a => RdrNameStr -> a
var RdrNameStr
o)
#if !MIN_VERSION_ghc(8,6,0)
            PlaceHolder
#endif
            (LHsExpr GhcPs -> LHsExpr GhcPs
parenthesizeExprForOp (LHsExpr GhcPs -> LHsExpr GhcPs) -> LHsExpr GhcPs -> LHsExpr GhcPs
forall a b. (a -> b) -> a -> b
$ HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsExpr'
y)
    HsExpr'
x @@ :: HsExpr' -> HsExpr' -> HsExpr'
@@ HsExpr'
y = (EpAnn NoEpAnns
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
 -> HsExpr')
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> HsExpr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XApp GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs -> HsExpr'
EpAnn NoEpAnns
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
-> HsExpr'
forall p. XApp p -> LHsExpr p -> LHsExpr p -> HsExpr p
HsApp (LHsExpr GhcPs -> LHsExpr GhcPs
parenthesizeExprForOp (LHsExpr GhcPs -> LHsExpr GhcPs) -> LHsExpr GhcPs -> LHsExpr GhcPs
forall a b. (a -> b) -> a -> b
$ HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsExpr'
x)
                (LHsExpr GhcPs -> LHsExpr GhcPs
parenthesizeExprForApp (LHsExpr GhcPs -> LHsExpr GhcPs) -> LHsExpr GhcPs -> LHsExpr GhcPs
forall a b. (a -> b) -> a -> b
$ HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsExpr'
y)

instance App HsType' where
    op :: HsType' -> RdrNameStr -> HsType' -> HsType'
op HsType'
x RdrNameStr
o HsType'
y
#if MIN_VERSION_ghc(9,4,0)
        = (EpAnn [AddEpAnn]
 -> PromotionFlag
 -> GenLocated (SrcSpanAnn AnnListItem) HsType'
 -> LocatedN RdrName
 -> GenLocated (SrcSpanAnn AnnListItem) HsType'
 -> HsType')
-> PromotionFlag
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> LocatedN RdrName
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> HsType'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XOpTy GhcPs
-> PromotionFlag
-> LHsType GhcPs
-> LIdP GhcPs
-> LHsType GhcPs
-> HsType'
EpAnn [AddEpAnn]
-> PromotionFlag
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> LocatedN RdrName
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> HsType'
forall pass.
XOpTy pass
-> PromotionFlag
-> LHsType pass
-> LIdP pass
-> LHsType pass
-> HsType pass
HsOpTy PromotionFlag
notPromoted (LHsType GhcPs -> LHsType GhcPs
parenthesizeTypeForOp (LHsType GhcPs -> LHsType GhcPs) -> LHsType GhcPs -> LHsType GhcPs
forall a b. (a -> b) -> a -> b
$ HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsType'
x)
                (RdrNameStr -> LocatedN RdrName
typeRdrName RdrNameStr
o)
                (LHsType GhcPs -> LHsType GhcPs
parenthesizeTypeForOp (LHsType GhcPs -> LHsType GhcPs) -> LHsType GhcPs -> LHsType GhcPs
forall a b. (a -> b) -> a -> b
$ HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsType'
y)
#else
        = noExt HsOpTy (parenthesizeTypeForOp $ mkLocated x)
                (typeRdrName o)
                (parenthesizeTypeForOp $ mkLocated y)
#endif
    HsType'
x @@ :: HsType' -> HsType' -> HsType'
@@ HsType'
y = (NoExtField
 -> GenLocated (SrcSpanAnn AnnListItem) HsType'
 -> GenLocated (SrcSpanAnn AnnListItem) HsType'
 -> HsType')
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> HsType'
forall a. (NoExtField -> a) -> a
noExt XAppTy GhcPs -> LHsType GhcPs -> LHsType GhcPs -> HsType'
NoExtField
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> GenLocated (SrcSpanAnn AnnListItem) HsType'
-> HsType'
forall pass.
XAppTy pass -> LHsType pass -> LHsType pass -> HsType pass
HsAppTy
                (LHsType GhcPs -> LHsType GhcPs
parenthesizeTypeForOp (LHsType GhcPs -> LHsType GhcPs) -> LHsType GhcPs -> LHsType GhcPs
forall a b. (a -> b) -> a -> b
$ HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsType'
x)
                (LHsType GhcPs -> LHsType GhcPs
parenthesizeTypeForApp (LHsType GhcPs -> LHsType GhcPs) -> LHsType GhcPs -> LHsType GhcPs
forall a b. (a -> b) -> a -> b
$ HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated HsType'
y)

class HasTuple e where
    unit :: e
    tupleOf :: Boxity -> [e] -> e

tuple, unboxedTuple :: HasTuple e => [e] -> e
tuple :: forall e. HasTuple e => [e] -> e
tuple = Boxity -> [e] -> e
forall e. HasTuple e => Boxity -> [e] -> e
tupleOf Boxity
Boxed
unboxedTuple :: forall e. HasTuple e => [e] -> e
unboxedTuple = Boxity -> [e] -> e
forall e. HasTuple e => Boxity -> [e] -> e
tupleOf Boxity
Unboxed

instance HasTuple HsExpr' where
    tupleOf :: Boxity -> [HsExpr'] -> HsExpr'
tupleOf Boxity
b [HsExpr']
ts =
        [HsTupArg GhcPs] -> Boxity -> HsExpr'
explicitTuple
            ((HsExpr' -> HsTupArg GhcPs) -> [HsExpr'] -> [HsTupArg GhcPs]
forall a b. (a -> b) -> [a] -> [b]
map ((EpAnn [AddEpAnn]
 -> GenLocated (SrcSpanAnn AnnListItem) HsExpr' -> HsTupArg GhcPs)
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr' -> HsTupArg GhcPs
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XPresent GhcPs -> LHsExpr GhcPs -> HsTupArg GhcPs
EpAnn [AddEpAnn]
-> GenLocated (SrcSpanAnn AnnListItem) HsExpr' -> HsTupArg GhcPs
forall id. XPresent id -> LHsExpr id -> HsTupArg id
Present (GenLocated (SrcSpanAnn AnnListItem) HsExpr' -> HsTupArg GhcPs)
-> (HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr')
-> HsExpr'
-> HsTupArg GhcPs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated) [HsExpr']
ts)
            Boxity
b
      where
#if MIN_VERSION_ghc(9,2,0)
        explicitTuple :: [HsTupArg GhcPs] -> Boxity -> HsExpr'
explicitTuple = (EpAnn [AddEpAnn] -> [HsTupArg GhcPs] -> Boxity -> HsExpr')
-> [HsTupArg GhcPs] -> Boxity -> HsExpr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XExplicitTuple GhcPs -> [HsTupArg GhcPs] -> Boxity -> HsExpr'
EpAnn [AddEpAnn] -> [HsTupArg GhcPs] -> Boxity -> HsExpr'
forall p. XExplicitTuple p -> [HsTupArg p] -> Boxity -> HsExpr p
ExplicitTuple
#else
        explicitTuple = noExt ExplicitTuple . map builtLoc
#endif
    unit :: HsExpr'
unit = (NoExtField -> LocatedN RdrName -> HsExpr')
-> LocatedN RdrName -> HsExpr'
forall a. (NoExtField -> a) -> a
noExt XVar GhcPs -> LIdP GhcPs -> HsExpr'
NoExtField -> LocatedN RdrName -> HsExpr'
forall p. XVar p -> LIdP p -> HsExpr p
HsVar LIdP GhcPs
LocatedN RdrName
unitDataConName

unitDataConName :: LIdP
unitDataConName :: LIdP GhcPs
unitDataConName = RdrName -> LocatedN RdrName
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated (RdrName -> LocatedN RdrName) -> RdrName -> LocatedN RdrName
forall a b. (a -> b) -> a -> b
$ Name -> RdrName
nameRdrName (Name -> RdrName) -> Name -> RdrName
forall a b. (a -> b) -> a -> b
$ DataCon -> Name
dataConName (DataCon -> Name) -> DataCon -> Name
forall a b. (a -> b) -> a -> b
$ DataCon
unitDataCon

instance HasTuple HsType' where
    tupleOf :: Boxity -> [HsType'] -> HsType'
tupleOf Boxity
b = (EpAnn AnnParen
 -> HsTupleSort
 -> [GenLocated (SrcSpanAnn AnnListItem) HsType']
 -> HsType')
-> HsTupleSort
-> [GenLocated (SrcSpanAnn AnnListItem) HsType']
-> HsType'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XTupleTy GhcPs -> HsTupleSort -> [LHsType GhcPs] -> HsType'
EpAnn AnnParen
-> HsTupleSort
-> [GenLocated (SrcSpanAnn AnnListItem) HsType']
-> HsType'
forall pass.
XTupleTy pass -> HsTupleSort -> [LHsType pass] -> HsType pass
HsTupleTy HsTupleSort
b' ([GenLocated (SrcSpanAnn AnnListItem) HsType'] -> HsType')
-> ([HsType'] -> [GenLocated (SrcSpanAnn AnnListItem) HsType'])
-> [HsType']
-> HsType'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType')
-> [HsType'] -> [GenLocated (SrcSpanAnn AnnListItem) HsType']
forall a b. (a -> b) -> [a] -> [b]
map HsType' -> GenLocated (SrcSpanAnn AnnListItem) HsType'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated
        where
            b' :: HsTupleSort
b' = case Boxity
b of
                    Boxity
Unboxed -> HsTupleSort
HsUnboxedTuple
                    -- See the note [Unit tuples] in HsType.hs for why
                    -- this isn't just HsBoxed.
                    Boxity
Boxed -> HsTupleSort
HsBoxedOrConstraintTuple
    unit :: HsType'
unit = Boxity -> [HsType'] -> HsType'
forall e. HasTuple e => Boxity -> [e] -> e
tupleOf Boxity
Boxed []

instance HasTuple Pat' where
    tupleOf :: Boxity -> [Pat'] -> Pat'
tupleOf Boxity
b [Pat']
ps =
        (EpAnn [AddEpAnn]
 -> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Boxity -> Pat')
-> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Boxity -> Pat'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XTuplePat GhcPs -> [LPat GhcPs] -> Boxity -> Pat'
EpAnn [AddEpAnn]
-> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Boxity -> Pat'
forall p. XTuplePat p -> [LPat p] -> Boxity -> Pat p
TuplePat ((Pat' -> GenLocated (SrcSpanAnn AnnListItem) Pat')
-> [Pat'] -> [GenLocated (SrcSpanAnn AnnListItem) Pat']
forall a b. (a -> b) -> [a] -> [b]
map Pat' -> LPat GhcPs
Pat' -> GenLocated (SrcSpanAnn AnnListItem) Pat'
builtPat [Pat']
ps) Boxity
b
#if !MIN_VERSION_ghc(8,6,0)
        []
#endif
    unit :: Pat'
unit = (NoExtField -> LocatedN RdrName -> Pat')
-> LocatedN RdrName -> Pat'
forall a. (NoExtField -> a) -> a
noExt XVarPat GhcPs -> LIdP GhcPs -> Pat'
NoExtField -> LocatedN RdrName -> Pat'
forall p. XVarPat p -> LIdP p -> Pat p
VarPat LIdP GhcPs
LocatedN RdrName
unitDataConName

-- | An explicit list of terms.
--
-- > [x, y]
-- > =====
-- > list [var "x", var "y"]
--
-- NOTE: for types, use either @listTy@ or @promotedListTy@.
class HasList e where
    list :: [e] -> e
    -- | The empty list @[]@.
    nil :: e

    -- | The list cons constructor @(:)@.
    cons :: e

-- TODO: allow something like "consOp" which applies (:) as an operator, but using
-- the built-in RdrName.

nilDataConName :: LIdP
nilDataConName :: LIdP GhcPs
nilDataConName = RdrName -> LocatedN RdrName
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated (RdrName -> LocatedN RdrName) -> RdrName -> LocatedN RdrName
forall a b. (a -> b) -> a -> b
$ Name -> RdrName
nameRdrName (Name -> RdrName) -> Name -> RdrName
forall a b. (a -> b) -> a -> b
$ DataCon -> Name
dataConName (DataCon -> Name) -> DataCon -> Name
forall a b. (a -> b) -> a -> b
$ DataCon
nilDataCon

instance HasList HsExpr' where
    list :: [HsExpr'] -> HsExpr'
list = ([GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr')
-> [GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr'
forall a. a -> a
withPlaceHolder ((EpAnn AnnList
 -> [GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr')
-> [GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XExplicitList GhcPs -> [LHsExpr GhcPs] -> HsExpr'
EpAnn AnnList
-> [GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr'
forall {p}. XExplicitList p -> [XRec p (HsExpr p)] -> HsExpr p
explicitList) ([GenLocated (SrcSpanAnn AnnListItem) HsExpr'] -> HsExpr')
-> ([HsExpr'] -> [GenLocated (SrcSpanAnn AnnListItem) HsExpr'])
-> [HsExpr']
-> HsExpr'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr')
-> [HsExpr'] -> [GenLocated (SrcSpanAnn AnnListItem) HsExpr']
forall a b. (a -> b) -> [a] -> [b]
map HsExpr' -> GenLocated (SrcSpanAnn AnnListItem) HsExpr'
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated
      where
#if MIN_VERSION_ghc(9,2,0)
        explicitList :: XExplicitList p -> [XRec p (HsExpr p)] -> HsExpr p
explicitList = XExplicitList p -> [XRec p (HsExpr p)] -> HsExpr p
forall {p}. XExplicitList p -> [XRec p (HsExpr p)] -> HsExpr p
ExplicitList
#else
        explicitList x = ExplicitList x Nothing
#endif
    nil :: HsExpr'
nil = (NoExtField -> LocatedN RdrName -> HsExpr')
-> LocatedN RdrName -> HsExpr'
forall a. (NoExtField -> a) -> a
noExt XVar GhcPs -> LIdP GhcPs -> HsExpr'
NoExtField -> LocatedN RdrName -> HsExpr'
forall p. XVar p -> LIdP p -> HsExpr p
HsVar LIdP GhcPs
LocatedN RdrName
nilDataConName
    cons :: HsExpr'
cons = (NoExtField -> LocatedN RdrName -> HsExpr')
-> LocatedN RdrName -> HsExpr'
forall a. (NoExtField -> a) -> a
noExt XVar GhcPs -> LIdP GhcPs -> HsExpr'
NoExtField -> LocatedN RdrName -> HsExpr'
forall p. XVar p -> LIdP p -> HsExpr p
HsVar (LocatedN RdrName -> HsExpr') -> LocatedN RdrName -> HsExpr'
forall a b. (a -> b) -> a -> b
$ RdrName -> LocatedN RdrName
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated RdrName
consDataCon_RDR

instance HasList Pat' where
#if MIN_VERSION_ghc(8,6,0)
    list :: [Pat'] -> Pat'
list = (EpAnn AnnList
 -> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Pat')
-> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Pat'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XListPat GhcPs -> [LPat GhcPs] -> Pat'
EpAnn AnnList -> [GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Pat'
forall p. XListPat p -> [LPat p] -> Pat p
ListPat ([GenLocated (SrcSpanAnn AnnListItem) Pat'] -> Pat')
-> ([Pat'] -> [GenLocated (SrcSpanAnn AnnListItem) Pat'])
-> [Pat']
-> Pat'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pat' -> GenLocated (SrcSpanAnn AnnListItem) Pat')
-> [Pat'] -> [GenLocated (SrcSpanAnn AnnListItem) Pat']
forall a b. (a -> b) -> [a] -> [b]
map Pat' -> LPat GhcPs
Pat' -> GenLocated (SrcSpanAnn AnnListItem) Pat'
builtPat
#else
    list ps = ListPat (map builtPat ps) PlaceHolder Nothing
#endif
    nil :: Pat'
nil = (NoExtField -> LocatedN RdrName -> Pat')
-> LocatedN RdrName -> Pat'
forall a. (NoExtField -> a) -> a
noExt XVarPat GhcPs -> LIdP GhcPs -> Pat'
NoExtField -> LocatedN RdrName -> Pat'
forall p. XVarPat p -> LIdP p -> Pat p
VarPat LIdP GhcPs
LocatedN RdrName
nilDataConName
    cons :: Pat'
cons = (NoExtField -> LocatedN RdrName -> Pat')
-> LocatedN RdrName -> Pat'
forall a. (NoExtField -> a) -> a
noExt XVarPat GhcPs -> LIdP GhcPs -> Pat'
NoExtField -> LocatedN RdrName -> Pat'
forall p. XVarPat p -> LIdP p -> Pat p
VarPat (LocatedN RdrName -> Pat') -> LocatedN RdrName -> Pat'
forall a b. (a -> b) -> a -> b
$ RdrName -> LocatedN RdrName
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated (RdrName -> LocatedN RdrName) -> RdrName -> LocatedN RdrName
forall a b. (a -> b) -> a -> b
$ RdrName
consDataCon_RDR

-- | Terms that can contain references to locally-bound variables.
--
-- Depending on the context, @'bvar' \"a\"@ could refer to either a
-- pattern variable or a type variable.
class BVar a where
    bvar :: OccNameStr -> a

-- | Terms that can contain references to named things.  They may be actual variables,
-- functions, or constructors.  For example, @'var' \"a\"@ and @'var' \"A\"@
-- are equally valid.
-- Depending on the context, the former could refer to either a function,
-- value, type variable, or pattern; and the latter could refer to either a type
-- constructor or a  data constructor,
class BVar a => Var a where
    var :: RdrNameStr -> a

instance BVar Pat' where
    bvar :: OccNameStr -> Pat'
bvar = (NoExtField -> LocatedN RdrName -> Pat')
-> LocatedN RdrName -> Pat'
forall a. (NoExtField -> a) -> a
noExt XVarPat GhcPs -> LIdP GhcPs -> Pat'
NoExtField -> LocatedN RdrName -> Pat'
forall p. XVarPat p -> LIdP p -> Pat p
VarPat (LocatedN RdrName -> Pat')
-> (OccNameStr -> LocatedN RdrName) -> OccNameStr -> Pat'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrNameStr -> LocatedN RdrName
valueRdrName (RdrNameStr -> LocatedN RdrName)
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> LocatedN RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr

instance Var HsExpr' where
    var :: RdrNameStr -> HsExpr'
var = (NoExtField -> LocatedN RdrName -> HsExpr')
-> LocatedN RdrName -> HsExpr'
forall a. (NoExtField -> a) -> a
noExt XVar GhcPs -> LIdP GhcPs -> HsExpr'
NoExtField -> LocatedN RdrName -> HsExpr'
forall p. XVar p -> LIdP p -> HsExpr p
HsVar (LocatedN RdrName -> HsExpr')
-> (RdrNameStr -> LocatedN RdrName) -> RdrNameStr -> HsExpr'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrNameStr -> LocatedN RdrName
valueRdrName

instance BVar HsExpr' where
    bvar :: OccNameStr -> HsExpr'
bvar = RdrNameStr -> HsExpr'
forall a. Var a => RdrNameStr -> a
var (RdrNameStr -> HsExpr')
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> HsExpr'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr

instance Var HsType' where
    var :: RdrNameStr -> HsType'
var = (EpAnn [AddEpAnn] -> PromotionFlag -> LocatedN RdrName -> HsType')
-> PromotionFlag -> LocatedN RdrName -> HsType'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XTyVar GhcPs -> PromotionFlag -> LIdP GhcPs -> HsType'
EpAnn [AddEpAnn] -> PromotionFlag -> LocatedN RdrName -> HsType'
forall pass.
XTyVar pass -> PromotionFlag -> LIdP pass -> HsType pass
HsTyVar PromotionFlag
notPromoted (LocatedN RdrName -> HsType')
-> (RdrNameStr -> LocatedN RdrName) -> RdrNameStr -> HsType'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrNameStr -> LocatedN RdrName
typeRdrName

instance BVar HsType' where
    bvar :: OccNameStr -> HsType'
bvar = RdrNameStr -> HsType'
forall a. Var a => RdrNameStr -> a
var (RdrNameStr -> HsType')
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> HsType'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr

#if MIN_VERSION_ghc(9,0,0)
instance BVar HsTyVarBndr' where
    bvar :: OccNameStr -> HsTyVarBndr'
bvar = (EpAnn [AddEpAnn] -> () -> LocatedN RdrName -> HsTyVarBndr')
-> () -> LocatedN RdrName -> HsTyVarBndr'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XUserTyVar GhcPs -> () -> LIdP GhcPs -> HsTyVarBndr'
EpAnn [AddEpAnn] -> () -> LocatedN RdrName -> HsTyVarBndr'
forall flag pass.
XUserTyVar pass -> flag -> LIdP pass -> HsTyVarBndr flag pass
UserTyVar () (LocatedN RdrName -> HsTyVarBndr')
-> (OccNameStr -> LocatedN RdrName) -> OccNameStr -> HsTyVarBndr'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrNameStr -> LocatedN RdrName
typeRdrName (RdrNameStr -> LocatedN RdrName)
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> LocatedN RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr

instance BVar HsTyVarBndrS' where
    bvar :: OccNameStr -> HsTyVarBndrS'
bvar = (EpAnn [AddEpAnn]
 -> Specificity -> LocatedN RdrName -> HsTyVarBndrS')
-> Specificity -> LocatedN RdrName -> HsTyVarBndrS'
forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed XUserTyVar GhcPs -> Specificity -> LIdP GhcPs -> HsTyVarBndrS'
EpAnn [AddEpAnn]
-> Specificity -> LocatedN RdrName -> HsTyVarBndrS'
forall flag pass.
XUserTyVar pass -> flag -> LIdP pass -> HsTyVarBndr flag pass
UserTyVar Specificity
SpecifiedSpec (LocatedN RdrName -> HsTyVarBndrS')
-> (OccNameStr -> LocatedN RdrName) -> OccNameStr -> HsTyVarBndrS'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrNameStr -> LocatedN RdrName
typeRdrName (RdrNameStr -> LocatedN RdrName)
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> LocatedN RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr
#else
instance BVar HsTyVarBndr' where
    bvar = withEpAnnNotUsed UserTyVar . typeRdrName . UnqualStr
#endif

instance Var IE' where
    var :: RdrNameStr -> IE'
var RdrNameStr
n =
      (NoExtField
 -> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs)
 -> IE')
-> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs) -> IE'
forall a. (NoExtField -> a) -> a
noExt XIEVar GhcPs -> LIEWrappedName GhcPs -> IE'
NoExtField
-> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs) -> IE'
forall pass. XIEVar pass -> LIEWrappedName pass -> IE pass
IEVar (GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs) -> IE')
-> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs) -> IE'
forall a b. (a -> b) -> a -> b
$ IEWrappedName GhcPs
-> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs)
forall a ann. a -> GenLocated (SrcSpanAnn ann) a
mkLocated (IEWrappedName GhcPs
 -> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs))
-> IEWrappedName GhcPs
-> GenLocated (SrcSpanAnn AnnListItem) (IEWrappedName GhcPs)
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_ghc(9,6,0)
      (XIEName GhcPs -> LIdP GhcPs -> IEWrappedName GhcPs
forall p. XIEName p -> LIdP p -> IEWrappedName p
IEName XIEName GhcPs
NoExtField
noExtField)
#else
      IEName
#endif
      (LIdP GhcPs -> IEWrappedName GhcPs)
-> LIdP GhcPs -> IEWrappedName GhcPs
forall a b. (a -> b) -> a -> b
$ RdrNameStr -> LocatedN RdrName
exportRdrName RdrNameStr
n

instance BVar IE' where
    bvar :: OccNameStr -> IE'
bvar = RdrNameStr -> IE'
forall a. Var a => RdrNameStr -> a
var (RdrNameStr -> IE')
-> (OccNameStr -> RdrNameStr) -> OccNameStr -> IE'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccNameStr -> RdrNameStr
UnqualStr