proto3-suite-0.9.4: src/Proto3/Suite/DotProto/Generate/Syntax.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NegativeLiterals #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
{-| Utilities to manipulate Haskell AST -}
module Proto3.Suite.DotProto.Generate.Syntax where
import Data.Functor ((<&>))
import Data.Maybe (maybeToList)
#if !MIN_VERSION_ghc_lib_parser(9,12,0)
import GHC.Data.Bag (listToBag)
#endif
import GHC.Data.FastString (mkFastString)
import qualified GHC.Hs as GHC
(HsDecl(..), HsDerivingClause(..), HsModule(..), HsTyVarBndr(..), HsType(..))
import GHC.Types.Basic (Origin(..))
import GHC.Types.Name.Occurrence (NameSpace, dataName, mkOccName, tcName, tvName, varName)
import GHC.Types.Name.Reader (mkRdrQual, mkRdrUnqual, rdrNameSpace)
import GHC.Types.SrcLoc (GenLocated(..), SrcSpan, generatedSrcSpan)
#if MIN_VERSION_ghc_lib_parser(9,10,0)
import GHC.Types.Basic (GenReason(OtherExpansion))
#endif
#if MIN_VERSION_ghc_lib_parser(9,8,0)
import Control.Arrow ((***))
import Data.Bool (bool)
import Data.Ratio ((%))
import Data.Void (Void)
import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,
HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)
import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)
import GHC.Types.Basic (DoPmc(..), TopLevelFlag(..))
import GHC.Types.Fixity (LexicalFixity(..))
import GHC.Types.PkgQual (RawPkgQual(..))
import GHC.Types.SourceText
(IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))
#elif MIN_VERSION_ghc_lib_parser(9,6,0)
import Control.Arrow ((***))
import Data.Bool (bool)
import Data.Ratio ((%))
import Data.Void (Void)
import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,
HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)
import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)
import GHC.Types.Basic (TopLevelFlag(..))
import GHC.Types.Fixity (LexicalFixity(..))
import GHC.Types.PkgQual (RawPkgQual(..))
import GHC.Types.SourceText
(IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))
#elif MIN_VERSION_ghc_lib_parser(9,4,0)
import Data.Ratio ((%))
import Data.Void (Void)
import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,
HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)
import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)
import GHC.Types.Basic (PromotionFlag(..), TopLevelFlag(..))
import GHC.Types.Fixity (LexicalFixity(..))
import GHC.Types.PkgQual (RawPkgQual(..))
import GHC.Types.SourceText
(IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))
import GHC.Types.SrcLoc (LayoutInfo(..))
import GHC.Unit (IsBootInterface(..))
import GHC.Unit.Module (ModuleName, mkModuleName)
#else
import Data.Ratio ((%))
import Data.Void (Void)
import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,
HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)
import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)
import GHC.Types.Basic (PromotionFlag(..), TopLevelFlag(..))
import GHC.Types.Fixity (LexicalFixity(..))
import GHC.Types.SourceText
(IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))
import GHC.Types.SrcLoc (LayoutInfo(..), noLoc)
import GHC.Unit (IsBootInterface(..))
import GHC.Unit.Module (ModuleName, mkModuleName)
#endif
#if MIN_VERSION_base(4,16,0)
import GHC.Exts (considerAccessible)
#endif
type HsAlt = LMatch GhcPs HsExp
type HsBangType = LBangType GhcPs
type HsBind = LHsBind GhcPs
type HsConDecl = LConDecl GhcPs
type HsDecl = LHsDecl GhcPs
type HsDerivStrategy = LDerivStrategy GhcPs
type HsDerivingClause = LHsDerivingClause GhcPs
type HsExp = LHsExpr GhcPs
type HsExportSpec = LIE GhcPs
type HsGrhs = LGRHS GhcPs HsExp
type HsGuardedAlts = GRHSs GhcPs HsExp
type HsImportDecl = LImportDecl GhcPs
type HsImportSpec = LIE GhcPs
type HsMatch = LMatch GhcPs HsExp
type HsName = LIdP GhcPs
type HsOuterFamEqnTyVarBndrs = GHC.HsOuterFamEqnTyVarBndrs GhcPs
type HsOuterSigTyVarBndrs = GHC.HsOuterSigTyVarBndrs GhcPs
type HsPat = LPat GhcPs
type HsQName = LIdP GhcPs
type HsQOp = LHsExpr GhcPs
type HsSig = LSig GhcPs
type HsTyVarBndrU = LHsTyVarBndr () GhcPs
type HsTyVarBndrV = LHsTyVarBndr
#if MIN_VERSION_ghc_lib_parser(9,8,0)
(HsBndrVis GhcPs)
#else
()
#endif
GhcPs
type HsType = LHsType GhcPs
type Module = ModuleName
#if MIN_VERSION_ghc_lib_parser(9,10,0)
pattern VirtualBraces :: Int -> EpLayout
pattern VirtualBraces indentation = EpVirtualBraces indentation
#endif
class SyntaxDefault a
where
synDef :: a
instance SyntaxDefault ()
where
synDef = ()
instance (SyntaxDefault a, SyntaxDefault b, SyntaxDefault c) => SyntaxDefault (a, b, c)
where
synDef = (synDef, synDef, synDef)
instance SyntaxDefault (Maybe a)
where
synDef = Nothing
instance SyntaxDefault [a]
where
synDef = []
instance (SyntaxDefault a, SyntaxDefault b) => SyntaxDefault (a, b)
where
synDef = (synDef, synDef)
instance SyntaxDefault NoExtField
where
synDef = NoExtField
instance SyntaxDefault SourceText
where
synDef = NoSourceText
instance SyntaxDefault SrcSpan
where
synDef = generatedSrcSpan
#if MIN_VERSION_ghc_lib_parser(9,10,0)
instance SyntaxDefault AnnParen
where
synDef = noAnn
instance SyntaxDefault AnnPragma
where
synDef = noAnn
instance SyntaxDefault AnnSig
where
synDef = noAnn
instance SyntaxDefault AnnsIf
where
synDef = noAnn
instance SyntaxDefault (AnnSortKey tag)
where
synDef = NoAnnSortKey
instance NoAnn a => SyntaxDefault (EpAnn a)
where
synDef = noAnn
instance SyntaxDefault EpAnnHsCase
where
synDef = noAnn
instance SyntaxDefault (EpToken token)
where
synDef = NoEpTok
instance SyntaxDefault (EpUniToken token utoken)
where
synDef = NoEpUniTok
instance SyntaxDefault (HsBndrVis GhcPs)
where
synDef = HsBndrRequired synDef
#endif
#if MIN_VERSION_ghc_lib_parser(9,8,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)
instance SyntaxDefault (HsBndrVis GhcPs)
where
synDef = HsBndrRequired
#endif
#if MIN_VERSION_ghc_lib_parser(9,4,0)
instance SyntaxDefault a => SyntaxDefault (GenLocated TokenLocation a)
where
synDef = L NoTokenLoc synDef
#endif
#if MIN_VERSION_ghc_lib_parser(9,4,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)
instance SyntaxDefault (SrcAnn a)
where
synDef = noSrcSpanA
instance SyntaxDefault (HsToken tok)
where
synDef = HsTok
instance SyntaxDefault (HsUniToken tok utok)
where
synDef = HsNormalTok
#else
instance SyntaxDefault IsUnicodeSyntax
where
synDef = NormalSyntax
#endif
pattern PfxCon :: [arg] -> HsConDetails Void arg r
pattern PfxCon args = PrefixCon [] args
#if !MIN_VERSION_ghc_lib_parser(9,10,0)
instance SyntaxDefault e => SyntaxDefault (GenLocated (SrcAnn a) e)
where
synDef = noLocA synDef
instance SyntaxDefault (EpAnn a)
where
synDef = EpAnnNotUsed
instance SyntaxDefault EpAnnComments
where
synDef = emptyComments
instance SyntaxDefault AnnSortKey
where
synDef = NoAnnSortKey
#endif
#if !MIN_VERSION_ghc_lib_parser(9,4,0)
dataConCantHappen :: NoExtCon -> a
dataConCantHappen = noExtCon
#endif
haskellName, jsonpbName, grpcName, lrName, protobufName,
protobufASTName, protobufFormName, proxyName ::
NameSpace -> String -> HsQName
haskellName = qual_ haskellNS
jsonpbName = qual_ (mkModuleName "HsJSONPB")
grpcName = qual_ (mkModuleName "HsGRPC")
lrName = qual_ (mkModuleName "LR")
protobufName = qual_ (mkModuleName "HsProtobuf")
protobufASTName = qual_ (mkModuleName "HsProtobufAST")
protobufFormName = qual_ protobufFormNS
proxyName = qual_ (mkModuleName "Proxy")
haskellNS :: ModuleName
haskellNS = mkModuleName "Hs"
protobufFormNS :: ModuleName
protobufFormNS = mkModuleName "HsProtobufForm"
protobufFormType :: NameSpace -> String -> HsType
protobufFormType ns = typeNamed_ . protobufFormName ns
formProtoTypeT :: HsType
formProtoTypeT = protobufFormType tcName "ProtoType"
formNamesOf, formNumberOf, formOneOfOf, formCardinalityOf, formProtoTypeOf :: HsQName
formNamesOf = protobufFormName tcName "NamesOf"
formNumberOf = protobufFormName tcName "NumberOf"
formOneOfOf = protobufFormName tcName "OneOfOf"
formCardinalityOf = protobufFormName tcName "CardinalityOf"
formProtoTypeOf = protobufFormName tcName "ProtoTypeOf"
formFieldNotFound, formFieldOrOneOfNotFound :: HsType
formFieldNotFound = protobufFormType tcName "FieldNotFound"
formFieldOrOneOfNotFound = protobufFormType tcName "FieldOrOneOfNotFound"
formUnpackedT, formPackedT :: HsType
formUnpackedT = protobufFormType dataName "Unpacked"
formPackedT = protobufFormType dataName "Packed"
formCardinalityT, formImplicitT, formOptionalT, formRepeatedT :: HsType
formCardinalityT = protobufFormType tcName "Cardinality"
formImplicitT = protobufFormType dataName "Implicit"
formOptionalT = protobufFormType dataName "Optional"
formRepeatedT = protobufFormType dataName "Repeated"
formInt32T, formInt64T, formSInt32T, formSInt64T, formUInt32T, formUInt64T,
formFixed32T, formFixed64T, formSFixed32T, formSFixed64T,
formStringT, formBytesT, formBoolT, formFloatT, formDoubleT,
formEnumerationT, formMessageT, formMapT :: HsType
formInt32T = protobufFormType dataName "Int32"
formInt64T = protobufFormType dataName "Int64"
formSInt32T = protobufFormType dataName "SInt32"
formSInt64T = protobufFormType dataName "SInt64"
formUInt32T = protobufFormType dataName "UInt32"
formUInt64T = protobufFormType dataName "UInt64"
formFixed32T = protobufFormType dataName "Fixed32"
formFixed64T = protobufFormType dataName "Fixed64"
formSFixed32T = protobufFormType dataName "SFixed32"
formSFixed64T = protobufFormType dataName "SFixed64"
formStringT = protobufFormType dataName "String"
formBytesT = protobufFormType dataName "Bytes"
formBoolT = protobufFormType dataName "Bool"
formFloatT = protobufFormType dataName "Float"
formDoubleT = protobufFormType dataName "Double"
formEnumerationT = protobufFormType dataName "Enumeration"
formMessageT = protobufFormType dataName "Message"
formMapT = protobufFormType dataName "Map"
formWrapperT :: HsType
formWrapperT = protobufFormType tcName "Wrapper"
--------------------------------------------------------------------------------
--
-- * Wrappers around ghc constructors
--
app :: HsExp -> HsExp -> HsExp
app f x = mkHsApp f (paren x)
apply :: HsExp -> [HsExp] -> HsExp
apply f xs = mkHsApps f (map paren xs)
appAt :: HsExp -> HsType -> HsExp
appAt f t = noLocA (HsAppType synDef f
#if MIN_VERSION_ghc_lib_parser(9,6,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)
synDef
#endif
(HsWC NoExtField (parenTy t)))
applyAt :: HsExp -> [HsType] -> HsExp
applyAt f = paren . foldl appAt f
opApp :: HsExp -> HsQOp -> HsExp -> HsExp
opApp x op y = noLocA $ OpApp synDef x op y
maybeModify :: HsExp -> Maybe HsExp -> HsExp
maybeModify x Nothing = x
maybeModify x (Just f) = paren (app f x)
paren :: HsExp -> HsExp
paren = mkLHsPar
parenPat :: HsPat -> HsPat
parenPat = mkParPat
parenTy :: HsType -> HsType
parenTy t@(L _ (GHC.HsParTy {})) = t
parenTy t@(L _ (GHC.HsTyVar {})) = t
parenTy t@(L _ (GHC.HsTupleTy {})) = t
parenTy t = nlHsParTy t
applicativeApply :: HsExp -> [HsExp] -> HsExp
applicativeApply f = foldl snoc nil
where
nil = apply pureE [f]
snoc g x = noLocA (OpApp synDef g apOp x)
tyApp :: HsType -> HsType -> HsType
tyApp f = parenTy . mkHsAppTy (parenTy f) . parenTy
tyApply :: HsType -> [HsType] -> HsType
tyApply = foldl tyApp
-- | Whenever @f@ is not itself a type application,
-- @'splitTyApp' ('tyApply' f as) = (f, as)@.
splitTyApp :: HsType -> (HsType, [HsType])
splitTyApp (L _ (GHC.HsParTy _ x)) = splitTyApp x
splitTyApp (L _ (GHC.HsAppTy NoExtField x y)) = (++ [y]) <$> splitTyApp x
splitTyApp x = (x, [])
tyConApp :: HsName -> HsType -> HsType
tyConApp = tyApp . typeNamed_
tyConApply :: HsName -> [HsType] -> HsType
tyConApply = tyApply . typeNamed_
-- | @'splitTyConApp' ('tyApply' (L _ (GHC.HsTyVar _ NotPromoted tc)) as) = Just (tc, as)@.
splitTyConApp :: HsType -> Maybe (HsName, [HsType])
splitTyConApp x = case splitTyApp x of
(L _ (GHC.HsTyVar _ NotPromoted tc), as) -> Just (tc, as)
_ -> Nothing
funTy :: HsType -> HsType -> HsType
funTy a b = noLocA (GHC.HsFunTy synDef unrestrictedArrow_ a b)
unrestrictedArrow_ :: HsArrow GhcPs
unrestrictedArrow_ = HsUnrestrictedArrow synDef
unbangedTy_ :: HsType -> HsBangType
#if MIN_VERSION_ghc_lib_parser(9,12,0)
unbangedTy_ = noLocA . GHC.HsBangTy noAnn (HsBang NoSrcUnpack NoSrcStrict) . parenTy
#else
unbangedTy_ = noLocA . GHC.HsBangTy synDef (HsSrcBang synDef NoSrcUnpack NoSrcStrict) . parenTy
#endif
#if MIN_VERSION_ghc_lib_parser(9,6,0)
-- https://hackage.haskell.org/package/ghc-lib-parser-9.6.2.20231121/docs/GHC-Hs.html#t:HsModule
module_ :: ModuleName -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> GHC.HsModule GhcPs
module_ moduleName maybeExports imports decls =
GHC.HsModule
{ hsmodExt = XModulePs
{ hsmodAnn = synDef
, hsmodLayout = VirtualBraces 2
, hsmodDeprecMessage = Nothing
, hsmodHaddockModHeader = Nothing
}
, hsmodName = Just $ noLocA moduleName
, hsmodExports = noLocA <$> maybeExports
, hsmodImports = imports
, hsmodDecls = decls
}
#else
-- https://hackage.haskell.org/package/ghc-lib-parser-9.2.2.20220307/docs/GHC-Hs.html#t:HsModule
module_ :: ModuleName -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> GHC.HsModule
module_ moduleName maybeExports imports decls =
GHC.HsModule
{ hsmodAnn = synDef
, hsmodLayout = VirtualBraces 2
, hsmodName = Just $ noLocA moduleName
, hsmodExports = noLocA <$> maybeExports
, hsmodImports = imports
, hsmodDecls = decls
, hsmodDeprecMessage = Nothing
, hsmodHaddockModHeader = Nothing
}
#endif
importDecl_ ::
ModuleName ->
Bool ->
Maybe ModuleName ->
Maybe (Bool, [HsImportSpec]) ->
HsImportDecl
importDecl_ moduleName qualified maybeAs details = noLocA ImportDecl
{
#if MIN_VERSION_ghc_lib_parser(9,6,0)
ideclExt = XImportDeclPass
{ ideclAnn = synDef
, ideclSourceText = synDef
, ideclImplicit = False
}
#else
ideclExt = synDef
, ideclSourceSrc = NoSourceText
#endif
, ideclName = noLocA moduleName
, ideclPkgQual =
#if MIN_VERSION_ghc_lib_parser(9,4,0)
NoRawPkgQual
#else
Nothing
#endif
, ideclSource = NotBoot
, ideclSafe = False
, ideclQualified = if qualified then QualifiedPre else NotQualified
#if !MIN_VERSION_ghc_lib_parser(9,6,0)
, ideclImplicit = False
#endif
, ideclAs = noLocA <$> maybeAs
#if MIN_VERSION_ghc_lib_parser(9,6,0)
, ideclImportList = (bool Exactly EverythingBut *** noLocA) <$> details
#else
, ideclHiding = fmap noLocA <$> details
#endif
}
ieName_ :: HsName -> HsImportSpec
ieName_ =
noLocA .
#if MIN_VERSION_ghc_lib_parser(9,10,0)
flip (IEVar synDef) Nothing .
#else
IEVar synDef .
#endif
noLocA .
IEName
#if MIN_VERSION_ghc_lib_parser(9,6,0)
synDef
#endif
ieNameAll_ :: HsName -> HsImportSpec
ieNameAll_ =
noLocA .
#if MIN_VERSION_ghc_lib_parser(9,10,0)
flip (IEThingAll synDef) Nothing .
#else
(IEThingAll synDef) .
#endif
noLocA .
IEName
#if MIN_VERSION_ghc_lib_parser(9,6,0)
synDef
#endif
dataDecl_ :: String -> [HsTyVarBndrV] -> [HsConDecl] -> [HsQName] -> HsDecl
dataDecl_ messageName bndrs constructors derivedInstances = noLocA $ GHC.TyClD NoExtField DataDecl
{ tcdDExt = synDef
, tcdLName = unqual_ tcName messageName
, tcdTyVars = HsQTvs NoExtField bndrs
, tcdFixity = Prefix
, tcdDataDefn = HsDataDefn
#if MIN_VERSION_ghc_lib_parser(9,12,0)
{ dd_ext = noAnn
#else
{ dd_ext = NoExtField
#endif
#if !MIN_VERSION_ghc_lib_parser(9,6,0)
, dd_ND = maybe DataType (const NewType) newtypeCtor
#endif
, dd_ctxt = synDef
, dd_cType = Nothing
, dd_kindSig = Nothing
, dd_cons =
#if MIN_VERSION_ghc_lib_parser(9,6,0)
maybe (DataTypeCons False constructors) NewTypeCon newtypeCtor
#else
constructors
#endif
, dd_derivs =
maybeToList $ derivingClause_ Nothing $ derivedInstances <&> \className ->
(implicitOuterSigTyVarBinders_, typeNamed_ className)
}
}
where
-- TO DO: Support GADT syntax, assuming we ever start to use it in generated code.
newtypeCtor = case constructors of
[ con@( L _ ( ConDeclH98 { con_forall = False
, con_ex_tvs = []
, con_mb_cxt = Nothing
, con_args = args
} ) ) ] -> case args of
PfxCon [_] -> Just con
RecCon (L _ [L _ ConDeclField { cd_fld_names = [_] }]) -> Just con
_ -> Nothing
_ -> Nothing
recDecl_ :: HsName -> [([HsName], HsBangType)] -> HsConDecl
recDecl_ name fields = noLocA ConDeclH98
#if MIN_VERSION_ghc_lib_parser(9,12,0)
{ con_ext = noAnn
#else
{ con_ext = synDef
#endif
, con_name = name
, con_forall = False
, con_ex_tvs = []
, con_mb_cxt = Nothing
, con_args = RecCon $ noLocA $ fields <&> \(names, bangTy) -> noLocA ConDeclField
{ cd_fld_ext = synDef
, cd_fld_names =
#if MIN_VERSION_ghc_lib_parser(9,4,0)
noLocA
#else
noLoc
#endif
. FieldOcc NoExtField <$> names
, cd_fld_type = bangTy
, cd_fld_doc = Nothing
}
, con_doc = Nothing
}
conDecl_ :: HsName -> [HsBangType] -> HsConDecl
conDecl_ name fields = noLocA ConDeclH98
#if MIN_VERSION_ghc_lib_parser(9,12,0)
{ con_ext = noAnn
#else
{ con_ext = synDef
#endif
, con_name = name
, con_forall = False
, con_ex_tvs = []
, con_mb_cxt = Nothing
, con_args = PfxCon (HsScaled unrestrictedArrow_ <$> fields)
, con_doc = Nothing
}
derivingClause_ ::
Maybe HsDerivStrategy ->
[(HsOuterSigTyVarBndrs, HsType)] ->
Maybe HsDerivingClause
derivingClause_ _ [] = Nothing
derivingClause_ strategy classTypes = Just $ L synDef $
GHC.HsDerivingClause
{ GHC.deriv_clause_ext = synDef
, GHC.deriv_clause_strategy = strategy
, GHC.deriv_clause_tys = noLocA $ DctMulti NoExtField $
noLocA . uncurry (HsSig NoExtField) <$> classTypes
}
splitDerivingClause ::
HsDerivingClause ->
(Maybe HsDerivStrategy, [(HsOuterSigTyVarBndrs, HsType)])
splitDerivingClause (L _ GHC.HsDerivingClause
{ GHC.deriv_clause_strategy = strategy
, GHC.deriv_clause_tys = L _ clauseTypes
}) =
case clauseTypes of
DctSingle _ sig -> (strategy, [splitSig sig])
DctMulti _ sigs -> (strategy, map splitSig sigs)
where
splitSig (L _ sig) = case sig of
HsSig _ binders classType -> (binders, classType)
XHsSigType impossible
#if MIN_VERSION_base(4,16,0)
| considerAccessible
-- We use 'considerAccessible' because GHC 9.4.6 will issue the warning
-- "Pattern match is redundant" (-Woverlapping-patterns) if we provide
-- this match *and* use its strict field 'impossible', and yet
-- if we omit this match then GHC 9.4.6 will issue the warning
-- "Pattern match(es) are non-exhaustive" (-Wincomplete-patterns).
-- We cannot avoid the warning without either 'considerAccessible'
-- or avoiding any use of 'impossible', which would require 'error'
-- or similar to handle this impossible case match.
#endif
-> dataConCantHappen impossible
instDecl_ :: HsQName -> [HsType] -> [HsBind] -> HsDecl
instDecl_ className classArgs binds = noLocA $ GHC.InstD NoExtField ClsInstD
{ cid_d_ext = NoExtField
, cid_inst = ClsInstDecl
#if MIN_VERSION_ghc_lib_parser(9,12,0)
{ cid_ext = (Nothing, noAnn, NoAnnSortKey)
#else
{ cid_ext = synDef
#endif
, cid_poly_ty = noLocA $ HsSig NoExtField implicitOuterSigTyVarBinders_ (tyConApply className classArgs)
#if MIN_VERSION_ghc_lib_parser(9,12,0)
, cid_binds = binds
#else
, cid_binds = listToBag binds
#endif
, cid_sigs = []
, cid_tyfam_insts = []
, cid_datafam_insts = []
, cid_overlap_mode = Nothing
}
}
typeOfInstDecl :: HsDecl -> Maybe (HsOuterSigTyVarBndrs, HsType)
typeOfInstDecl ( L _ ( GHC.InstD _ ClsInstD
{ cid_inst = ClsInstDecl
{ cid_poly_ty = L _ (HsSig _ binders classType)
} } ) ) =
Just (binders, classType)
typeOfInstDecl _ =
Nothing
closedTyFamDecl_ ::
HsQName ->
[HsTyVarBndrV] ->
HsType ->
[(Maybe [HsTyVarBndrU], [HsType], HsType)] ->
HsDecl
closedTyFamDecl_ tyFamName famBndrs resultKind eqns =
noLocA $ GHC.TyClD NoExtField $ FamDecl synDef $ FamilyDecl
#if MIN_VERSION_ghc_lib_parser(9,12,0)
{ fdExt = noAnn
#else
{ fdExt = synDef
#endif
, fdInfo = ClosedTypeFamily (Just (map onEqn eqns))
, fdTopLevel = TopLevel
, fdLName = tyFamName
, fdTyVars = HsQTvs synDef famBndrs
, fdFixity = Prefix
, fdResultSig =
#if MIN_VERSION_ghc_lib_parser(9,4,0)
noLocA $
#else
noLoc $
#endif
KindSig synDef resultKind
, fdInjectivityAnn = Nothing
}
where
onEqn (eqnBndrs, pats, rhs) = noLocA $
FamEqn
{ feqn_ext = synDef
, feqn_tycon = tyFamName
, feqn_bndrs = maybe (HsOuterImplicit NoExtField) (HsOuterExplicit synDef) eqnBndrs
, feqn_pats = map
(HsValArg
#if MIN_VERSION_ghc_lib_parser(9,10,0)
synDef
#endif
) pats
, feqn_fixity = Prefix
, feqn_rhs = rhs
}
tyFamInstDecl_ :: HsQName -> Maybe [HsTyVarBndrU] -> [HsType] -> HsType -> HsDecl
tyFamInstDecl_ tyFamName bndrs pats rhs = noLocA $ GHC.InstD NoExtField TyFamInstD
{ tfid_ext = NoExtField
, tfid_inst = TyFamInstDecl
{ tfid_xtn = synDef
, tfid_eqn = FamEqn
{ feqn_ext = synDef
, feqn_tycon = tyFamName
, feqn_bndrs = maybe (HsOuterImplicit NoExtField) (HsOuterExplicit synDef) bndrs
, feqn_pats = map
(HsValArg
#if MIN_VERSION_ghc_lib_parser(9,10,0)
synDef
#endif
) pats
, feqn_fixity = Prefix
, feqn_rhs = rhs
}
}
}
-- | 'HsBind' includes a location, and this is one of the few places
-- where we do not need a location. Rather than distinguishing in
-- the type between bindings that have a location and those that
-- do not, we simply ignore any binding location given here.
valDecl_ :: HsBind -> HsDecl
valDecl_ (L _ b) = noLocA (GHC.ValD NoExtField b)
patBind_ :: HsPat -> HsExp -> HsBind
patBind_ (L _ (VarPat _ nm)) rhs =
function_ nm [([], rhs)] -- The comments at 'HsBindLR' say to use 'FunBind'.
patBind_ (L _ (BangPat _ (L _ (VarPat _ nm)))) rhs =
functionLike_ SrcStrict nm [([], rhs)] -- The comments at 'HsBindLR' say to use 'FunBind'.
patBind_ (L _ (LazyPat _ (L _ (VarPat _ nm)))) rhs =
functionLike_ SrcLazy nm [([], rhs)] -- The comments at 'HsBindLR' say to use 'FunBind'.
patBind_ pat rhs = noLocA PatBind
{ pat_ext = synDef
, pat_lhs = pat
#if MIN_VERSION_ghc_lib_parser(9,10,0)
, pat_mult = HsNoMultAnn synDef
#endif
, pat_rhs = unguardedGRHSs synDef rhs synDef
#if !MIN_VERSION_ghc_lib_parser(9,6,0)
, pat_ticks = synDef
#endif
}
-- | @'functionS_' = 'function_' . 'unqual_' 'varName'@
functionS_ :: String -> [([HsPat], HsExp)] -> HsBind
functionS_ = function_ . unqual_ varName
-- | A function with prefix syntax (as opposed to infix).
function_ :: HsName -> [([HsPat], HsExp)] -> HsBind
function_ = functionLike_ NoSrcStrict
functionLike_ :: SrcStrictness -> HsName -> [([HsPat], HsExp)] -> HsBind
functionLike_ strictness name alts = noLocA $ mkFunBind generated name (map match alts)
where
generated :: Origin
generated = Generated
#if MIN_VERSION_ghc_lib_parser(9,10,0)
OtherExpansion
#endif
#if MIN_VERSION_ghc_lib_parser(9,8,0)
DoPmc
#endif
match :: ([HsPat], HsExp) -> HsMatch
#if MIN_VERSION_ghc_lib_parser(9,12,0)
match (pats, rhs) = mkSimpleMatch ctxt (noLocA pats) rhs
#else
match (pats, rhs) = mkSimpleMatch ctxt pats rhs
#endif
ctxt = FunRhs
{ mc_fun = name
, mc_fixity = Prefix
, mc_strictness = strictness
#if MIN_VERSION_ghc_lib_parser(9,12,0)
, mc_an = noAnn
#endif
}
typeSig_ :: [HsName] -> HsOuterSigTyVarBndrs -> HsType -> HsDecl
typeSig_ nms bndrs ty = noLocA $ GHC.SigD NoExtField $ TypeSig synDef nms $
HsWC NoExtField $
noLocA $
HsSig NoExtField bndrs ty
implicitOuterFamEqnTyVarBinders_ :: HsOuterFamEqnTyVarBndrs
implicitOuterFamEqnTyVarBinders_ = HsOuterImplicit NoExtField
implicitOuterSigTyVarBinders_ :: HsOuterSigTyVarBndrs
implicitOuterSigTyVarBinders_ = HsOuterImplicit NoExtField
userTyVar_ :: flag -> HsName -> LHsTyVarBndr flag GhcPs
#if MIN_VERSION_ghc_lib_parser(9,12,0)
userTyVar_ flag nm = noLocA $ GHC.HsTvb noAnn flag (HsBndrVar NoExtField nm) (HsBndrNoKind NoExtField)
#else
userTyVar_ flag nm = noLocA $ GHC.UserTyVar synDef flag nm
#endif
kindedTyVar_ :: flag -> HsName -> HsType -> LHsTyVarBndr flag GhcPs
#if MIN_VERSION_ghc_lib_parser(9,12,0)
kindedTyVar_ flag nm ty = noLocA $ GHC.HsTvb noAnn flag (HsBndrVar NoExtField nm) (HsBndrKind NoExtField ty)
#else
kindedTyVar_ flag nm ty = noLocA $ GHC.KindedTyVar synDef flag nm ty
#endif
wild_ :: HsPat
wild_ = noLocA $ WildPat NoExtField
qual_ :: ModuleName -> NameSpace -> String -> HsQName
qual_ m ns name = noLocA $ mkRdrQual m (mkOccName ns name)
unqual_ :: NameSpace -> String -> HsName
unqual_ ns name = noLocA $ mkRdrUnqual (mkOccName ns name)
uvar_ :: String -> HsExp
uvar_ = var_ . unqual_ varName
var_ :: HsQName -> HsExp
var_ = noLocA . HsVar NoExtField
fieldBind_ :: HsName -> HsExp -> LHsRecField GhcPs HsExp
fieldBind_ nm val = noLocA
#if MIN_VERSION_ghc_lib_parser(9,4,0)
HsFieldBind
{ hfbAnn = synDef
, hfbLHS = noLocA $ FieldOcc NoExtField nm
, hfbRHS = val
, hfbPun = False
}
#else
HsRecField
{ hsRecFieldAnn = synDef
, hsRecFieldLbl = noLoc $ FieldOcc NoExtField nm
, hsRecFieldArg = val
, hsRecPun = False
}
#endif
recordCtor_ :: HsName -> [LHsRecField GhcPs HsExp] -> HsExp
recordCtor_ nm fields = noLocA RecordCon
{ rcon_ext = synDef
, rcon_con = nm
, rcon_flds = HsRecFields
{ rec_flds = fields
, rec_dotdot = Nothing
#if MIN_VERSION_ghc_lib_parser(9,12,0)
, rec_ext = NoExtField
#endif
}
}
fieldUpd_ :: HsName -> HsExp -> LHsRecUpdField GhcPs
#if MIN_VERSION_ghc_lib_parser(9,8,0)
GhcPs
#endif
fieldUpd_ nm val = noLocA
#if MIN_VERSION_ghc_lib_parser(9,4,0)
HsFieldBind
{ hfbAnn = synDef
#if MIN_VERSION_ghc_lib_parser(9,12,0)
, hfbLHS = noLocA $ FieldOcc NoExtField nm
#else
, hfbLHS = noLocA $ Ambiguous NoExtField nm
#endif
, hfbRHS = val
, hfbPun = False
}
#else
HsRecField
{ hsRecFieldAnn = synDef
, hsRecFieldLbl = noLoc $ Ambiguous NoExtField nm
, hsRecFieldArg = val
, hsRecPun = False
}
#endif
recordUpd_ :: HsExp -> [ LHsRecUpdField GhcPs
#if MIN_VERSION_ghc_lib_parser(9,8,0)
GhcPs
#endif
] -> HsExp
recordUpd_ r fields = noLocA RecordUpd
{ rupd_ext = synDef
, rupd_expr = r
, rupd_flds =
#if MIN_VERSION_ghc_lib_parser(9,8,0)
RegularRecUpdFields synDef
#else
Left
#endif
fields
}
protobufType_, primType_, protobufStringType_, protobufBytesType_ :: String -> HsType
protobufType_ = typeNamed_ . protobufName tcName
primType_ = typeNamed_ . haskellName tcName
protobufStringType_ = tyApp (protobufType_ "String") . typeNamed_ . haskellName tcName
protobufBytesType_ = tyApp (protobufType_ "Bytes") . typeNamed_ . haskellName tcName
protobufFixedType_, protobufSignedType_, protobufWrappedType_ :: HsType -> HsType
protobufFixedType_ = tyApp (protobufType_ "Fixed")
protobufSignedType_ = tyApp (protobufType_ "Signed")
protobufWrappedType_ = tyApp (protobufType_ "Wrapped")
typeNamed_ :: HsName -> HsType
typeNamed_ nm@(L _ r) = noLocA $ GHC.HsTyVar synDef promotion nm
where
promotion
| rdrNameSpace r == dataName = IsPromoted
| otherwise = NotPromoted
type_ :: String -> HsType
type_ = typeNamed_ . unqual_ tcName
tvarn_ :: String -> HsName
tvarn_ = unqual_ tvName
tvar_ :: String -> HsType
tvar_ = typeNamed_ . tvarn_
kindSig_ :: HsType -> HsType -> HsType
kindSig_ ty = noLocA . GHC.HsKindSig synDef ty
tupleType_ :: [HsType] -> HsType
tupleType_ = noLocA . GHC.HsTupleTy synDef HsBoxedOrConstraintTuple
patVar :: String -> HsPat
patVar = noLocA . VarPat NoExtField . unqual_ varName
conPat :: HsQName -> [HsPat] -> HsPat
conPat (L _ ctor) = nlConPat ctor
recPat :: HsQName -> [LHsRecField GhcPs HsPat] -> HsPat
recPat ctor fields = noLocA $ ConPat synDef ctor $ RecCon $ HsRecFields
{ rec_flds = fields
, rec_dotdot = Nothing
#if MIN_VERSION_ghc_lib_parser(9,12,0)
, rec_ext = NoExtField
#endif
}
fieldPunPat :: HsName -> LHsRecField GhcPs HsPat
fieldPunPat nm = noLocA
#if MIN_VERSION_ghc_lib_parser(9,4,0)
HsFieldBind
{ hfbAnn = synDef
, hfbLHS = noLocA $ FieldOcc NoExtField nm
, hfbRHS = noLocA $ VarPat NoExtField nm
, hfbPun = True
}
#else
HsRecField
{ hsRecFieldAnn = synDef
, hsRecFieldLbl = noLoc $ FieldOcc NoExtField nm
, hsRecFieldArg = noLocA $ VarPat NoExtField nm
, hsRecPun = True
}
#endif
alt_ :: HsPat -> HsExp -> HsAlt
alt_ = mkHsCaseAlt
case_ :: HsExp -> [HsAlt] -> HsExp
case_ e = noLocA . HsCase synDef e . mkMatchGroup generated . noLocA
where
generated :: Origin
generated = Generated
#if MIN_VERSION_ghc_lib_parser(9,10,0)
OtherExpansion
#endif
#if MIN_VERSION_ghc_lib_parser(9,8,0)
DoPmc
#endif
-- | Simple let expression for ordinary bindings.
let_ :: [HsBind] -> HsExp -> HsExp
let_ locals e =
#if MIN_VERSION_ghc_lib_parser(9,10,0)
noLocA $ HsLet synDef binds e
#elif MIN_VERSION_ghc_lib_parser(9,4,0)
noLocA $ HsLet synDef synDef binds synDef e
#else
noLocA $ HsLet synDef binds e
#endif
where
#if MIN_VERSION_ghc_lib_parser(9,12,0)
binds = HsValBinds synDef (ValBinds synDef locals [])
#else
binds = HsValBinds synDef (ValBinds synDef (listToBag locals) [])
#endif
-- | Lambda abstraction.
lambda_ :: [HsPat] -> HsExp -> HsExp
#if MIN_VERSION_ghc_lib_parser(9,12,0)
lambda_ = mkHsLam . noLocA
#else
lambda_ = mkHsLam
#endif
if_ :: HsExp -> HsExp -> HsExp -> HsExp
if_ c t f = noLocA $ mkHsIf c t f synDef
-- | A boxed tuple with all components present.
tuple_ :: [HsExp] -> HsExp
#if MIN_VERSION_ghc_lib_parser(9,12,0)
tuple_ xs = mkLHsTupleExpr xs noAnn
#else
tuple_ xs = mkLHsTupleExpr xs synDef
#endif
-- | A promoted boxed tuple value with all components present.
tupleT_ :: [HsType] -> HsType
tupleT_ = noLocA . HsExplicitTupleTy synDef
#if MIN_VERSION_ghc_lib_parser(9,12,0)
NotPromoted
#endif
list_ :: [HsExp] -> HsExp
list_ = nlList
listT_ :: [HsType] -> HsType
listT_ = noLocA . HsExplicitListTy synDef IsPromoted
str_ :: String -> HsExp
str_ = noLocA . HsLit synDef . mkHsString
strPat :: String -> HsPat
strPat = noLocA . LitPat NoExtField . HsString NoSourceText . mkFastString
symT :: String -> HsType
symT = noLocA . HsTyLit synDef . HsStrTy NoSourceText . mkFastString
--------------------------------------------------------------------------------
--
-- * Common Haskell expressions, constructors, and operators
--
nothingN, justN :: HsQName
dotProtoFieldC, primC, optionalC, repeatedC, nestedRepeatedC, namedC, mapC,
fieldNumberC, singleC, dotsC, pathC, qualifiedC, anonymousC, dotProtoOptionC,
identifierC, stringLitC, intLitC, floatLitC, boolLitC, trueC, falseC, nothingC,
justC, forceEmitC, encodeMessageFieldE, fromStringE, decodeMessageFieldE,
pureE, returnE, mappendE, memptyE, msumE, atE, oneofE, fmapE :: HsExp
forceEmitT, justT, maybeT, nothingT, natT, symbolT, typeErrorT :: HsType
dotProtoFieldC = var_ (protobufASTName tcName "DotProtoField")
primC = var_ (protobufASTName dataName "Prim")
optionalC = var_ (protobufASTName dataName "Optional")
repeatedC = var_ (protobufASTName dataName "Repeated")
nestedRepeatedC = var_ (protobufASTName dataName "NestedRepeated")
namedC = var_ (protobufASTName tcName "Named")
mapC = var_ (protobufASTName dataName "Map")
fieldNumberC = var_ (protobufName dataName "FieldNumber")
singleC = var_ (protobufASTName dataName "Single")
pathC = var_ (protobufASTName dataName "Path")
dotsC = var_ (protobufASTName dataName "Dots")
qualifiedC = var_ (protobufASTName dataName "Qualified")
anonymousC = var_ (protobufASTName dataName "Anonymous")
dotProtoOptionC = var_ (protobufASTName tcName "DotProtoOption")
identifierC = var_ (protobufASTName dataName "Identifier")
stringLitC = var_ (protobufASTName dataName "StringLit")
intLitC = var_ (protobufASTName dataName "IntLit")
floatLitC = var_ (protobufASTName dataName "FloatLit")
boolLitC = var_ (protobufASTName dataName "BoolLit")
forceEmitC = var_ (protobufName dataName "ForceEmit")
forceEmitT = protobufType_ "ForceEmit"
encodeMessageFieldE = var_ (protobufName varName "encodeMessageField")
decodeMessageFieldE = var_ (protobufName varName "decodeMessageField")
atE = var_ (protobufName varName "at")
oneofE = var_ (protobufName varName "oneof")
trueC = var_ (haskellName dataName "True")
falseC = var_ (haskellName dataName "False")
nothingC = var_ nothingN
nothingN = haskellName dataName "Nothing"
nothingT = typeNamed_ (haskellName tcName "Nothing")
justC = var_ justN
justN = haskellName dataName "Just"
justT = typeNamed_ (haskellName tcName "Just")
maybeT = typeNamed_ (haskellName tcName "Maybe")
fromStringE = var_ (haskellName varName "fromString")
pureE = var_ (haskellName varName "pure")
returnE = var_ (haskellName varName "return")
mappendE = var_ (haskellName varName "mappend")
memptyE = var_ (haskellName varName "mempty")
msumE = var_ (haskellName varName "msum")
fmapE = var_ (haskellName varName "fmap")
natT = typeNamed_ (haskellName tcName "Nat")
symbolT = typeNamed_ (haskellName tcName "Symbol")
typeErrorT = typeNamed_ (haskellName tcName "TypeError")
apOp :: HsQOp
apOp = uvar_ "<*>"
fmapOp :: HsQOp
fmapOp = uvar_ "<$>"
composeOp :: HsQOp
composeOp = var_ (haskellName varName ".")
fractionOp :: HsQOp
fractionOp = var_ (haskellName varName "/")
bindOp :: HsQOp
bindOp = var_ (haskellName varName ">>=")
altOp :: HsQOp
altOp = uvar_ "<|>"
toJSONPBOp :: HsQOp
toJSONPBOp = uvar_ ".="
parseJSONPBOp :: HsQOp
parseJSONPBOp = uvar_ ".:"
neConsOp :: HsQOp
neConsOp = var_ (haskellName varName ":|")
intE :: Integral a => a -> HsExp
intE x = noLocA $ HsOverLit synDef $ mkHsIntegral $ IL
{ il_text = NoSourceText
, il_neg = x < 0
, il_value = toInteger x
}
intP :: Integral a => a -> HsPat
intP x = noLocA $ NPat synDef overlit Nothing NoExtField
where
overlit = L synDef $ mkHsIntegral $ IL
{ il_text = NoSourceText
, il_neg = x < 0
, il_value = toInteger x
}
natTLit :: Integral a => a -> HsType
natTLit = noLocA . HsTyLit synDef . HsNumTy NoSourceText . toInteger
floatE :: forall f . RealFloat f => f -> HsExp
floatE x
| isNaN x = opApp zero fractionOp zero
| isInfinite x = opApp (if x < 0 then minusOne else plusOne) fractionOp zero
| otherwise = scientific x
where
zero = scientific (0 :: f)
minusOne = scientific (-1 :: f)
plusOne = scientific (1 :: f)
scientific y = noLocA $ HsOverLit synDef overlit
where
(_s, _e) = decodeFloat (abs y)
overlit = mkHsFractional $ FL
{ fl_text = NoSourceText
, fl_neg = y < 0
, fl_signi = _s % 1
, fl_exp = toInteger _e
, fl_exp_base = case floatRadix y of
2 -> Base2
10 -> Base10
b -> error $ "doubleE: unsupported floatRadix " ++ show b
}
do_ :: [ExprLStmt GhcPs] -> HsExp
do_ = noLocA . mkHsDo (DoExpr Nothing) . noLocA
letStmt_ :: [HsBind] -> ExprLStmt GhcPs
letStmt_ locals = noLocA $ LetStmt synDef binds
where
#if MIN_VERSION_ghc_lib_parser(9,12,0)
binds = HsValBinds synDef (ValBinds synDef locals [])
#else
binds = HsValBinds synDef (ValBinds synDef (listToBag locals) [])
#endif
bindStmt_ :: HsPat -> HsExp -> ExprLStmt GhcPs
bindStmt_ p e = noLocA $ mkPsBindStmt synDef p e
lastStmt_ :: HsExp -> ExprLStmt GhcPs
lastStmt_ = noLocA . mkLastStmt
bodyStmt_ :: HsExp -> ExprLStmt GhcPs
bodyStmt_ = noLocA . mkBodyStmt