module GHC.Parser.PostProcess (
mkRdrGetField, mkRdrProjection, Fbind,
mkHsOpApp,
mkHsIntegral, mkHsFractional, mkHsIsString,
mkHsDo, mkSpliceDecl,
mkRoleAnnotDecl,
mkClassDecl,
mkTyData, mkDataFamInst,
mkTySynonym, mkTyFamInstEqn,
mkStandaloneKindSig,
mkTyFamInst,
mkFamDecl,
mkInlinePragma,
mkPatSynMatchGroup,
mkRecConstrOrUpdate,
mkTyClD, mkInstD,
mkRdrRecordCon, mkRdrRecordUpd,
setRdrNameSpace,
fromSpecTyVarBndr, fromSpecTyVarBndrs,
annBinds,
cvBindGroup,
cvBindsAndSigs,
cvTopDecls,
placeHolderPunRhs,
mkImport,
parseCImport,
mkExport,
mkExtName,
mkGadtDecl,
mkConDeclH98,
checkImportDecl,
checkExpBlockArguments, checkCmdBlockArguments,
checkPrecP,
checkContext,
checkPattern,
checkPattern_hints,
checkMonadComp,
checkValDef,
checkValSigLhs,
LRuleTyTmVar, RuleTyTmVar(..),
mkRuleBndrs, mkRuleTyVarBndrs,
checkRuleTyVarBndrNames,
checkRecordSyntax,
checkEmptyGADTs,
addFatalError, hintBangPat,
mkBangTy,
UnpackednessPragma(..),
mkMultTy,
ImpExpSubSpec(..),
ImpExpQcSpec(..),
mkModuleImpExp,
mkTypeImpExp,
mkImpExpSubSpec,
checkImportSpec,
starSym,
warnStarIsType,
warnPrepositiveQualifiedModule,
failOpFewArgs,
failOpNotEnabledImportQualifiedPost,
failOpImportQualifiedTwice,
SumOrTuple (..),
PV,
runPV,
ECP(ECP, unECP),
DisambInfixOp(..),
DisambECP(..),
ecpFromExp,
ecpFromCmd,
PatBuilder,
DisambTD(..),
addUnpackednessP,
dataConBuilderCon,
dataConBuilderDetails,
) where
import GHC.Prelude
import GHC.Hs
import GHC.Core.TyCon ( TyCon, isTupleTyCon, tyConSingleDataCon_maybe )
import GHC.Core.DataCon ( DataCon, dataConTyCon )
import GHC.Core.ConLike ( ConLike(..) )
import GHC.Core.Coercion.Axiom ( Role, fsFromRole )
import GHC.Types.Name.Reader
import GHC.Types.Name
import GHC.Unit.Module (ModuleName)
import GHC.Types.Basic
import GHC.Types.Fixity
import GHC.Types.SourceText
import GHC.Parser.Types
import GHC.Parser.Lexer
import GHC.Parser.Errors
import GHC.Utils.Lexeme ( isLexCon )
import GHC.Types.TyThing
import GHC.Core.Type ( unrestrictedFunTyCon, Specificity(..) )
import GHC.Builtin.Types( cTupleTyConName, tupleTyCon, tupleDataCon,
nilDataConName, nilDataConKey,
listTyConName, listTyConKey, eqTyCon_RDR )
import GHC.Types.ForeignCall
import GHC.Types.SrcLoc
import GHC.Types.Unique ( hasKey )
import GHC.Data.OrdList
import GHC.Utils.Outputable as Outputable
import GHC.Data.FastString
import GHC.Data.Maybe
import GHC.Data.Bag
import GHC.Utils.Misc
import Data.Either
import Data.List
import Data.Foldable
import GHC.Driver.Flags ( WarningFlag(..) )
import qualified Data.Semigroup as Semi
import GHC.Utils.Panic
import Control.Monad
import Text.ParserCombinators.ReadP as ReadP
import Data.Char
import Data.Data ( dataTypeOf, fromConstr, dataTypeConstrs )
import Data.Kind ( Type )
#include "HsVersions.h"
mkTyClD :: LTyClDecl (GhcPass p) -> LHsDecl (GhcPass p)
mkTyClD (L loc d) = L loc (TyClD noExtField d)
mkInstD :: LInstDecl (GhcPass p) -> LHsDecl (GhcPass p)
mkInstD (L loc d) = L loc (InstD noExtField d)
mkClassDecl :: SrcSpan
-> Located (Maybe (LHsContext GhcPs), LHsType GhcPs)
-> Located (a,[LHsFunDep GhcPs])
-> OrdList (LHsDecl GhcPs)
-> LayoutInfo
-> [AddEpAnn]
-> P (LTyClDecl GhcPs)
mkClassDecl loc' (L _ (mcxt, tycl_hdr)) fds where_cls layoutInfo annsIn
= do { let loc = noAnnSrcSpan loc'
; (binds, sigs, ats, at_defs, _, docs) <- cvBindsAndSigs where_cls
; (cls, tparams, fixity, ann) <- checkTyClHdr True tycl_hdr
; (tyvars,annst) <- checkTyVars (text "class") whereDots cls tparams
; cs <- getCommentsFor (locA loc)
; let anns' = addAnns (EpAnn (spanAsAnchor $ locA loc) annsIn noCom) (ann++annst) cs
; return (L loc (ClassDecl { tcdCExt = (anns', NoAnnSortKey, layoutInfo)
, tcdCtxt = mcxt
, tcdLName = cls, tcdTyVars = tyvars
, tcdFixity = fixity
, tcdFDs = snd (unLoc fds)
, tcdSigs = mkClassOpSigs sigs
, tcdMeths = binds
, tcdATs = ats, tcdATDefs = at_defs
, tcdDocs = docs })) }
mkTyData :: SrcSpan
-> NewOrData
-> Maybe (LocatedP CType)
-> Located (Maybe (LHsContext GhcPs), LHsType GhcPs)
-> Maybe (LHsKind GhcPs)
-> [LConDecl GhcPs]
-> Located (HsDeriving GhcPs)
-> [AddEpAnn]
-> P (LTyClDecl GhcPs)
mkTyData loc' new_or_data cType (L _ (mcxt, tycl_hdr))
ksig data_cons (L _ maybe_deriv) annsIn
= do { let loc = noAnnSrcSpan loc'
; (tc, tparams, fixity, ann) <- checkTyClHdr False tycl_hdr
; (tyvars, anns) <- checkTyVars (ppr new_or_data) equalsDots tc tparams
; cs <- getCommentsFor (locA loc)
; let anns' = addAnns (EpAnn (spanAsAnchor $ locA loc) annsIn noCom) (ann ++ anns) cs
; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv anns'
; return (L loc (DataDecl { tcdDExt = anns',
tcdLName = tc, tcdTyVars = tyvars,
tcdFixity = fixity,
tcdDataDefn = defn })) }
mkDataDefn :: NewOrData
-> Maybe (LocatedP CType)
-> Maybe (LHsContext GhcPs)
-> Maybe (LHsKind GhcPs)
-> [LConDecl GhcPs]
-> HsDeriving GhcPs
-> EpAnn
-> P (HsDataDefn GhcPs)
mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv ann
= do { checkDatatypeContext mcxt
; return (HsDataDefn { dd_ext = ann
, dd_ND = new_or_data, dd_cType = cType
, dd_ctxt = mcxt
, dd_cons = data_cons
, dd_kindSig = ksig
, dd_derivs = maybe_deriv }) }
mkTySynonym :: SrcSpan
-> LHsType GhcPs
-> LHsType GhcPs
-> [AddEpAnn]
-> P (LTyClDecl GhcPs)
mkTySynonym loc lhs rhs annsIn
= do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs
; cs1 <- getCommentsFor loc
; (tyvars, anns) <- checkTyVars (text "type") equalsDots tc tparams
; cs2 <- getCommentsFor loc
; let anns' = addAnns (EpAnn (spanAsAnchor loc) annsIn noCom) (ann ++ anns) (cs1 Semi.<> cs2)
; return (L (noAnnSrcSpan loc) (SynDecl
{ tcdSExt = anns'
, tcdLName = tc, tcdTyVars = tyvars
, tcdFixity = fixity
, tcdRhs = rhs })) }
mkStandaloneKindSig
:: SrcSpan
-> Located [LocatedN RdrName]
-> LHsSigType GhcPs
-> [AddEpAnn]
-> P (LStandaloneKindSig GhcPs)
mkStandaloneKindSig loc lhs rhs anns =
do { vs <- mapM check_lhs_name (unLoc lhs)
; v <- check_singular_lhs (reverse vs)
; cs <- getCommentsFor loc
; return $ L (noAnnSrcSpan loc)
$ StandaloneKindSig (EpAnn (spanAsAnchor loc) anns cs) v rhs }
where
check_lhs_name v@(unLoc->name) =
if isUnqual name && isTcOcc (rdrNameOcc name)
then return v
else addFatalError $ PsError (PsErrUnexpectedQualifiedConstructor (unLoc v)) [] (getLocA v)
check_singular_lhs vs =
case vs of
[] -> panic "mkStandaloneKindSig: empty left-hand side"
[v] -> return v
_ -> addFatalError $ PsError (PsErrMultipleNamesInStandaloneKindSignature vs) [] (getLoc lhs)
mkTyFamInstEqn :: SrcSpan
-> HsOuterFamEqnTyVarBndrs GhcPs
-> LHsType GhcPs
-> LHsType GhcPs
-> [AddEpAnn]
-> P (LTyFamInstEqn GhcPs)
mkTyFamInstEqn loc bndrs lhs rhs anns
= do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs
; cs <- getCommentsFor loc
; return (L (noAnnSrcSpan loc) $ FamEqn
{ feqn_ext = EpAnn (spanAsAnchor loc) (anns `mappend` ann) cs
, feqn_tycon = tc
, feqn_bndrs = bndrs
, feqn_pats = tparams
, feqn_fixity = fixity
, feqn_rhs = rhs })}
mkDataFamInst :: SrcSpan
-> NewOrData
-> Maybe (LocatedP CType)
-> (Maybe ( LHsContext GhcPs), HsOuterFamEqnTyVarBndrs GhcPs
, LHsType GhcPs)
-> Maybe (LHsKind GhcPs)
-> [LConDecl GhcPs]
-> Located (HsDeriving GhcPs)
-> [AddEpAnn]
-> P (LInstDecl GhcPs)
mkDataFamInst loc new_or_data cType (mcxt, bndrs, tycl_hdr)
ksig data_cons (L _ maybe_deriv) anns
= do { (tc, tparams, fixity, ann) <- checkTyClHdr False tycl_hdr
;
; cs <- getCommentsFor loc
; let anns' = addAnns (EpAnn (spanAsAnchor loc) ann cs) anns noCom
; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv anns'
; return (L (noAnnSrcSpan loc) (DataFamInstD anns' (DataFamInstDecl
(FamEqn { feqn_ext = noAnn
, feqn_tycon = tc
, feqn_bndrs = bndrs
, feqn_pats = tparams
, feqn_fixity = fixity
, feqn_rhs = defn })))) }
mkTyFamInst :: SrcSpan
-> TyFamInstEqn GhcPs
-> [AddEpAnn]
-> P (LInstDecl GhcPs)
mkTyFamInst loc eqn anns = do
cs <- getCommentsFor loc
return (L (noAnnSrcSpan loc) (TyFamInstD noExtField
(TyFamInstDecl (EpAnn (spanAsAnchor loc) anns cs) eqn)))
mkFamDecl :: SrcSpan
-> FamilyInfo GhcPs
-> TopLevelFlag
-> LHsType GhcPs
-> Located (FamilyResultSig GhcPs)
-> Maybe (LInjectivityAnn GhcPs)
-> [AddEpAnn]
-> P (LTyClDecl GhcPs)
mkFamDecl loc info topLevel lhs ksig injAnn annsIn
= do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs
; cs1 <- getCommentsFor loc
; (tyvars, anns) <- checkTyVars (ppr info) equals_or_where tc tparams
; cs2 <- getCommentsFor loc
; let anns' = addAnns (EpAnn (spanAsAnchor loc) annsIn noCom) (ann++anns) (cs1 Semi.<> cs2)
; return (L (noAnnSrcSpan loc) (FamDecl noExtField
(FamilyDecl
{ fdExt = anns'
, fdTopLevel = topLevel
, fdInfo = info, fdLName = tc
, fdTyVars = tyvars
, fdFixity = fixity
, fdResultSig = ksig
, fdInjectivityAnn = injAnn }))) }
where
equals_or_where = case info of
DataFamily -> empty
OpenTypeFamily -> empty
ClosedTypeFamily {} -> whereDots
mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs)
mkSpliceDecl lexpr@(L loc expr)
| HsSpliceE _ splice@(HsUntypedSplice {}) <- expr = do
cs <- getCommentsFor (locA loc)
return $ L (addCommentsToSrcAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) ExplicitSplice)
| HsSpliceE _ splice@(HsQuasiQuote {}) <- expr = do
cs <- getCommentsFor (locA loc)
return $ L (addCommentsToSrcAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) ExplicitSplice)
| otherwise = do
cs <- getCommentsFor (locA loc)
return $ L (addCommentsToSrcAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField
(L loc (mkUntypedSplice noAnn BareSplice lexpr))
ImplicitSplice)
mkRoleAnnotDecl :: SrcSpan
-> LocatedN RdrName
-> [Located (Maybe FastString)]
-> [AddEpAnn]
-> P (LRoleAnnotDecl GhcPs)
mkRoleAnnotDecl loc tycon roles anns
= do { roles' <- mapM parse_role roles
; cs <- getCommentsFor loc
; return $ L (noAnnSrcSpan loc)
$ RoleAnnotDecl (EpAnn (spanAsAnchor loc) anns cs) tycon roles' }
where
role_data_type = dataTypeOf (undefined :: Role)
all_roles = map fromConstr $ dataTypeConstrs role_data_type
possible_roles = [(fsFromRole role, role) | role <- all_roles]
parse_role (L loc_role Nothing) = return $ L loc_role Nothing
parse_role (L loc_role (Just role))
= case lookup role possible_roles of
Just found_role -> return $ L loc_role $ Just found_role
Nothing ->
let nearby = fuzzyLookup (unpackFS role)
(mapFst unpackFS possible_roles)
in
addFatalError $ PsError (PsErrIllegalRoleName role nearby) [] loc_role
fromSpecTyVarBndrs :: [LHsTyVarBndr Specificity GhcPs] -> P [LHsTyVarBndr () GhcPs]
fromSpecTyVarBndrs = mapM fromSpecTyVarBndr
fromSpecTyVarBndr :: LHsTyVarBndr Specificity GhcPs -> P (LHsTyVarBndr () GhcPs)
fromSpecTyVarBndr bndr = case bndr of
(L loc (UserTyVar xtv flag idp)) -> (check_spec flag loc)
>> return (L loc $ UserTyVar xtv () idp)
(L loc (KindedTyVar xtv flag idp k)) -> (check_spec flag loc)
>> return (L loc $ KindedTyVar xtv () idp k)
where
check_spec :: Specificity -> SrcSpanAnnA -> P ()
check_spec SpecifiedSpec _ = return ()
check_spec InferredSpec loc = addFatalError $ PsError PsErrInferredTypeVarNotAllowed [] (locA loc)
annBinds :: AddEpAnn -> HsLocalBinds GhcPs -> HsLocalBinds GhcPs
annBinds a (HsValBinds an bs) = (HsValBinds (add_where a an) bs)
annBinds a (HsIPBinds an bs) = (HsIPBinds (add_where a an) bs)
annBinds _ (EmptyLocalBinds x) = (EmptyLocalBinds x)
add_where :: AddEpAnn -> EpAnn' AnnList -> EpAnn' AnnList
add_where an@(AddEpAnn _ (AR rs)) (EpAnn a (AnnList anc o c r t) cs)
| valid_anchor (anchor a)
= EpAnn (widenAnchor a [an]) (AnnList anc o c (an:r) t) cs
| otherwise
= EpAnn (patch_anchor rs a) (AnnList (fmap (patch_anchor rs) anc) o c (an:r) t) cs
add_where an@(AddEpAnn _ (AR rs)) EpAnnNotUsed
= EpAnn (Anchor rs UnchangedAnchor)
(AnnList (Just $ Anchor rs UnchangedAnchor) Nothing Nothing [an] []) noCom
add_where (AddEpAnn _ (AD _)) _ = panic "add_where"
valid_anchor :: RealSrcSpan -> Bool
valid_anchor r = srcSpanStartLine r >= 0
patch_anchor :: RealSrcSpan -> Anchor -> Anchor
patch_anchor r1 (Anchor r0 op) = Anchor r op
where
r = if srcSpanStartLine r0 < 0 then r1 else r0
cvTopDecls :: OrdList (LHsDecl GhcPs) -> [LHsDecl GhcPs]
cvTopDecls decls = getMonoBindAll (fromOL decls)
cvBindGroup :: OrdList (LHsDecl GhcPs) -> P (HsValBinds GhcPs)
cvBindGroup binding
= do { (mbs, sigs, fam_ds, tfam_insts
, dfam_insts, _) <- cvBindsAndSigs binding
; ASSERT( null fam_ds && null tfam_insts && null dfam_insts)
return $ ValBinds NoAnnSortKey mbs sigs }
cvBindsAndSigs :: OrdList (LHsDecl GhcPs)
-> P (LHsBinds GhcPs, [LSig GhcPs], [LFamilyDecl GhcPs]
, [LTyFamInstDecl GhcPs], [LDataFamInstDecl GhcPs], [LDocDecl GhcPs])
cvBindsAndSigs fb = do
fb' <- drop_bad_decls (fromOL fb)
return (partitionBindsAndSigs (getMonoBindAll fb'))
where
drop_bad_decls [] = return []
drop_bad_decls (L l (SpliceD _ d) : ds) = do
addError $ PsError (PsErrDeclSpliceNotAtTopLevel d) [] (locA l)
drop_bad_decls ds
drop_bad_decls (d:ds) = (d:) <$> drop_bad_decls ds
getMonoBind :: LHsBind GhcPs -> [LHsDecl GhcPs]
-> (LHsBind GhcPs, [LHsDecl GhcPs])
getMonoBind (L loc1 (FunBind { fun_id = fun_id1@(L _ f1)
, fun_matches =
MG { mg_alts = (L _ mtchs1) } }))
binds
| has_args mtchs1
= go mtchs1 loc1 binds []
where
go :: [LMatch GhcPs (LHsExpr GhcPs)] -> SrcSpanAnnA
-> [LHsDecl GhcPs] -> [LHsDecl GhcPs]
-> (LHsBind GhcPs,[LHsDecl GhcPs])
go mtchs loc
((L loc2 (ValD _ (FunBind { fun_id = (L _ f2)
, fun_matches =
MG { mg_alts = (L _ [L lm2 mtchs2]) } })))
: binds) _
| f1 == f2 =
let (loc2', lm2') = transferComments loc2 lm2
in go (L lm2' mtchs2 : mtchs)
(combineSrcSpansA loc loc2') binds []
go mtchs loc (doc_decl@(L loc2 (DocD {})) : binds) doc_decls
= let doc_decls' = doc_decl : doc_decls
in go mtchs (combineSrcSpansA loc loc2) binds doc_decls'
go mtchs loc binds doc_decls
= ( L loc (makeFunBind fun_id1 (mkLocatedList $ reverse mtchs))
, (reverse doc_decls) ++ binds)
getMonoBind bind binds = (bind, binds)
getMonoBindAll :: [LHsDecl GhcPs] -> [LHsDecl GhcPs]
getMonoBindAll [] = []
getMonoBindAll (L l (ValD _ b) : ds) =
let (L l' b', ds') = getMonoBind (L l b) ds
in L l' (ValD noExtField b') : getMonoBindAll ds'
getMonoBindAll (d : ds) = d : getMonoBindAll ds
has_args :: [LMatch GhcPs (LHsExpr GhcPs)] -> Bool
has_args [] = panic "GHC.Parser.PostProcess.has_args"
has_args (L _ (Match { m_pats = args }) : _) = not (null args)
tyConToDataCon :: LocatedN RdrName -> Either PsError (LocatedN RdrName)
tyConToDataCon (L loc tc)
| isTcOcc occ || isDataOcc occ
, isLexCon (occNameFS occ)
= return (L loc (setRdrNameSpace tc srcDataName))
| otherwise
= Left $ PsError (PsErrNotADataCon tc) [] (locA loc)
where
occ = rdrNameOcc tc
mkPatSynMatchGroup :: LocatedN RdrName
-> LocatedL (OrdList (LHsDecl GhcPs))
-> P (MatchGroup GhcPs (LHsExpr GhcPs))
mkPatSynMatchGroup (L loc patsyn_name) (L ld decls) =
do { matches <- mapM fromDecl (fromOL decls)
; when (null matches) (wrongNumberErr (locA loc))
; return $ mkMatchGroup FromSource (L ld matches) }
where
fromDecl (L loc decl@(ValD _ (PatBind _
pat@(L _ (ConPat noAnn ln@(L _ name) details))
rhs _))) =
do { unless (name == patsyn_name) $
wrongNameBindingErr (locA loc) decl
; match <- case details of
PrefixCon _ pats -> return $ Match { m_ext = noAnn
, m_ctxt = ctxt, m_pats = pats
, m_grhss = rhs }
where
ctxt = FunRhs { mc_fun = ln
, mc_fixity = Prefix
, mc_strictness = NoSrcStrict }
InfixCon p1 p2 -> return $ Match { m_ext = noAnn
, m_ctxt = ctxt
, m_pats = [p1, p2]
, m_grhss = rhs }
where
ctxt = FunRhs { mc_fun = ln
, mc_fixity = Infix
, mc_strictness = NoSrcStrict }
RecCon{} -> recordPatSynErr (locA loc) pat
; return $ L loc match }
fromDecl (L loc decl) = extraDeclErr (locA loc) decl
extraDeclErr loc decl =
addFatalError $ PsError (PsErrNoSingleWhereBindInPatSynDecl patsyn_name decl) [] loc
wrongNameBindingErr loc decl =
addFatalError $ PsError (PsErrInvalidWhereBindInPatSynDecl patsyn_name decl) [] loc
wrongNumberErr loc =
addFatalError $ PsError (PsErrEmptyWhereInPatSynDecl patsyn_name) [] loc
recordPatSynErr :: SrcSpan -> LPat GhcPs -> P a
recordPatSynErr loc pat =
addFatalError $ PsError (PsErrRecordSyntaxInPatSynDecl pat) [] loc
mkConDeclH98 :: EpAnn -> LocatedN RdrName -> Maybe [LHsTyVarBndr Specificity GhcPs]
-> Maybe (LHsContext GhcPs) -> HsConDeclH98Details GhcPs
-> ConDecl GhcPs
mkConDeclH98 ann name mb_forall mb_cxt args
= ConDeclH98 { con_ext = ann
, con_name = name
, con_forall = isJust mb_forall
, con_ex_tvs = mb_forall `orElse` []
, con_mb_cxt = mb_cxt
, con_args = args
, con_doc = Nothing }
mkGadtDecl :: SrcSpan
-> [LocatedN RdrName]
-> LHsSigType GhcPs
-> [AddEpAnn]
-> P (LConDecl GhcPs)
mkGadtDecl loc names ty annsIn = do
cs <- getCommentsFor loc
let l = noAnnSrcSpan loc
let (args, res_ty, annsa, csa)
| L ll (HsFunTy af _w (L loc' (HsRecTy an rf)) res_ty) <- body_ty
= let
an' = addTrailingAnnToL (locA loc') (anns af) (comments af) an
in ( RecConGADT (L (SrcSpanAnn an' (locA loc')) rf), res_ty
, [], epAnnComments (ann ll))
| otherwise
= let (anns, cs, arg_types, res_type) = splitHsFunType body_ty
in (PrefixConGADT arg_types, res_type, anns, cs)
an = case outer_bndrs of
_ -> EpAnn (spanAsAnchor loc) (annsIn ++ annsa) (cs Semi.<> csa)
pure $ L l ConDeclGADT
{ con_g_ext = an
, con_names = names
, con_bndrs = L (getLoc ty) outer_bndrs
, con_mb_cxt = mcxt
, con_g_args = args
, con_res_ty = res_ty
, con_doc = Nothing }
where
(outer_bndrs, mcxt, body_ty) = splitLHsGadtTy ty
setRdrNameSpace :: RdrName -> NameSpace -> RdrName
setRdrNameSpace (Unqual occ) ns = Unqual (setOccNameSpace ns occ)
setRdrNameSpace (Qual m occ) ns = Qual m (setOccNameSpace ns occ)
setRdrNameSpace (Orig m occ) ns = Orig m (setOccNameSpace ns occ)
setRdrNameSpace (Exact n) ns
| Just thing <- wiredInNameTyThing_maybe n
= setWiredInNameSpace thing ns
| isExternalName n
= Orig (nameModule n) occ
| otherwise
= Exact (mkSystemNameAt (nameUnique n) occ (nameSrcSpan n))
where
occ = setOccNameSpace ns (nameOccName n)
setWiredInNameSpace :: TyThing -> NameSpace -> RdrName
setWiredInNameSpace (ATyCon tc) ns
| isDataConNameSpace ns
= ty_con_data_con tc
| isTcClsNameSpace ns
= Exact (getName tc)
setWiredInNameSpace (AConLike (RealDataCon dc)) ns
| isTcClsNameSpace ns
= data_con_ty_con dc
| isDataConNameSpace ns
= Exact (getName dc)
setWiredInNameSpace thing ns
= pprPanic "setWiredinNameSpace" (pprNameSpace ns <+> ppr thing)
ty_con_data_con :: TyCon -> RdrName
ty_con_data_con tc
| isTupleTyCon tc
, Just dc <- tyConSingleDataCon_maybe tc
= Exact (getName dc)
| tc `hasKey` listTyConKey
= Exact nilDataConName
| otherwise
= Unqual (setOccNameSpace srcDataName (getOccName tc))
data_con_ty_con :: DataCon -> RdrName
data_con_ty_con dc
| let tc = dataConTyCon dc
, isTupleTyCon tc
= Exact (getName tc)
| dc `hasKey` nilDataConKey
= Exact listTyConName
| otherwise
= Unqual (setOccNameSpace tcClsName (getOccName dc))
eitherToP :: MonadP m => Either PsError a -> m a
eitherToP (Left err) = addFatalError err
eitherToP (Right thing) = return thing
checkTyVars :: SDoc -> SDoc -> LocatedN RdrName -> [LHsTypeArg GhcPs]
-> P ( LHsQTyVars GhcPs
, [AddEpAnn] )
checkTyVars pp_what equals_or_where tc tparms
= do { (tvs, anns) <- fmap unzip $ mapM check tparms
; return (mkHsQTvs tvs, concat anns) }
where
check (HsTypeArg _ ki@(L loc _)) = addFatalError $ PsError (PsErrUnexpectedTypeAppInDecl ki pp_what (unLoc tc)) [] (locA loc)
check (HsValArg ty) = chkParens [] noCom ty
check (HsArgPar sp) = addFatalError $ PsError (PsErrMalformedDecl pp_what (unLoc tc)) [] sp
chkParens :: [AddEpAnn] -> EpAnnComments -> LHsType GhcPs
-> P (LHsTyVarBndr () GhcPs, [AddEpAnn])
chkParens acc cs (L l (HsParTy an ty))
= chkParens (mkParensEpAnn (locA l) ++ acc) (cs Semi.<> epAnnComments an) ty
chkParens acc cs ty = do
tv <- chk acc cs ty
return (tv, reverse acc)
chk :: [AddEpAnn] -> EpAnnComments -> LHsType GhcPs -> P (LHsTyVarBndr () GhcPs)
chk an cs (L l (HsKindSig annk (L annt (HsTyVar ann _ (L lv tv))) k))
| isRdrTyVar tv
= return (L (widenLocatedAn (l Semi.<> annt) an)
(KindedTyVar (addAnns (annk Semi.<> ann) an cs) () (L lv tv) k))
chk an cs (L l (HsTyVar ann _ (L ltv tv)))
| isRdrTyVar tv = return (L (widenLocatedAn l an)
(UserTyVar (addAnns ann an cs) () (L ltv tv)))
chk _ _ t@(L loc _)
= addFatalError $ PsError (PsErrUnexpectedTypeInDecl t pp_what (unLoc tc) tparms equals_or_where) [] (locA loc)
whereDots, equalsDots :: SDoc
whereDots = text "where ..."
equalsDots = text "= ..."
checkDatatypeContext :: Maybe (LHsContext GhcPs) -> P ()
checkDatatypeContext Nothing = return ()
checkDatatypeContext (Just c)
= do allowed <- getBit DatatypeContextsBit
unless allowed $ addError $ PsError (PsErrIllegalDataTypeContext c) [] (getLocA c)
type LRuleTyTmVar = Located RuleTyTmVar
data RuleTyTmVar = RuleTyTmVar EpAnn (LocatedN RdrName) (Maybe (LHsType GhcPs))
mkRuleBndrs :: [LRuleTyTmVar] -> [LRuleBndr GhcPs]
mkRuleBndrs = fmap (fmap cvt_one)
where cvt_one (RuleTyTmVar ann v Nothing) = RuleBndr ann v
cvt_one (RuleTyTmVar ann v (Just sig)) =
RuleBndrSig ann v (mkHsPatSigType sig)
mkRuleTyVarBndrs :: [LRuleTyTmVar] -> [LHsTyVarBndr () GhcPs]
mkRuleTyVarBndrs = fmap cvt_one
where cvt_one (L l (RuleTyTmVar ann v Nothing))
= L (noAnnSrcSpan l) (UserTyVar ann () (fmap tm_to_ty v))
cvt_one (L l (RuleTyTmVar ann v (Just sig)))
= L (noAnnSrcSpan l) (KindedTyVar ann () (fmap tm_to_ty v) sig)
tm_to_ty (Unqual occ) = Unqual (setOccNameSpace tvName occ)
tm_to_ty _ = panic "mkRuleTyVarBndrs"
checkRuleTyVarBndrNames :: [LHsTyVarBndr flag GhcPs] -> P ()
checkRuleTyVarBndrNames = mapM_ (check . fmap hsTyVarName)
where check (L loc (Unqual occ)) =
when ((occNameString occ ==) `any` ["forall","family","role"])
(addFatalError $ PsError (PsErrParseErrorOnInput occ) [] (locA loc))
check _ = panic "checkRuleTyVarBndrNames"
checkRecordSyntax :: (MonadP m, Outputable a) => LocatedA a -> m (LocatedA a)
checkRecordSyntax lr@(L loc r)
= do allowed <- getBit TraditionalRecordSyntaxBit
unless allowed $ addError $ PsError (PsErrIllegalTraditionalRecordSyntax (ppr r)) [] (locA loc)
return lr
checkEmptyGADTs :: Located ([AddEpAnn], [LConDecl GhcPs])
-> P (Located ([AddEpAnn], [LConDecl GhcPs]))
checkEmptyGADTs gadts@(L span (_, []))
= do gadtSyntax <- getBit GadtSyntaxBit
unless gadtSyntax $ addError $ PsError PsErrIllegalWhereInDataDecl [] span
return gadts
checkEmptyGADTs gadts = return gadts
checkTyClHdr :: Bool
-> LHsType GhcPs
-> P (LocatedN RdrName,
[LHsTypeArg GhcPs],
LexicalFixity,
[AddEpAnn])
checkTyClHdr is_cls ty
= goL ty [] [] Prefix
where
goL (L l ty) acc ann fix = go (locA l) ty acc ann fix
go _ (HsParTy an (L l (HsStarTy _ isUni))) acc ann' fix
= do { addWarning Opt_WarnStarBinder (PsWarnStarBinder (locA l))
; let name = mkOccName tcClsName (starSym isUni)
; let a' = newAnns l an
; return (L a' (Unqual name), acc, fix
, ann') }
go _ (HsTyVar _ _ ltc@(L _ tc)) acc ann fix
| isRdrTc tc = return (ltc, acc, fix, ann)
go _ (HsOpTy _ t1 ltc@(L _ tc) t2) acc ann _fix
| isRdrTc tc = return (ltc, HsValArg t1:HsValArg t2:acc, Infix, ann)
go l (HsParTy _ ty) acc ann fix = goL ty acc (ann ++mkParensEpAnn l) fix
go _ (HsAppTy _ t1 t2) acc ann fix = goL t1 (HsValArg t2:acc) ann fix
go _ (HsAppKindTy l ty ki) acc ann fix = goL ty (HsTypeArg l ki:acc) ann fix
go l (HsTupleTy _ HsBoxedOrConstraintTuple ts) [] ann fix
= return (L (noAnnSrcSpan l) (nameRdrName tup_name)
, map HsValArg ts, fix, ann)
where
arity = length ts
tup_name | is_cls = cTupleTyConName arity
| otherwise = getName (tupleTyCon Boxed arity)
go l _ _ _ _
= addFatalError $ PsError (PsErrMalformedTyOrClDecl ty) [] l
newAnns :: SrcSpanAnnA -> EpAnn' AnnParen -> SrcSpanAnnN
newAnns (SrcSpanAnn EpAnnNotUsed l) (EpAnn as (AnnParen _ o c) cs) =
let
lr = combineRealSrcSpans (realSrcSpan l) (anchor as)
an = (EpAnn (Anchor lr UnchangedAnchor) (NameAnn NameParens o (AR $ realSrcSpan l) c []) cs)
in SrcSpanAnn an (RealSrcSpan lr Nothing)
newAnns _ EpAnnNotUsed = panic "missing AnnParen"
newAnns (SrcSpanAnn (EpAnn ap (AnnListItem ta) csp) l) (EpAnn as (AnnParen _ o c) cs) =
let
lr = combineRealSrcSpans (anchor ap) (anchor as)
an = (EpAnn (Anchor lr UnchangedAnchor) (NameAnn NameParens o (AR $ realSrcSpan l) c ta) (csp Semi.<> cs))
in SrcSpanAnn an (RealSrcSpan lr Nothing)
checkExpBlockArguments :: LHsExpr GhcPs -> PV ()
checkCmdBlockArguments :: LHsCmd GhcPs -> PV ()
(checkExpBlockArguments, checkCmdBlockArguments) = (checkExpr, checkCmd)
where
checkExpr :: LHsExpr GhcPs -> PV ()
checkExpr expr = case unLoc expr of
HsDo _ (DoExpr m) _ -> check (PsErrDoInFunAppExpr m) expr
HsDo _ (MDoExpr m) _ -> check (PsErrMDoInFunAppExpr m) expr
HsLam {} -> check PsErrLambdaInFunAppExpr expr
HsCase {} -> check PsErrCaseInFunAppExpr expr
HsLamCase {} -> check PsErrLambdaCaseInFunAppExpr expr
HsLet {} -> check PsErrLetInFunAppExpr expr
HsIf {} -> check PsErrIfInFunAppExpr expr
HsProc {} -> check PsErrProcInFunAppExpr expr
_ -> return ()
checkCmd :: LHsCmd GhcPs -> PV ()
checkCmd cmd = case unLoc cmd of
HsCmdLam {} -> check PsErrLambdaCmdInFunAppCmd cmd
HsCmdCase {} -> check PsErrCaseCmdInFunAppCmd cmd
HsCmdIf {} -> check PsErrIfCmdInFunAppCmd cmd
HsCmdLet {} -> check PsErrLetCmdInFunAppCmd cmd
HsCmdDo {} -> check PsErrDoCmdInFunAppCmd cmd
_ -> return ()
check err a = do
blockArguments <- getBit BlockArgumentsBit
unless blockArguments $
addError $ PsError (err a) [] (getLocA a)
checkContext :: LHsType GhcPs -> P (LHsContext GhcPs)
checkContext orig_t@(L (SrcSpanAnn _ l) _orig_t) =
check ([],[],noCom) orig_t
where
check :: ([EpaAnchor],[EpaAnchor],EpAnnComments)
-> LHsType GhcPs -> P (LHsContext GhcPs)
check (oparens,cparens,cs) (L _l (HsTupleTy ann' HsBoxedOrConstraintTuple ts))
= do
let (op,cp,cs') = case ann' of
EpAnnNotUsed -> ([],[],noCom)
EpAnn _ (AnnParen _ o c) cs -> ([o],[c],cs)
return (L (SrcSpanAnn (EpAnn (spanAsAnchor l)
(AnnContext Nothing (op Semi.<> oparens) (cp Semi.<> cparens)) (cs Semi.<> cs')) l) ts)
check (opi,cpi,csi) (L _lp1 (HsParTy ann' ty))
= do
let (op,cp,cs') = case ann' of
EpAnnNotUsed -> ([],[],noCom)
EpAnn _ (AnnParen _ open close ) cs -> ([open],[close],cs)
check (op++opi,cp++cpi,cs' Semi.<> csi) ty
check (_opi,_cpi,_csi) _t =
return (L (SrcSpanAnn (EpAnn (spanAsAnchor l) (AnnContext Nothing [] []) noCom) l) [orig_t])
checkImportDecl :: Maybe EpaAnchor
-> Maybe EpaAnchor
-> P ()
checkImportDecl mPre mPost = do
let whenJust mg f = maybe (pure ()) f mg
importQualifiedPostEnabled <- getBit ImportQualifiedPostBit
whenJust mPost $ \post ->
when (not importQualifiedPostEnabled) $
failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaAnchorRealSrcSpan post) Nothing)
whenJust mPost $ \post ->
when (isJust mPre) $
failOpImportQualifiedTwice (RealSrcSpan (epaAnchorRealSrcSpan post) Nothing)
whenJust mPre $ \pre ->
warnPrepositiveQualifiedModule (RealSrcSpan (epaAnchorRealSrcSpan pre) Nothing)
checkPattern :: LocatedA (PatBuilder GhcPs) -> P (LPat GhcPs)
checkPattern = runPV . checkLPat
checkPattern_hints :: [Hint] -> PV (LocatedA (PatBuilder GhcPs)) -> P (LPat GhcPs)
checkPattern_hints hints pp = runPV_hints hints (pp >>= checkLPat)
checkLPat :: LocatedA (PatBuilder GhcPs) -> PV (LPat GhcPs)
checkLPat e@(L l _) = checkPat l e [] []
checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsPatSigType GhcPs] -> [LPat GhcPs]
-> PV (LPat GhcPs)
checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args
| isRdrDataCon c = return . L loc $ ConPat
{ pat_con_ext = noAnn
, pat_con = L ln c
, pat_args = PrefixCon tyargs args
}
| not (null tyargs) =
add_hint TypeApplicationsInPatternsOnlyDataCons $
patFail (locA l) (ppr e <+> hsep [text "@" <> ppr t | t <- tyargs])
| not (null args) && patIsRec c =
add_hint SuggestRecursiveDo $
patFail (locA l) (ppr e)
checkPat loc (L _ (PatBuilderAppType f _ t)) tyargs args =
checkPat loc f (t : tyargs) args
checkPat loc (L _ (PatBuilderApp f e)) [] args = do
p <- checkLPat e
checkPat loc f [] (p : args)
checkPat loc (L l e) [] [] = do
p <- checkAPat loc e
return (L l p)
checkPat loc e _ _ = patFail (locA loc) (ppr e)
checkAPat :: SrcSpanAnnA -> PatBuilder GhcPs -> PV (Pat GhcPs)
checkAPat loc e0 = do
nPlusKPatterns <- getBit NPlusKPatternsBit
case e0 of
PatBuilderPat p -> return p
PatBuilderVar x -> return (VarPat noExtField x)
PatBuilderOverLit pos_lit -> return (mkNPat (L (locA loc) pos_lit) Nothing noAnn)
PatBuilderOpApp
(L _ (PatBuilderVar (L nloc n)))
(L _ plus)
(L lloc (PatBuilderOverLit lit@(OverLit {ol_val = HsIntegral {}})))
anns
| nPlusKPatterns && (plus == plus_RDR)
-> return (mkNPlusKPat (L nloc n) (L (locA lloc) lit) anns)
PatBuilderOpApp _ op _ _ | opIsAt (unLoc op) -> do
addError $ PsError PsErrAtInPatPos [] (getLocA op)
return (WildPat noExtField)
PatBuilderOpApp l (L cl c) r anns
| isRdrDataCon c -> do
l <- checkLPat l
r <- checkLPat r
return $ ConPat
{ pat_con_ext = anns
, pat_con = L cl c
, pat_args = InfixCon l r
}
PatBuilderPar e an@(AnnParen pt o c) -> do
(L l p) <- checkLPat e
let aa = [AddEpAnn ai o, AddEpAnn ac c]
(ai,ac) = parenTypeKws pt
return (ParPat (EpAnn (spanAsAnchor $ (widenSpan (locA l) aa)) an noCom) (L l p))
_ -> patFail (locA loc) (ppr e0)
placeHolderPunRhs :: DisambECP b => PV (LocatedA b)
placeHolderPunRhs = mkHsVarPV (noLocA pun_RDR)
plus_RDR, pun_RDR :: RdrName
plus_RDR = mkUnqual varName (fsLit "+")
pun_RDR = mkUnqual varName (fsLit "pun-right-hand-side")
checkPatField :: LHsRecField GhcPs (LocatedA (PatBuilder GhcPs))
-> PV (LHsRecField GhcPs (LPat GhcPs))
checkPatField (L l fld) = do p <- checkLPat (hsRecFieldArg fld)
return (L l (fld { hsRecFieldArg = p }))
patFail :: SrcSpan -> SDoc -> PV a
patFail loc e = addFatalError $ PsError (PsErrParseErrorInPat e) [] loc
patIsRec :: RdrName -> Bool
patIsRec e = e == mkUnqual varName (fsLit "rec")
checkValDef :: SrcSpan
-> LocatedA (PatBuilder GhcPs)
-> Maybe (AddEpAnn, LHsType GhcPs)
-> Located (GRHSs GhcPs (LHsExpr GhcPs))
-> P (HsBind GhcPs)
checkValDef loc lhs (Just (sigAnn, sig)) grhss
= do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn]
>>= checkLPat
checkPatBind loc [] lhs' grhss
checkValDef loc lhs Nothing g@(L l grhss)
= do { mb_fun <- isFunLhs lhs
; case mb_fun of
Just (fun, is_infix, pats, ann) ->
checkFunBind NoSrcStrict loc ann (getLocA lhs)
fun is_infix pats (L l grhss)
Nothing -> do
lhs' <- checkPattern lhs
checkPatBind loc [] lhs' g }
checkFunBind :: SrcStrictness
-> SrcSpan
-> [AddEpAnn]
-> SrcSpan
-> LocatedN RdrName
-> LexicalFixity
-> [LocatedA (PatBuilder GhcPs)]
-> Located (GRHSs GhcPs (LHsExpr GhcPs))
-> P (HsBind GhcPs)
checkFunBind strictness locF ann lhs_loc fun is_infix pats (L rhs_span grhss)
= do ps <- runPV_hints param_hints (mapM checkLPat pats)
let match_span = noAnnSrcSpan $ combineSrcSpans lhs_loc rhs_span
cs <- getCommentsFor locF
return (makeFunBind fun (L (noAnnSrcSpan $ locA match_span)
[L match_span (Match { m_ext = EpAnn (spanAsAnchor locF) ann cs
, m_ctxt = FunRhs
{ mc_fun = fun
, mc_fixity = is_infix
, mc_strictness = strictness }
, m_pats = ps
, m_grhss = grhss })]))
where
param_hints
| Infix <- is_infix = [SuggestInfixBindMaybeAtPat (unLoc fun)]
| otherwise = []
makeFunBind :: LocatedN RdrName -> LocatedL [LMatch GhcPs (LHsExpr GhcPs)]
-> HsBind GhcPs
makeFunBind fn ms
= FunBind { fun_ext = noExtField,
fun_id = fn,
fun_matches = mkMatchGroup FromSource ms,
fun_tick = [] }
checkPatBind :: SrcSpan
-> [AddEpAnn]
-> LPat GhcPs
-> Located (GRHSs GhcPs (LHsExpr GhcPs))
-> P (HsBind GhcPs)
checkPatBind loc annsIn (L _ (BangPat (EpAnn _ ans cs) (L _ (VarPat _ v))))
(L _match_span grhss)
= return (makeFunBind v (L (noAnnSrcSpan loc)
[L (noAnnSrcSpan loc) (m (EpAnn (spanAsAnchor loc) (ans++annsIn) cs) v)]))
where
m a v = Match { m_ext = a
, m_ctxt = FunRhs { mc_fun = v
, mc_fixity = Prefix
, mc_strictness = SrcStrict }
, m_pats = []
, m_grhss = grhss }
checkPatBind loc annsIn lhs (L _ grhss) = do
cs <- getCommentsFor loc
return (PatBind (EpAnn (spanAsAnchor loc) annsIn cs) lhs grhss ([],[]))
checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName)
checkValSigLhs (L _ (HsVar _ lrdr@(L _ v)))
| isUnqual v
, not (isDataOcc (rdrNameOcc v))
= return lrdr
checkValSigLhs lhs@(L l _)
= addFatalError $ PsError (PsErrInvalidTypeSignature lhs) [] (locA l)
checkDoAndIfThenElse
:: (Outputable a, Outputable b, Outputable c)
=> (a -> Bool -> b -> Bool -> c -> PsErrorDesc)
-> LocatedA a -> Bool -> LocatedA b -> Bool -> LocatedA c -> PV ()
checkDoAndIfThenElse err guardExpr semiThen thenExpr semiElse elseExpr
| semiThen || semiElse = do
doAndIfThenElse <- getBit DoAndIfThenElseBit
let e = err (unLoc guardExpr)
semiThen (unLoc thenExpr)
semiElse (unLoc elseExpr)
loc = combineLocs (reLoc guardExpr) (reLoc elseExpr)
unless doAndIfThenElse $ addError (PsError e [] loc)
| otherwise = return ()
isFunLhs :: LocatedA (PatBuilder GhcPs)
-> P (Maybe (LocatedN RdrName, LexicalFixity,
[LocatedA (PatBuilder GhcPs)],[AddEpAnn]))
isFunLhs e = go e [] []
where
go (L _ (PatBuilderVar (L loc f))) es ann
| not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, ann))
go (L _ (PatBuilderApp f e)) es ann = go f (e:es) ann
go (L l (PatBuilderPar e _an)) es@(_:_) ann
= go e es (ann ++ mkParensEpAnn (locA l))
go (L loc (PatBuilderOpApp l (L loc' op) r (EpAnn loca anns cs))) es ann
| not (isRdrDataCon op)
= return (Just (L loc' op, Infix, (l:r:es), (anns ++ ann)))
| otherwise
= do { mb_l <- go l es ann
; case mb_l of
Just (op', Infix, j : k : es', ann')
-> return (Just (op', Infix, j : op_app : es', ann'))
where
op_app = L loc (PatBuilderOpApp k
(L loc' op) r (EpAnn loca anns cs))
_ -> return Nothing }
go _ _ _ = return Nothing
mkBangTy :: EpAnn -> SrcStrictness -> LHsType GhcPs -> HsType GhcPs
mkBangTy anns strictness =
HsBangTy anns (HsSrcBang NoSourceText NoSrcUnpack strictness)
data UnpackednessPragma =
UnpackednessPragma [AddEpAnn] SourceText SrcUnpackedness
addUnpackednessP :: MonadP m => Located UnpackednessPragma -> LHsType GhcPs -> m (LHsType GhcPs)
addUnpackednessP (L lprag (UnpackednessPragma anns prag unpk)) ty = do
let l' = combineSrcSpans lprag (getLocA ty)
cs <- getCommentsFor l'
let an = EpAnn (spanAsAnchor l') anns cs
t' = addUnpackedness an ty
return (L (noAnnSrcSpan l') t')
where
addUnpackedness an (L _ (HsBangTy x bang t))
| HsSrcBang NoSourceText NoSrcUnpack strictness <- bang
= HsBangTy (addAnns an (epAnnAnns x) (epAnnComments x)) (HsSrcBang prag unpk strictness) t
addUnpackedness an t
= HsBangTy an (HsSrcBang prag unpk NoSrcStrict) t
checkMonadComp :: PV (HsStmtContext GhcRn)
checkMonadComp = do
monadComprehensions <- getBit MonadComprehensionsBit
return $ if monadComprehensions
then MonadComp
else ListComp
newtype ECP =
ECP { unECP :: forall b. DisambECP b => PV (LocatedA b) }
ecpFromExp :: LHsExpr GhcPs -> ECP
ecpFromExp a = ECP (ecpFromExp' a)
ecpFromCmd :: LHsCmd GhcPs -> ECP
ecpFromCmd a = ECP (ecpFromCmd' a)
type Fbind b = Either (LHsRecField GhcPs (LocatedA b)) (LHsRecProj GhcPs (LocatedA b))
class DisambInfixOp b where
mkHsVarOpPV :: LocatedN RdrName -> PV (LocatedN b)
mkHsConOpPV :: LocatedN RdrName -> PV (LocatedN b)
mkHsInfixHolePV :: SrcSpan -> (EpAnnComments -> EpAnn' EpAnnUnboundVar) -> PV (Located b)
instance DisambInfixOp (HsExpr GhcPs) where
mkHsVarOpPV v = return $ L (getLoc v) (HsVar noExtField v)
mkHsConOpPV v = return $ L (getLoc v) (HsVar noExtField v)
mkHsInfixHolePV l ann = do
cs <- getCommentsFor l
return $ L l (hsHoleExpr (ann cs))
instance DisambInfixOp RdrName where
mkHsConOpPV (L l v) = return $ L l v
mkHsVarOpPV (L l v) = return $ L l v
mkHsInfixHolePV l _ = addFatalError $ PsError PsErrInvalidInfixHole [] l
type AnnoBody b
= ( Anno (GRHS GhcPs (LocatedA (Body b GhcPs))) ~ SrcSpan
, Anno [LocatedA (Match GhcPs (LocatedA (Body b GhcPs)))] ~ SrcSpanAnnL
, Anno (Match GhcPs (LocatedA (Body b GhcPs))) ~ SrcSpanAnnA
, Anno (StmtLR GhcPs GhcPs (LocatedA (Body (Body b GhcPs) GhcPs))) ~ SrcSpanAnnA
, Anno [LocatedA (StmtLR GhcPs GhcPs
(LocatedA (Body (Body (Body b GhcPs) GhcPs) GhcPs)))] ~ SrcSpanAnnL
)
class (b ~ (Body b) GhcPs, AnnoBody b) => DisambECP b where
type Body b :: Type -> Type
ecpFromCmd' :: LHsCmd GhcPs -> PV (LocatedA b)
ecpFromExp' :: LHsExpr GhcPs -> PV (LocatedA b)
mkHsProjUpdatePV :: SrcSpan -> Located [Located (HsFieldLabel GhcPs)]
-> LocatedA b -> Bool -> [AddEpAnn] -> PV (LHsRecProj GhcPs (LocatedA b))
mkHsLamPV
:: SrcSpan -> (EpAnnComments -> MatchGroup GhcPs (LocatedA b)) -> PV (LocatedA b)
mkHsLetPV
:: SrcSpan -> HsLocalBinds GhcPs -> LocatedA b -> AnnsLet -> PV (LocatedA b)
type InfixOp b
superInfixOp
:: (DisambInfixOp (InfixOp b) => PV (LocatedA b )) -> PV (LocatedA b)
mkHsOpAppPV :: SrcSpan -> LocatedA b -> LocatedN (InfixOp b) -> LocatedA b
-> PV (LocatedA b)
mkHsCasePV :: SrcSpan -> LHsExpr GhcPs -> (LocatedL [LMatch GhcPs (LocatedA b)])
-> EpAnnHsCase -> PV (LocatedA b)
mkHsLamCasePV :: SrcSpan -> (LocatedL [LMatch GhcPs (LocatedA b)])
-> [AddEpAnn]
-> PV (LocatedA b)
type FunArg b
superFunArg :: (DisambECP (FunArg b) => PV (LocatedA b)) -> PV (LocatedA b)
mkHsAppPV :: SrcSpanAnnA -> LocatedA b -> LocatedA (FunArg b) -> PV (LocatedA b)
mkHsAppTypePV :: SrcSpanAnnA -> LocatedA b -> SrcSpan -> LHsType GhcPs -> PV (LocatedA b)
mkHsIfPV :: SrcSpan
-> LHsExpr GhcPs
-> Bool
-> LocatedA b
-> Bool
-> LocatedA b
-> [AddEpAnn]
-> PV (LocatedA b)
mkHsDoPV ::
SrcSpan ->
Maybe ModuleName ->
LocatedL [LStmt GhcPs (LocatedA b)] ->
AnnList ->
PV (LocatedA b)
mkHsParPV :: SrcSpan -> LocatedA b -> AnnParen -> PV (LocatedA b)
mkHsVarPV :: LocatedN RdrName -> PV (LocatedA b)
mkHsLitPV :: Located (HsLit GhcPs) -> PV (Located b)
mkHsOverLitPV :: Located (HsOverLit GhcPs) -> PV (Located b)
mkHsWildCardPV :: SrcSpan -> PV (Located b)
mkHsTySigPV
:: SrcSpanAnnA -> LocatedA b -> LHsType GhcPs -> [AddEpAnn] -> PV (LocatedA b)
mkHsExplicitListPV :: SrcSpan -> [LocatedA b] -> AnnList -> PV (LocatedA b)
mkHsSplicePV :: Located (HsSplice GhcPs) -> PV (Located b)
mkHsRecordPV ::
Bool ->
SrcSpan ->
SrcSpan ->
LocatedA b ->
([Fbind b], Maybe SrcSpan) ->
[AddEpAnn] ->
PV (LocatedA b)
mkHsNegAppPV :: SrcSpan -> LocatedA b -> [AddEpAnn] -> PV (LocatedA b)
mkHsSectionR_PV
:: SrcSpan -> LocatedA (InfixOp b) -> LocatedA b -> PV (Located b)
mkHsViewPatPV
:: SrcSpan -> LHsExpr GhcPs -> LocatedA b -> [AddEpAnn] -> PV (LocatedA b)
mkHsAsPatPV
:: SrcSpan -> LocatedN RdrName -> LocatedA b -> [AddEpAnn] -> PV (LocatedA b)
mkHsLazyPatPV :: SrcSpan -> LocatedA b -> [AddEpAnn] -> PV (LocatedA b)
mkHsBangPatPV :: SrcSpan -> LocatedA b -> [AddEpAnn] -> PV (LocatedA b)
mkSumOrTuplePV
:: SrcSpanAnnA -> Boxity -> SumOrTuple b -> [AddEpAnn] -> PV (LocatedA b)
rejectPragmaPV :: LocatedA b -> PV ()
instance DisambECP (HsCmd GhcPs) where
type Body (HsCmd GhcPs) = HsCmd
ecpFromCmd' = return
ecpFromExp' (L l e) = cmdFail (locA l) (ppr e)
mkHsProjUpdatePV l _ _ _ _ = addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
mkHsLamPV l mg = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdLam NoExtField (mg cs))
mkHsLetPV l bs e anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdLet (EpAnn (spanAsAnchor l) anns cs) bs e)
type InfixOp (HsCmd GhcPs) = HsExpr GhcPs
superInfixOp m = m
mkHsOpAppPV l c1 op c2 = do
let cmdArg c = L (getLocA c) $ HsCmdTop noExtField c
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) $ HsCmdArrForm (EpAnn (spanAsAnchor l) (AnnList Nothing Nothing Nothing [] []) cs) (reLocL op) Infix Nothing [cmdArg c1, cmdArg c2]
mkHsCasePV l c (L lm m) anns = do
cs <- getCommentsFor l
let mg = mkMatchGroup FromSource (L lm m)
return $ L (noAnnSrcSpan l) (HsCmdCase (EpAnn (spanAsAnchor l) anns cs) c mg)
mkHsLamCasePV l (L lm m) anns = do
cs <- getCommentsFor l
let mg = mkMatchGroup FromSource (L lm m)
return $ L (noAnnSrcSpan l) (HsCmdLamCase (EpAnn (spanAsAnchor l) anns cs) mg)
type FunArg (HsCmd GhcPs) = HsExpr GhcPs
superFunArg m = m
mkHsAppPV l c e = do
cs <- getCommentsFor (locA l)
checkCmdBlockArguments c
checkExpBlockArguments e
return $ L l (HsCmdApp (comment (realSrcSpan $ locA l) cs) c e)
mkHsAppTypePV l c _ t = cmdFail (locA l) (ppr c <+> text "@" <> ppr t)
mkHsIfPV l c semi1 a semi2 b anns = do
checkDoAndIfThenElse PsErrSemiColonsInCondCmd c semi1 a semi2 b
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (mkHsCmdIf c a b (EpAnn (spanAsAnchor l) anns cs))
mkHsDoPV l Nothing stmts anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdDo (EpAnn (spanAsAnchor l) anns cs) stmts)
mkHsDoPV l (Just m) _ _ = addFatalError $ PsError (PsErrQualifiedDoInCmd m) [] l
mkHsParPV l c ann = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdPar (EpAnn (spanAsAnchor l) ann cs) c)
mkHsVarPV (L l v) = cmdFail (locA l) (ppr v)
mkHsLitPV (L l a) = cmdFail l (ppr a)
mkHsOverLitPV (L l a) = cmdFail l (ppr a)
mkHsWildCardPV l = cmdFail l (text "_")
mkHsTySigPV l a sig _ = cmdFail (locA l) (ppr a <+> text "::" <+> ppr sig)
mkHsExplicitListPV l xs _ = cmdFail l $
brackets (fsep (punctuate comma (map ppr xs)))
mkHsSplicePV (L l sp) = cmdFail l (ppr sp)
mkHsRecordPV _ l _ a (fbinds, ddLoc) _ = do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
else cmdFail l $ ppr a <+> ppr (mk_rec_fields fs ddLoc)
mkHsNegAppPV l a _ = cmdFail l (text "-" <> ppr a)
mkHsSectionR_PV l op c = cmdFail l $
let pp_op = fromMaybe (panic "cannot print infix operator")
(ppr_infix_expr (unLoc op))
in pp_op <> ppr c
mkHsViewPatPV l a b _ = cmdFail l $
ppr a <+> text "->" <+> ppr b
mkHsAsPatPV l v c _ = cmdFail l $
pprPrefixOcc (unLoc v) <> text "@" <> ppr c
mkHsLazyPatPV l c _ = cmdFail l $
text "~" <> ppr c
mkHsBangPatPV l c _ = cmdFail l $
text "!" <> ppr c
mkSumOrTuplePV l boxity a _ = cmdFail (locA l) (pprSumOrTuple boxity a)
rejectPragmaPV _ = return ()
cmdFail :: SrcSpan -> SDoc -> PV a
cmdFail loc e = addFatalError $ PsError (PsErrParseErrorInCmd e) [] loc
instance DisambECP (HsExpr GhcPs) where
type Body (HsExpr GhcPs) = HsExpr
ecpFromCmd' (L l c) = do
addError $ PsError (PsErrArrowCmdInExpr c) [] (locA l)
return (L l (hsHoleExpr noAnn))
ecpFromExp' = return
mkHsProjUpdatePV l fields arg isPun anns = do
cs <- getCommentsFor l
return $ mkRdrProjUpdate (noAnnSrcSpan l) fields arg isPun (EpAnn (spanAsAnchor l) anns cs)
mkHsLamPV l mg = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsLam NoExtField (mg cs))
mkHsLetPV l bs c anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsLet (EpAnn (spanAsAnchor l) anns cs) bs c)
type InfixOp (HsExpr GhcPs) = HsExpr GhcPs
superInfixOp m = m
mkHsOpAppPV l e1 op e2 = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) $ OpApp (EpAnn (spanAsAnchor l) [] cs) e1 (reLocL op) e2
mkHsCasePV l e (L lm m) anns = do
cs <- getCommentsFor l
let mg = mkMatchGroup FromSource (L lm m)
return $ L (noAnnSrcSpan l) (HsCase (EpAnn (spanAsAnchor l) anns cs) e mg)
mkHsLamCasePV l (L lm m) anns = do
cs <- getCommentsFor l
let mg = mkMatchGroup FromSource (L lm m)
return $ L (noAnnSrcSpan l) (HsLamCase (EpAnn (spanAsAnchor l) anns cs) mg)
type FunArg (HsExpr GhcPs) = HsExpr GhcPs
superFunArg m = m
mkHsAppPV l e1 e2 = do
cs <- getCommentsFor (locA l)
checkExpBlockArguments e1
checkExpBlockArguments e2
return $ L l (HsApp (comment (realSrcSpan $ locA l) cs) e1 e2)
mkHsAppTypePV l e la t = do
checkExpBlockArguments e
return $ L l (HsAppType la e (mkHsWildCardBndrs t))
mkHsIfPV l c semi1 a semi2 b anns = do
checkDoAndIfThenElse PsErrSemiColonsInCondExpr c semi1 a semi2 b
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (mkHsIf c a b (EpAnn (spanAsAnchor l) anns cs))
mkHsDoPV l mod stmts anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsDo (EpAnn (spanAsAnchor l) anns cs) (DoExpr mod) stmts)
mkHsParPV l e ann = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsPar (EpAnn (spanAsAnchor l) ann cs) e)
mkHsVarPV v@(L l _) = return $ L (na2la l) (HsVar noExtField v)
mkHsLitPV (L l a) = do
cs <- getCommentsFor l
return $ L l (HsLit (comment (realSrcSpan l) cs) a)
mkHsOverLitPV (L l a) = do
cs <- getCommentsFor l
return $ L l (HsOverLit (comment (realSrcSpan l) cs) a)
mkHsWildCardPV l = return $ L l (hsHoleExpr noAnn)
mkHsTySigPV l a sig anns = do
cs <- getCommentsFor (locA l)
return $ L l (ExprWithTySig (EpAnn (spanAsAnchor $ locA l) anns cs) a (hsTypeToHsSigWcType sig))
mkHsExplicitListPV l xs anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (ExplicitList (EpAnn (spanAsAnchor l) anns cs) xs)
mkHsSplicePV sp@(L l _) = do
cs <- getCommentsFor l
return $ mapLoc (HsSpliceE (EpAnn (spanAsAnchor l) NoEpAnns cs)) sp
mkHsRecordPV opts l lrec a (fbinds, ddLoc) anns = do
cs <- getCommentsFor l
r <- mkRecConstrOrUpdate opts a lrec (fbinds, ddLoc) (EpAnn (spanAsAnchor l) anns cs)
checkRecordSyntax (L (noAnnSrcSpan l) r)
mkHsNegAppPV l a anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (NegApp (EpAnn (spanAsAnchor l) anns cs) a noSyntaxExpr)
mkHsSectionR_PV l op e = do
cs <- getCommentsFor l
return $ L l (SectionR (comment (realSrcSpan l) cs) op e)
mkHsViewPatPV l a b _ = addError (PsError (PsErrViewPatInExpr a b) [] l)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
mkHsAsPatPV l v e _ = addError (PsError (PsErrTypeAppWithoutSpace (unLoc v) e) [] l)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
mkHsLazyPatPV l e _ = addError (PsError (PsErrLazyPatWithoutSpace e) [] l)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
mkHsBangPatPV l e _ = addError (PsError (PsErrBangPatWithoutSpace e) [] l)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
mkSumOrTuplePV = mkSumOrTupleExpr
rejectPragmaPV (L _ (OpApp _ _ _ e)) =
rejectPragmaPV e
rejectPragmaPV (L l (HsPragE _ prag _)) = addError $ PsError (PsErrUnallowedPragma prag) [] (locA l)
rejectPragmaPV _ = return ()
hsHoleExpr :: EpAnn' EpAnnUnboundVar -> HsExpr GhcPs
hsHoleExpr anns = HsUnboundVar anns (mkVarOcc "_")
type instance Anno (GRHS GhcPs (LocatedA (PatBuilder GhcPs))) = SrcSpan
type instance Anno [LocatedA (Match GhcPs (LocatedA (PatBuilder GhcPs)))] = SrcSpanAnnL
type instance Anno (Match GhcPs (LocatedA (PatBuilder GhcPs))) = SrcSpanAnnA
type instance Anno (StmtLR GhcPs GhcPs (LocatedA (PatBuilder GhcPs))) = SrcSpanAnnA
instance DisambECP (PatBuilder GhcPs) where
type Body (PatBuilder GhcPs) = PatBuilder
ecpFromCmd' (L l c) = addFatalError $ PsError (PsErrArrowCmdInPat c) [] (locA l)
ecpFromExp' (L l e) = addFatalError $ PsError (PsErrArrowExprInPat e) [] (locA l)
mkHsLamPV l _ = addFatalError $ PsError PsErrLambdaInPat [] l
mkHsLetPV l _ _ _ = addFatalError $ PsError PsErrLetInPat [] l
mkHsProjUpdatePV l _ _ _ _ = addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
type InfixOp (PatBuilder GhcPs) = RdrName
superInfixOp m = m
mkHsOpAppPV l p1 op p2 = do
cs <- getCommentsFor l
let anns = EpAnn (spanAsAnchor l) [] cs
return $ L (noAnnSrcSpan l) $ PatBuilderOpApp p1 op p2 anns
mkHsCasePV l _ _ _ = addFatalError $ PsError PsErrCaseInPat [] l
mkHsLamCasePV l _ _ = addFatalError $ PsError PsErrLambdaCaseInPat [] l
type FunArg (PatBuilder GhcPs) = PatBuilder GhcPs
superFunArg m = m
mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2)
mkHsAppTypePV l p la t = return $ L l (PatBuilderAppType p la (mkHsPatSigType t))
mkHsIfPV l _ _ _ _ _ _ = addFatalError $ PsError PsErrIfTheElseInPat [] l
mkHsDoPV l _ _ _ = addFatalError $ PsError PsErrDoNotationInPat [] l
mkHsParPV l p an = return $ L (noAnnSrcSpan l) (PatBuilderPar p an)
mkHsVarPV v@(getLoc -> l) = return $ L (na2la l) (PatBuilderVar v)
mkHsLitPV lit@(L l a) = do
checkUnboxedStringLitPat lit
return $ L l (PatBuilderPat (LitPat noExtField a))
mkHsOverLitPV (L l a) = return $ L l (PatBuilderOverLit a)
mkHsWildCardPV l = return $ L l (PatBuilderPat (WildPat noExtField))
mkHsTySigPV l b sig anns = do
p <- checkLPat b
cs <- getCommentsFor (locA l)
return $ L l (PatBuilderPat (SigPat (EpAnn (spanAsAnchor $ locA l) anns cs) p (mkHsPatSigType sig)))
mkHsExplicitListPV l xs anns = do
ps <- traverse checkLPat xs
cs <- getCommentsFor l
return (L (noAnnSrcSpan l) (PatBuilderPat (ListPat (EpAnn (spanAsAnchor l) anns cs) ps)))
mkHsSplicePV (L l sp) = return $ L l (PatBuilderPat (SplicePat noExtField sp))
mkHsRecordPV _ l _ a (fbinds, ddLoc) anns = do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
else do
cs <- getCommentsFor l
r <- mkPatRec a (mk_rec_fields fs ddLoc) (EpAnn (spanAsAnchor l) anns cs)
checkRecordSyntax (L (noAnnSrcSpan l) r)
mkHsNegAppPV l (L lp p) anns = do
lit <- case p of
PatBuilderOverLit pos_lit -> return (L (locA lp) pos_lit)
_ -> patFail l (text "-" <> ppr p)
cs <- getCommentsFor l
let an = EpAnn (spanAsAnchor l) anns cs
return $ L (noAnnSrcSpan l) (PatBuilderPat (mkNPat lit (Just noSyntaxExpr) an))
mkHsSectionR_PV l op p = patFail l (pprInfixOcc (unLoc op) <> ppr p)
mkHsViewPatPV l a b anns = do
p <- checkLPat b
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (PatBuilderPat (ViewPat (EpAnn (spanAsAnchor l) anns cs) a p))
mkHsAsPatPV l v e a = do
p <- checkLPat e
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (PatBuilderPat (AsPat (EpAnn (spanAsAnchor l) a cs) v p))
mkHsLazyPatPV l e a = do
p <- checkLPat e
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (PatBuilderPat (LazyPat (EpAnn (spanAsAnchor l) a cs) p))
mkHsBangPatPV l e an = do
p <- checkLPat e
cs <- getCommentsFor l
let pb = BangPat (EpAnn (spanAsAnchor l) an cs) p
hintBangPat l pb
return $ L (noAnnSrcSpan l) (PatBuilderPat pb)
mkSumOrTuplePV = mkSumOrTuplePat
rejectPragmaPV _ = return ()
checkUnboxedStringLitPat :: Located (HsLit GhcPs) -> PV ()
checkUnboxedStringLitPat (L loc lit) =
case lit of
HsStringPrim _ _
-> addFatalError $ PsError (PsErrIllegalUnboxedStringInPat lit) [] loc
_ -> return ()
mkPatRec ::
LocatedA (PatBuilder GhcPs) ->
HsRecFields GhcPs (LocatedA (PatBuilder GhcPs)) ->
EpAnn ->
PV (PatBuilder GhcPs)
mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) anns
| isRdrDataCon (unLoc c)
= do fs <- mapM checkPatField fs
return $ PatBuilderPat $ ConPat
{ pat_con_ext = anns
, pat_con = c
, pat_args = RecCon (HsRecFields fs dd)
}
mkPatRec p _ _ =
addFatalError $ PsError (PsErrInvalidRecordCon (unLoc p)) [] (getLocA p)
class DisambTD b where
mkHsAppTyHeadPV :: LHsType GhcPs -> PV (LocatedA b)
mkHsAppTyPV :: LocatedA b -> LHsType GhcPs -> PV (LocatedA b)
mkHsAppKindTyPV :: LocatedA b -> SrcSpan -> LHsType GhcPs -> PV (LocatedA b)
mkHsOpTyPV :: LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> PV (LocatedA b)
mkUnpackednessPV :: Located UnpackednessPragma -> LocatedA b -> PV (LocatedA b)
instance DisambTD (HsType GhcPs) where
mkHsAppTyHeadPV = return
mkHsAppTyPV t1 t2 = return (mkHsAppTy t1 t2)
mkHsAppKindTyPV t l_at ki = return (mkHsAppKindTy l_at t ki)
mkHsOpTyPV t1 op t2 = return (mkLHsOpTy t1 op t2)
mkUnpackednessPV = addUnpackednessP
dataConBuilderCon :: DataConBuilder -> LocatedN RdrName
dataConBuilderCon (PrefixDataConBuilder _ dc) = dc
dataConBuilderCon (InfixDataConBuilder _ dc _) = dc
dataConBuilderDetails :: DataConBuilder -> HsConDeclH98Details GhcPs
dataConBuilderDetails (PrefixDataConBuilder flds _)
| [L l_t (HsRecTy an fields)] <- toList flds
= RecCon (L (SrcSpanAnn an (locA l_t)) fields)
dataConBuilderDetails (PrefixDataConBuilder flds _)
= PrefixCon noTypeArgs (map hsLinear (toList flds))
dataConBuilderDetails (InfixDataConBuilder lhs _ rhs)
= InfixCon (hsLinear lhs) (hsLinear rhs)
instance DisambTD DataConBuilder where
mkHsAppTyHeadPV = tyToDataConBuilder
mkHsAppTyPV (L l (PrefixDataConBuilder flds fn)) t =
return $
L (noAnnSrcSpan $ combineSrcSpans (locA l) (getLocA t))
(PrefixDataConBuilder (flds `snocOL` t) fn)
mkHsAppTyPV (L _ InfixDataConBuilder{}) _ =
panic "mkHsAppTyPV: InfixDataConBuilder"
mkHsAppKindTyPV lhs l_at ki =
addFatalError $ PsError (PsErrUnexpectedKindAppInDataCon (unLoc lhs) (unLoc ki)) [] l_at
mkHsOpTyPV lhs tc rhs = do
check_no_ops (unLoc rhs)
data_con <- eitherToP $ tyConToDataCon tc
return $ L l (InfixDataConBuilder lhs data_con rhs)
where
l = combineLocsA lhs rhs
check_no_ops (HsBangTy _ _ t) = check_no_ops (unLoc t)
check_no_ops (HsOpTy{}) =
addError $ PsError (PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs)) [] (locA l)
check_no_ops _ = return ()
mkUnpackednessPV unpk constr_stuff
| L _ (InfixDataConBuilder lhs data_con rhs) <- constr_stuff
=
do lhs' <- addUnpackednessP unpk lhs
let l = combineLocsA (reLocA unpk) constr_stuff
return $ L l (InfixDataConBuilder lhs' data_con rhs)
| otherwise =
do addError $ PsError PsErrUnpackDataCon [] (getLoc unpk)
return constr_stuff
tyToDataConBuilder :: LHsType GhcPs -> PV (LocatedA DataConBuilder)
tyToDataConBuilder (L l (HsTyVar _ NotPromoted v)) = do
data_con <- eitherToP $ tyConToDataCon v
return $ L l (PrefixDataConBuilder nilOL data_con)
tyToDataConBuilder (L l (HsTupleTy _ HsBoxedOrConstraintTuple ts)) = do
let data_con = L (l2l l) (getRdrName (tupleDataCon Boxed (length ts)))
return $ L l (PrefixDataConBuilder (toOL ts) data_con)
tyToDataConBuilder t =
addFatalError $ PsError (PsErrInvalidDataCon (unLoc t)) [] (getLocA t)
checkPrecP
:: Located (SourceText,Int)
-> Located (OrdList (LocatedN RdrName))
-> P ()
checkPrecP (L l (_,i)) (L _ ol)
| 0 <= i, i <= maxPrecedence = pure ()
| all specialOp ol = pure ()
| otherwise = addFatalError $ PsError (PsErrPrecedenceOutOfRange i) [] l
where
specialOp op = unLoc op `elem` [ eqTyCon_RDR
, getRdrName unrestrictedFunTyCon ]
mkRecConstrOrUpdate
:: Bool
-> LHsExpr GhcPs
-> SrcSpan
-> ([Fbind (HsExpr GhcPs)], Maybe SrcSpan)
-> EpAnn
-> PV (HsExpr GhcPs)
mkRecConstrOrUpdate _ (L _ (HsVar _ (L l c))) _lrec (fbinds,dd) anns
| isRdrDataCon c
= do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] (getLocA (head ps))
else return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns)
mkRecConstrOrUpdate overloaded_update exp _ (fs,dd) anns
| Just dd_loc <- dd = addFatalError $ PsError PsErrDotsInRecordUpdate [] dd_loc
| otherwise = mkRdrRecordUpd overloaded_update exp fs anns
mkRdrRecordUpd :: Bool -> LHsExpr GhcPs -> [Fbind (HsExpr GhcPs)] -> EpAnn -> PV (HsExpr GhcPs)
mkRdrRecordUpd overloaded_on exp@(L loc _) fbinds anns = do
let (fs, ps) = partitionEithers fbinds
fs' = map (fmap mk_rec_upd_field) fs
case overloaded_on of
False | not $ null ps ->
addFatalError $ PsError PsErrOverloadedRecordUpdateNotEnabled [] (locA loc)
False ->
return RecordUpd {
rupd_ext = anns
, rupd_expr = exp
, rupd_flds = Left fs' }
True -> do
let qualifiedFields =
[ L l lbl | L _ (HsRecField _ (L l lbl) _ _) <- fs'
, isQual . rdrNameAmbiguousFieldOcc $ lbl
]
if not $ null qualifiedFields
then
addFatalError $ PsError PsErrOverloadedRecordUpdateNoQualifiedFields [] (getLoc (head qualifiedFields))
else
return RecordUpd {
rupd_ext = anns
, rupd_expr = exp
, rupd_flds = Right (toProjUpdates fbinds) }
where
toProjUpdates :: [Fbind (HsExpr GhcPs)] -> [LHsRecUpdProj GhcPs]
toProjUpdates = map (\case { Right p -> p; Left f -> recFieldToProjUpdate f })
recFieldToProjUpdate :: LHsRecField GhcPs (LHsExpr GhcPs) -> LHsRecUpdProj GhcPs
recFieldToProjUpdate (L l (HsRecField anns (L _ (FieldOcc _ (L loc rdr))) arg pun)) =
let f = occNameFS . rdrNameOcc $ rdr
fl = HsFieldLabel noAnn (L lf f)
lf = locA loc
in mkRdrProjUpdate l (L lf [L lf fl]) (punnedVar f) pun anns
where
punnedVar :: FastString -> LHsExpr GhcPs
punnedVar f = if not pun then arg else noLocA . HsVar noExtField . noLocA . mkRdrUnqual . mkVarOccFS $ f
mkRdrRecordCon
:: LocatedN RdrName -> HsRecordBinds GhcPs -> EpAnn -> HsExpr GhcPs
mkRdrRecordCon con flds anns
= RecordCon { rcon_ext = anns, rcon_con = con, rcon_flds = flds }
mk_rec_fields :: [LocatedA (HsRecField (GhcPass p) arg)] -> Maybe SrcSpan -> HsRecFields (GhcPass p) arg
mk_rec_fields fs Nothing = HsRecFields { rec_flds = fs, rec_dotdot = Nothing }
mk_rec_fields fs (Just s) = HsRecFields { rec_flds = fs
, rec_dotdot = Just (L s (length fs)) }
mk_rec_upd_field :: HsRecField GhcPs (LHsExpr GhcPs) -> HsRecUpdField GhcPs
mk_rec_upd_field (HsRecField noAnn (L loc (FieldOcc _ rdr)) arg pun)
= HsRecField noAnn (L loc (Unambiguous noExtField rdr)) arg pun
mkInlinePragma :: SourceText -> (InlineSpec, RuleMatchInfo) -> Maybe Activation
-> InlinePragma
mkInlinePragma src (inl, match_info) mb_act
= InlinePragma { inl_src = src
, inl_inline = inl
, inl_sat = Nothing
, inl_act = act
, inl_rule = match_info }
where
act = case mb_act of
Just act -> act
Nothing ->
case inl of
NoInline -> NeverActive
_other -> AlwaysActive
mkImport :: Located CCallConv
-> Located Safety
-> (Located StringLiteral, LocatedN RdrName, LHsSigType GhcPs)
-> P (EpAnn -> HsDecl GhcPs)
mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) =
case unLoc cconv of
CCallConv -> mkCImport
CApiConv -> mkCImport
StdCallConv -> mkCImport
PrimCallConv -> mkOtherImport
JavaScriptCallConv -> mkOtherImport
where
mkCImport = do
let e = unpackFS entity
case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc esrc) of
Nothing -> addFatalError $ PsError PsErrMalformedEntityString [] loc
Just importSpec -> returnSpec importSpec
mkOtherImport = returnSpec importSpec
where
entity' = if nullFS entity
then mkExtName (unLoc v)
else entity
funcTarget = CFunction (StaticTarget esrc entity' Nothing True)
importSpec = CImport cconv safety Nothing funcTarget (L loc esrc)
returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport
{ fd_i_ext = ann
, fd_name = v
, fd_sig_ty = ty
, fd_fi = spec
}
parseCImport :: Located CCallConv -> Located Safety -> FastString -> String
-> Located SourceText
-> Maybe ForeignImport
parseCImport cconv safety nm str sourceText =
listToMaybe $ map fst $ filter (null.snd) $
readP_to_S parse str
where
parse = do
skipSpaces
r <- choice [
string "dynamic" >> return (mk Nothing (CFunction DynamicTarget)),
string "wrapper" >> return (mk Nothing CWrapper),
do optional (token "static" >> skipSpaces)
((mk Nothing <$> cimp nm) +++
(do h <- munch1 hdr_char
skipSpaces
mk (Just (Header (SourceText h) (mkFastString h)))
<$> cimp nm))
]
skipSpaces
return r
token str = do _ <- string str
toks <- look
case toks of
c : _
| id_char c -> pfail
_ -> return ()
mk h n = CImport cconv safety h n sourceText
hdr_char c = not (isSpace c)
id_first_char c = isAlpha c || c == '_'
id_char c = isAlphaNum c || c == '_'
cimp nm = (ReadP.char '&' >> skipSpaces >> CLabel <$> cid)
+++ (do isFun <- case unLoc cconv of
CApiConv ->
option True
(do token "value"
skipSpaces
return False)
_ -> return True
cid' <- cid
return (CFunction (StaticTarget NoSourceText cid'
Nothing isFun)))
where
cid = return nm +++
(do c <- satisfy id_first_char
cs <- many (satisfy id_char)
return (mkFastString (c:cs)))
mkExport :: Located CCallConv
-> (Located StringLiteral, LocatedN RdrName, LHsSigType GhcPs)
-> P (EpAnn -> HsDecl GhcPs)
mkExport (L lc cconv) (L le (StringLiteral esrc entity _), v, ty)
= return $ \ann -> ForD noExtField $
ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty
, fd_fe = CExport (L lc (CExportStatic esrc entity' cconv))
(L le esrc) }
where
entity' | nullFS entity = mkExtName (unLoc v)
| otherwise = entity
mkExtName :: RdrName -> CLabelString
mkExtName rdrNm = mkFastString (occNameString (rdrNameOcc rdrNm))
data ImpExpSubSpec = ImpExpAbs
| ImpExpAll
| ImpExpList [LocatedA ImpExpQcSpec]
| ImpExpAllWith [LocatedA ImpExpQcSpec]
data ImpExpQcSpec = ImpExpQcName (LocatedN RdrName)
| ImpExpQcType EpaAnchor (LocatedN RdrName)
| ImpExpQcWildcard
mkModuleImpExp :: [AddEpAnn] -> LocatedA ImpExpQcSpec -> ImpExpSubSpec -> P (IE GhcPs)
mkModuleImpExp anns (L l specname) subs = do
cs <- getCommentsFor (locA l)
let ann = EpAnn (spanAsAnchor $ locA l) anns cs
case subs of
ImpExpAbs
| isVarNameSpace (rdrNameSpace name)
-> return $ IEVar noExtField (L l (ieNameFromSpec specname))
| otherwise -> IEThingAbs ann . L l <$> nameT
ImpExpAll -> IEThingAll ann . L l <$> nameT
ImpExpList xs ->
(\newName -> IEThingWith ann (L l newName)
NoIEWildcard (wrapped xs)) <$> nameT
ImpExpAllWith xs ->
do allowed <- getBit PatternSynonymsBit
if allowed
then
let withs = map unLoc xs
pos = maybe NoIEWildcard IEWildcard
(findIndex isImpExpQcWildcard withs)
ies :: [LocatedA (IEWrappedName RdrName)]
ies = wrapped $ filter (not . isImpExpQcWildcard . unLoc) xs
in (\newName
-> IEThingWith ann (L l newName) pos ies)
<$> nameT
else addFatalError $ PsError PsErrIllegalPatSynExport [] (locA l)
where
name = ieNameVal specname
nameT =
if isVarNameSpace (rdrNameSpace name)
then addFatalError $ PsError (PsErrVarForTyCon name) [] (locA l)
else return $ ieNameFromSpec specname
ieNameVal (ImpExpQcName ln) = unLoc ln
ieNameVal (ImpExpQcType _ ln) = unLoc ln
ieNameVal (ImpExpQcWildcard) = panic "ieNameVal got wildcard"
ieNameFromSpec (ImpExpQcName ln) = IEName ln
ieNameFromSpec (ImpExpQcType r ln) = IEType r ln
ieNameFromSpec (ImpExpQcWildcard) = panic "ieName got wildcard"
wrapped = map (mapLoc ieNameFromSpec)
mkTypeImpExp :: LocatedN RdrName
-> P (LocatedN RdrName)
mkTypeImpExp name =
do allowed <- getBit ExplicitNamespacesBit
unless allowed $ addError $ PsError PsErrIllegalExplicitNamespace [] (getLocA name)
return (fmap (`setRdrNameSpace` tcClsName) name)
checkImportSpec :: LocatedL [LIE GhcPs] -> P (LocatedL [LIE GhcPs])
checkImportSpec ie@(L _ specs) =
case [l | (L l (IEThingWith _ _ (IEWildcard _) _)) <- specs] of
[] -> return ie
(l:_) -> importSpecError (locA l)
where
importSpecError l =
addFatalError $ PsError PsErrIllegalImportBundleForm [] l
mkImpExpSubSpec :: [LocatedA ImpExpQcSpec] -> P ([AddEpAnn], ImpExpSubSpec)
mkImpExpSubSpec [] = return ([], ImpExpList [])
mkImpExpSubSpec [L la ImpExpQcWildcard] =
return ([AddEpAnn AnnDotdot (AR $ la2r la)], ImpExpAll)
mkImpExpSubSpec xs =
if (any (isImpExpQcWildcard . unLoc) xs)
then return $ ([], ImpExpAllWith xs)
else return $ ([], ImpExpList xs)
isImpExpQcWildcard :: ImpExpQcSpec -> Bool
isImpExpQcWildcard ImpExpQcWildcard = True
isImpExpQcWildcard _ = False
warnPrepositiveQualifiedModule :: SrcSpan -> P ()
warnPrepositiveQualifiedModule span =
addWarning Opt_WarnPrepositiveQualifiedModule (PsWarnImportPreQualified span)
failOpNotEnabledImportQualifiedPost :: SrcSpan -> P ()
failOpNotEnabledImportQualifiedPost loc = addError $ PsError PsErrImportPostQualified [] loc
failOpImportQualifiedTwice :: SrcSpan -> P ()
failOpImportQualifiedTwice loc = addError $ PsError PsErrImportQualifiedTwice [] loc
warnStarIsType :: SrcSpan -> P ()
warnStarIsType span = addWarning Opt_WarnStarIsType (PsWarnStarIsType span)
failOpFewArgs :: MonadP m => LocatedN RdrName -> m a
failOpFewArgs (L loc op) =
do { star_is_type <- getBit StarIsTypeBit
; addFatalError $ PsError (PsErrOpFewArgs (StarIsType star_is_type) op) [] (locA loc) }
data PV_Context =
PV_Context
{ pv_options :: ParserOpts
, pv_hints :: [Hint]
}
data PV_Accum =
PV_Accum
{ pv_warnings :: Bag PsWarning
, pv_errors :: Bag PsError
, pv_header_comments :: Maybe [LEpaComment]
, pv_comment_q :: [LEpaComment]
}
data PV_Result a = PV_Ok PV_Accum a | PV_Failed PV_Accum
newtype PV a = PV { unPV :: PV_Context -> PV_Accum -> PV_Result a }
instance Functor PV where
fmap = liftM
instance Applicative PV where
pure a = a `seq` PV (\_ acc -> PV_Ok acc a)
(<*>) = ap
instance Monad PV where
m >>= f = PV $ \ctx acc ->
case unPV m ctx acc of
PV_Ok acc' a -> unPV (f a) ctx acc'
PV_Failed acc' -> PV_Failed acc'
runPV :: PV a -> P a
runPV = runPV_hints []
runPV_hints :: [Hint] -> PV a -> P a
runPV_hints hints m =
P $ \s ->
let
pv_ctx = PV_Context
{ pv_options = options s
, pv_hints = hints }
pv_acc = PV_Accum
{ pv_warnings = warnings s
, pv_errors = errors s
, pv_header_comments = header_comments s
, pv_comment_q = comment_q s }
mkPState acc' =
s { warnings = pv_warnings acc'
, errors = pv_errors acc'
, comment_q = pv_comment_q acc' }
in
case unPV m pv_ctx pv_acc of
PV_Ok acc' a -> POk (mkPState acc') a
PV_Failed acc' -> PFailed (mkPState acc')
add_hint :: Hint -> PV a -> PV a
add_hint hint m =
let modifyHint ctx = ctx{pv_hints = pv_hints ctx ++ [hint]} in
PV (\ctx acc -> unPV m (modifyHint ctx) acc)
instance MonadP PV where
addError err@(PsError e hints loc) =
PV $ \ctx acc ->
let err' | null (pv_hints ctx) = err
| otherwise = PsError e (hints ++ pv_hints ctx) loc
in PV_Ok acc{pv_errors = err' `consBag` pv_errors acc} ()
addWarning option w =
PV $ \ctx acc ->
if warnopt option (pv_options ctx)
then PV_Ok acc{pv_warnings= w `consBag` pv_warnings acc} ()
else PV_Ok acc ()
addFatalError err =
addError err >> PV (const PV_Failed)
getBit ext =
PV $ \ctx acc ->
let b = ext `xtest` pExtsBitmap (pv_options ctx) in
PV_Ok acc $! b
allocateCommentsP ss = PV $ \_ s ->
let (comment_q', newAnns) = allocateComments ss (pv_comment_q s) in
PV_Ok s {
pv_comment_q = comment_q'
} (EpaComments newAnns)
allocatePriorCommentsP ss = PV $ \_ s ->
let (header_comments', comment_q', newAnns)
= allocatePriorComments ss (pv_comment_q s) (pv_header_comments s) in
PV_Ok s {
pv_header_comments = header_comments',
pv_comment_q = comment_q'
} (EpaComments newAnns)
allocateFinalCommentsP ss = PV $ \_ s ->
let (header_comments', comment_q', newAnns)
= allocateFinalComments ss (pv_comment_q s) (pv_header_comments s) in
PV_Ok s {
pv_header_comments = header_comments',
pv_comment_q = comment_q'
} (EpaCommentsBalanced (fromMaybe [] header_comments') (reverse newAnns))
hintBangPat :: SrcSpan -> Pat GhcPs -> PV ()
hintBangPat span e = do
bang_on <- getBit BangPatBit
unless bang_on $
addError $ PsError (PsErrIllegalBangPattern e) [] span
mkSumOrTupleExpr :: SrcSpanAnnA -> Boxity -> SumOrTuple (HsExpr GhcPs)
-> [AddEpAnn]
-> PV (LHsExpr GhcPs)
mkSumOrTupleExpr l boxity (Tuple es) anns = do
cs <- getCommentsFor (locA l)
return $ L l (ExplicitTuple (EpAnn (spanAsAnchor $ locA l) anns cs) (map toTupArg es) boxity)
where
toTupArg :: Either (EpAnn' EpaAnchor) (LHsExpr GhcPs) -> HsTupArg GhcPs
toTupArg (Left ann) = missingTupArg ann
toTupArg (Right a) = Present noAnn a
mkSumOrTupleExpr l Unboxed (Sum alt arity e barsp barsa) anns = do
let an = case anns of
[AddEpAnn AnnOpenPH o, AddEpAnn AnnClosePH c] ->
AnnExplicitSum o barsp barsa c
_ -> panic "mkSumOrTupleExpr"
cs <- getCommentsFor (locA l)
return $ L l (ExplicitSum (EpAnn (spanAsAnchor $ locA l) an cs) alt arity e)
mkSumOrTupleExpr l Boxed a@Sum{} _ =
addFatalError $ PsError (PsErrUnsupportedBoxedSumExpr a) [] (locA l)
mkSumOrTuplePat
:: SrcSpanAnnA -> Boxity -> SumOrTuple (PatBuilder GhcPs) -> [AddEpAnn]
-> PV (LocatedA (PatBuilder GhcPs))
mkSumOrTuplePat l boxity (Tuple ps) anns = do
ps' <- traverse toTupPat ps
cs <- getCommentsFor (locA l)
return $ L l (PatBuilderPat (TuplePat (EpAnn (spanAsAnchor $ locA l) anns cs) ps' boxity))
where
toTupPat :: Either (EpAnn' EpaAnchor) (LocatedA (PatBuilder GhcPs)) -> PV (LPat GhcPs)
toTupPat p = case p of
Left _ -> addFatalError $ PsError PsErrTupleSectionInPat [] (locA l)
Right p' -> checkLPat p'
mkSumOrTuplePat l Unboxed (Sum alt arity p barsb barsa) anns = do
p' <- checkLPat p
cs <- getCommentsFor (locA l)
let an = EpAnn (spanAsAnchor $ locA l) (EpAnnSumPat anns barsb barsa) cs
return $ L l (PatBuilderPat (SumPat an p' alt arity))
mkSumOrTuplePat l Boxed a@Sum{} _ =
addFatalError $ PsError (PsErrUnsupportedBoxedSumPat a) [] (locA l)
mkLHsOpTy :: LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> LHsType GhcPs
mkLHsOpTy x op y =
let loc = getLoc x `combineSrcSpansA` (noAnnSrcSpan $ getLocA op) `combineSrcSpansA` getLoc y
in L loc (mkHsOpTy x op y)
mkMultTy :: IsUnicodeSyntax -> Located Token -> LHsType GhcPs -> HsArrow GhcPs
mkMultTy u tok t@(L _ (HsTyLit _ (HsNumTy (SourceText "1") 1)))
= HsLinearArrow u (Just $ AddEpAnn AnnPercentOne (AR $ realSrcSpan $ combineLocs tok (reLoc t)))
mkMultTy u tok t = HsExplicitMult u (Just $ AddEpAnn AnnPercent (AR $ realSrcSpan $ getLoc tok)) t
starSym :: Bool -> String
starSym True = "★"
starSym False = "*"
mkRdrGetField :: SrcSpanAnnA -> LHsExpr GhcPs -> Located (HsFieldLabel GhcPs)
-> EpAnnCO -> LHsExpr GhcPs
mkRdrGetField loc arg field anns =
L loc HsGetField {
gf_ext = anns
, gf_expr = arg
, gf_field = field
}
mkRdrProjection :: [Located (HsFieldLabel GhcPs)] -> EpAnn' AnnProjection -> HsExpr GhcPs
mkRdrProjection [] _ = panic "mkRdrProjection: The impossible has happened!"
mkRdrProjection flds anns =
HsProjection {
proj_ext = anns
, proj_flds = flds
}
mkRdrProjUpdate :: SrcSpanAnnA -> Located [Located (HsFieldLabel GhcPs)]
-> LHsExpr GhcPs -> Bool -> EpAnn
-> LHsRecProj GhcPs (LHsExpr GhcPs)
mkRdrProjUpdate _ (L _ []) _ _ _ = panic "mkRdrProjUpdate: The impossible has happened!"
mkRdrProjUpdate loc (L l flds) arg isPun anns =
L loc HsRecField {
hsRecFieldAnn = anns
, hsRecFieldLbl = L l (FieldLabelStrings flds)
, hsRecFieldArg = arg
, hsRecPun = isPun
}