{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Retrie.PatternMap.Instances where
import Control.Monad
import Data.ByteString (ByteString)
import Data.Maybe
import Retrie.AlphaEnv
import Retrie.ExactPrint
import Retrie.GHC
import Retrie.PatternMap.Bag
import Retrie.PatternMap.Class
import Retrie.Quantifiers
import Retrie.Substitution
data TupArgMap a
= TupArgMap { tamPresent :: EMap a, tamMissing :: MaybeMap a }
deriving (Functor)
instance PatternMap TupArgMap where
type Key TupArgMap = LHsTupArg GhcPs
mEmpty :: TupArgMap a
mEmpty = TupArgMap mEmpty mEmpty
mUnion :: TupArgMap a -> TupArgMap a -> TupArgMap a
mUnion (TupArgMap p1 m1) (TupArgMap p2 m2) = TupArgMap (mUnion p1 p2) (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key TupArgMap -> A a -> TupArgMap a -> TupArgMap a
mAlter env vs tupArg f m = go (unLoc tupArg)
where
#if __GLASGOW_HASKELL__ < 806
go (Present e) = m { tamPresent = mAlter env vs e f (tamPresent m) }
#else
go (Present _ e) = m { tamPresent = mAlter env vs e f (tamPresent m) }
go XTupArg{} = error "XTupArg"
#endif
go (Missing _) = m { tamMissing = mAlter env vs () f (tamMissing m) }
mMatch :: MatchEnv -> Key TupArgMap -> (Substitution, TupArgMap a) -> [(Substitution, a)]
mMatch env = go . unLoc
where
#if __GLASGOW_HASKELL__ < 806
go (Present e) = mapFor tamPresent >=> mMatch env e
#else
go (Present _ e) = mapFor tamPresent >=> mMatch env e
go XTupArg{} = const []
#endif
go (Missing _) = mapFor tamMissing >=> mMatch env ()
data BoxityMap a
= BoxityMap { boxBoxed :: MaybeMap a, boxUnboxed :: MaybeMap a }
deriving (Functor)
instance PatternMap BoxityMap where
type Key BoxityMap = Boxity
mEmpty :: BoxityMap a
mEmpty = BoxityMap mEmpty mEmpty
mUnion :: BoxityMap a -> BoxityMap a -> BoxityMap a
mUnion (BoxityMap b1 u1) (BoxityMap b2 u2) = BoxityMap (mUnion b1 b2) (mUnion u1 u2)
mAlter :: AlphaEnv -> Quantifiers -> Key BoxityMap -> A a -> BoxityMap a -> BoxityMap a
mAlter env vs Boxed f m = m { boxBoxed = mAlter env vs () f (boxBoxed m) }
mAlter env vs Unboxed f m = m { boxUnboxed = mAlter env vs () f (boxUnboxed m) }
mMatch :: MatchEnv -> Key BoxityMap -> (Substitution, BoxityMap a) -> [(Substitution, a)]
mMatch env Boxed = mapFor boxBoxed >=> mMatch env ()
mMatch env Unboxed = mapFor boxUnboxed >=> mMatch env ()
data VMap a = VM { bvmap :: IntMap a, fvmap :: FSEnv a }
| VMEmpty
deriving (Functor)
instance PatternMap VMap where
type Key VMap = RdrName
mEmpty :: VMap a
mEmpty = VMEmpty
mUnion :: VMap a -> VMap a -> VMap a
mUnion VMEmpty m = m
mUnion m VMEmpty = m
mUnion (VM b1 f1) (VM b2 f2) = VM (mUnion b1 b2) (mUnion f1 f2)
mAlter :: AlphaEnv -> Quantifiers -> Key VMap -> A a -> VMap a -> VMap a
mAlter env vs v f VMEmpty = mAlter env vs v f (VM mEmpty mEmpty)
mAlter env vs v f m@VM{}
| Just bv <- lookupAlphaEnv v env = m { bvmap = mAlter env vs bv f (bvmap m) }
| otherwise = m { fvmap = mAlter env vs (rdrFS v) f (fvmap m) }
mMatch :: MatchEnv -> Key VMap -> (Substitution, VMap a) -> [(Substitution, a)]
mMatch _ _ (_,VMEmpty) = []
mMatch env v (hs,m@VM{})
| Just bv <- lookupAlphaEnv v (meAlphaEnv env) = mMatch env bv (hs, bvmap m)
| otherwise = mMatch env (rdrFS v) (hs, fvmap m)
data LMap a
= LMEmpty
| LM { lmChar :: Map Char a
, lmCharPrim :: Map Char a
, lmString :: FSEnv a
, lmStringPrim :: Map ByteString a
, lmInt :: BoolMap (Map Integer a)
, lmIntPrim :: Map Integer a
, lmWordPrim :: Map Integer a
, lmInt64Prim :: Map Integer a
, lmWord64Prim :: Map Integer a
}
deriving (Functor)
emptyLMapWrapper :: LMap a
emptyLMapWrapper
= LM mEmpty mEmpty mEmpty mEmpty mEmpty
mEmpty mEmpty mEmpty mEmpty
instance PatternMap LMap where
type Key LMap = HsLit GhcPs
mEmpty :: LMap a
mEmpty = LMEmpty
mUnion :: LMap a -> LMap a -> LMap a
mUnion LMEmpty m = m
mUnion m LMEmpty = m
mUnion (LM a1 b1 c1 d1 e1 f1 g1 h1 i1)
(LM a2 b2 c2 d2 e2 f2 g2 h2 i2) =
LM (mUnion a1 a2)
(mUnion b1 b2)
(mUnion c1 c2)
(mUnion d1 d2)
(mUnion e1 e2)
(mUnion f1 f2)
(mUnion g1 g2)
(mUnion h1 h2)
(mUnion i1 i2)
mAlter :: AlphaEnv -> Quantifiers -> Key LMap -> A a -> LMap a -> LMap a
mAlter env vs lit f LMEmpty = mAlter env vs lit f emptyLMapWrapper
mAlter env vs lit f m@LM{} = go lit
where
go (HsChar _ c) = m { lmChar = mAlter env vs c f (lmChar m) }
go (HsCharPrim _ c) = m { lmCharPrim = mAlter env vs c f (lmCharPrim m) }
go (HsString _ fs) = m { lmString = mAlter env vs fs f (lmString m) }
go (HsStringPrim _ bs) = m { lmStringPrim = mAlter env vs bs f (lmStringPrim m) }
go (HsInt _ (IL _ b i)) =
m { lmInt = mAlter env vs b (toA (mAlter env vs i f)) (lmInt m) }
go (HsIntPrim _ i) = m { lmIntPrim = mAlter env vs i f (lmIntPrim m) }
go (HsWordPrim _ i) = m { lmWordPrim = mAlter env vs i f (lmWordPrim m) }
go (HsInt64Prim _ i) = m { lmInt64Prim = mAlter env vs i f (lmInt64Prim m) }
go (HsWord64Prim _ i) = m { lmWord64Prim = mAlter env vs i f (lmWord64Prim m) }
go (HsInteger _ _ _) = error "HsInteger"
go HsRat{} = error "HsRat"
go HsFloatPrim{} = error "HsFloatPrim"
go HsDoublePrim{} = error "HsDoublePrim"
#if __GLASGOW_HASKELL__ < 806
#else
go XLit{} = error "XLit"
#endif
mMatch :: MatchEnv -> Key LMap -> (Substitution, LMap a) -> [(Substitution, a)]
mMatch _ _ (_,LMEmpty) = []
mMatch env lit (hs,m@LM{}) = go lit (hs,m)
where
go (HsChar _ c) = mapFor lmChar >=> mMatch env c
go (HsCharPrim _ c) = mapFor lmCharPrim >=> mMatch env c
go (HsString _ fs) = mapFor lmString >=> mMatch env fs
go (HsStringPrim _ bs) = mapFor lmStringPrim >=> mMatch env bs
go (HsInt _ (IL _ b i)) = mapFor lmInt >=> mMatch env b >=> mMatch env i
go (HsIntPrim _ i) = mapFor lmIntPrim >=> mMatch env i
go (HsWordPrim _ i) = mapFor lmWordPrim >=> mMatch env i
go (HsInt64Prim _ i) = mapFor lmInt64Prim >=> mMatch env i
go (HsWord64Prim _ i) = mapFor lmWord64Prim >=> mMatch env i
go _ = const []
data OLMap a
= OLMEmpty
| OLM
{ olmIntegral :: BoolMap (Map Integer a)
, olmFractional :: Map Rational a
, olmIsString :: FSEnv a
}
deriving (Functor)
emptyOLMapWrapper :: OLMap a
emptyOLMapWrapper = OLM mEmpty mEmpty mEmpty
instance PatternMap OLMap where
type Key OLMap = OverLitVal
mEmpty :: OLMap a
mEmpty = OLMEmpty
mUnion :: OLMap a -> OLMap a -> OLMap a
mUnion OLMEmpty m = m
mUnion m OLMEmpty = m
mUnion (OLM a1 b1 c1) (OLM a2 b2 c2) =
OLM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2)
mAlter :: AlphaEnv -> Quantifiers -> Key OLMap -> A a -> OLMap a -> OLMap a
mAlter env vs lv f OLMEmpty = mAlter env vs lv f emptyOLMapWrapper
mAlter env vs lv f m@OLM{} = go lv
where
go (HsIntegral (IL _ b i)) =
m { olmIntegral = mAlter env vs b (toA (mAlter env vs i f)) (olmIntegral m) }
go (HsFractional fl) = m { olmFractional = mAlter env vs (fl_value fl) f (olmFractional m) }
go (HsIsString _ fs) = m { olmIsString = mAlter env vs fs f (olmIsString m) }
mMatch :: MatchEnv -> Key OLMap -> (Substitution, OLMap a) -> [(Substitution, a)]
mMatch _ _ (_,OLMEmpty) = []
mMatch env lv (hs,m@OLM{}) = go lv (hs,m)
where
go (HsIntegral (IL _ b i)) =
mapFor olmIntegral >=> mMatch env b >=> mMatch env i
go (HsFractional fl) = mapFor olmFractional >=> mMatch env (fl_value fl)
go (HsIsString _ fs) = mapFor olmIsString >=> mMatch env fs
data EMap a
= EMEmpty
| EM { emHole :: Map RdrName a
, emVar :: VMap a
, emIPVar :: FSEnv a
, emOverLit :: OLMap a
, emLit :: LMap a
, emLam :: MGMap a
, emApp :: EMap (EMap a)
, emOpApp :: EMap (EMap (EMap a))
, emNegApp :: EMap a
, emPar :: EMap a
, emExplicitTuple :: BoxityMap (ListMap TupArgMap a)
, emCase :: EMap (MGMap a)
, emSecL :: EMap (EMap a)
, emSecR :: EMap (EMap a)
, emIf :: EMap (EMap (EMap a))
, emLet :: LBMap (EMap a)
, emDo :: SCMap (SLMap a)
, emExplicitList :: ListMap EMap a
, emRecordCon :: VMap (ListMap RFMap a)
, emRecordUpd :: EMap (ListMap RFMap a)
, emExprWithTySig :: EMap (TyMap a)
}
deriving (Functor)
emptyEMapWrapper :: EMap a
emptyEMapWrapper =
EM mEmpty mEmpty mEmpty mEmpty mEmpty
mEmpty mEmpty mEmpty mEmpty mEmpty
mEmpty mEmpty mEmpty mEmpty mEmpty
mEmpty mEmpty mEmpty mEmpty mEmpty
mEmpty
instance PatternMap EMap where
type Key EMap = LHsExpr GhcPs
mEmpty :: EMap a
mEmpty = EMEmpty
mUnion :: EMap a -> EMap a -> EMap a
mUnion EMEmpty m = m
mUnion m EMEmpty = m
mUnion (EM a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1)
(EM a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 n2 o2 p2 q2 r2 s2 t2 u2) =
EM (mUnion a1 a2)
(mUnion b1 b2)
(mUnion c1 c2)
(mUnion d1 d2)
(mUnion e1 e2)
(mUnion f1 f2)
(mUnion g1 g2)
(mUnion h1 h2)
(mUnion i1 i2)
(mUnion j1 j2)
(mUnion k1 k2)
(mUnion l1 l2)
(mUnion m1 m2)
(mUnion n1 n2)
(mUnion o1 o2)
(mUnion p1 p2)
(mUnion q1 q2)
(mUnion r1 r2)
(mUnion s1 s2)
(mUnion t1 t2)
(mUnion u1 u2)
mAlter :: AlphaEnv -> Quantifiers -> Key EMap -> A a -> EMap a -> EMap a
mAlter env vs e f EMEmpty = mAlter env vs e f emptyEMapWrapper
mAlter env vs e f m@EM{} = go (unLoc e)
where
dollarFork v@HsVar{} l r
| Just (L _ rdr) <- varRdrName v
, occNameString (occName rdr) == "$" =
#if __GLASGOW_HASKELL__ < 806
go (HsApp l (noLoc (HsPar r)))
#else
go (HsApp noExt l (noLoc (HsPar noExt r)))
#endif
dollarFork _ _ _ = m
#if __GLASGOW_HASKELL__ < 806
go (HsVar v)
| unLoc v `isQ` vs = m { emHole = mAlter env vs (unLoc v) f (emHole m) }
| otherwise = m { emVar = mAlter env vs (unLoc v) f (emVar m) }
go (ExplicitTuple as b) =
m { emExplicitTuple = mAlter env vs b (toA (mAlter env vs as f)) (emExplicitTuple m) }
go (HsApp l r) =
m { emApp = mAlter env vs l (toA (mAlter env vs r f)) (emApp m) }
go (HsCase s mg) =
m { emCase = mAlter env vs s (toA (mAlter env vs mg f)) (emCase m) }
go (HsDo sc ss _) =
m { emDo = mAlter env vs sc (toA (mAlter env vs (unLoc ss) f)) (emDo m) }
go (HsIf _ c tr fl) =
m { emIf = mAlter env vs c
(toA (mAlter env vs tr
(toA (mAlter env vs fl f)))) (emIf m) }
go (HsIPVar (HsIPName ip)) = m { emIPVar = mAlter env vs ip f (emIPVar m) }
go (HsLit l) = m { emLit = mAlter env vs l f (emLit m) }
go (HsLam mg) = m { emLam = mAlter env vs mg f (emLam m) }
go (HsOverLit ol) = m { emOverLit = mAlter env vs (ol_val ol) f (emOverLit m) }
go (NegApp e' _) = m { emNegApp = mAlter env vs e' f (emNegApp m) }
go (HsPar e') = m { emPar = mAlter env vs e' f (emPar m) }
go (OpApp l o _ r) = (dollarFork (unLoc o) l r)
{ emOpApp = mAlter env vs o (toA (mAlter env vs l (toA (mAlter env vs r f)))) (emOpApp m) }
go (RecordCon v _ _ fs) =
m { emRecordCon = mAlter env vs (unLoc v) (toA (mAlter env vs (fieldsToRdrNames $ rec_flds fs) f)) (emRecordCon m) }
go (RecordUpd e' fs _ _ _ _) =
m { emRecordUpd = mAlter env vs e' (toA (mAlter env vs (fieldsToRdrNames fs) f)) (emRecordUpd m) }
go (SectionL lhs o) =
m { emSecL = mAlter env vs o (toA (mAlter env vs lhs f)) (emSecL m) }
go (SectionR o rhs) =
m { emSecR = mAlter env vs o (toA (mAlter env vs rhs f)) (emSecR m) }
go (HsLet lbs e') =
#else
go (HsVar _ v)
| unLoc v `isQ` vs = m { emHole = mAlter env vs (unLoc v) f (emHole m) }
| otherwise = m { emVar = mAlter env vs (unLoc v) f (emVar m) }
go (ExplicitTuple _ as b) =
m { emExplicitTuple = mAlter env vs b (toA (mAlter env vs as f)) (emExplicitTuple m) }
go (HsApp _ l r) =
m { emApp = mAlter env vs l (toA (mAlter env vs r f)) (emApp m) }
go (HsCase _ s mg) =
m { emCase = mAlter env vs s (toA (mAlter env vs mg f)) (emCase m) }
go (HsDo _ sc ss) =
m { emDo = mAlter env vs sc (toA (mAlter env vs (unLoc ss) f)) (emDo m) }
go (HsIf _ _ c tr fl) =
m { emIf = mAlter env vs c
(toA (mAlter env vs tr
(toA (mAlter env vs fl f)))) (emIf m) }
go (HsIPVar _ (HsIPName ip)) = m { emIPVar = mAlter env vs ip f (emIPVar m) }
go (HsLit _ l) = m { emLit = mAlter env vs l f (emLit m) }
go (HsLam _ mg) = m { emLam = mAlter env vs mg f (emLam m) }
go (HsOverLit _ ol) = m { emOverLit = mAlter env vs (ol_val ol) f (emOverLit m) }
go (NegApp _ e' _) = m { emNegApp = mAlter env vs e' f (emNegApp m) }
go (HsPar _ e') = m { emPar = mAlter env vs e' f (emPar m) }
go (OpApp _ l o r) = (dollarFork (unLoc o) l r)
{ emOpApp = mAlter env vs o (toA (mAlter env vs l (toA (mAlter env vs r f)))) (emOpApp m) }
go (RecordCon _ v fs) =
m { emRecordCon = mAlter env vs (unLoc v) (toA (mAlter env vs (fieldsToRdrNames $ rec_flds fs) f)) (emRecordCon m) }
go (RecordUpd _ e' fs) =
m { emRecordUpd = mAlter env vs e' (toA (mAlter env vs (fieldsToRdrNames fs) f)) (emRecordUpd m) }
go (SectionL _ lhs o) =
m { emSecL = mAlter env vs o (toA (mAlter env vs lhs f)) (emSecL m) }
go (SectionR _ o rhs) =
m { emSecR = mAlter env vs o (toA (mAlter env vs rhs f)) (emSecR m) }
go XExpr{} = error "XExpr"
go (HsLet _ lbs e') =
#endif
let
bs = collectLocalBinders $ unLoc lbs
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in m { emLet = mAlter env vs (unLoc lbs) (toA (mAlter env' vs' e' f)) (emLet m) }
go HsLamCase{} = error "HsLamCase"
go HsMultiIf{} = error "HsMultiIf"
go (ExplicitList _ _ es) = m { emExplicitList = mAlter env vs es f (emExplicitList m) }
go ArithSeq{} = error "ArithSeq"
#if __GLASGOW_HASKELL__ < 806
go (ExprWithTySig e' (HsWC _ (HsIB _ ty _))) =
m { emExprWithTySig = mAlter env vs e' (toA (mAlter env vs ty f)) (emExprWithTySig m) }
#else
#if __GLASGOW_HASKELL__ < 808
go (ExprWithTySig (HsWC _ (HsIB _ ty)) e') =
#else
go (ExprWithTySig _ e' (HsWC _ (HsIB _ ty))) =
#endif
m { emExprWithTySig = mAlter env vs e' (toA (mAlter env vs ty f)) (emExprWithTySig m) }
go ExprWithTySig{} = error "ExprWithTySig"
#endif
go HsSCC{} = error "HsSCC"
go HsCoreAnn{} = error "HsCoreAnn"
go HsBracket{} = error "HsBracket"
go HsRnBracketOut{} = error "HsRnBracketOut"
go HsTcBracketOut{} = error "HsTcBracketOut"
go HsSpliceE{} = error "HsSpliceE"
go HsProc{} = error "HsProc"
go HsStatic{} = error "HsStatic"
go HsArrApp{} = error "HsArrApp"
go HsArrForm{} = error "HsArrForm"
go HsTick{} = error "HsTick"
go HsBinTick{} = error "HsBinTick"
go HsTickPragma{} = error "HsTickPragma"
go EWildPat{} = error "EWildPat"
go EAsPat{} = error "EAsPat"
go EViewPat{} = error "EViewPat"
go ELazyPat{} = error "ELazyPat"
go HsWrap{} = error "HsWrap"
go HsUnboundVar{} = error "HsUnboundVar"
go HsRecFld{} = error "HsRecFld"
go HsOverLabel{} = error "HsOverLabel"
go HsAppType{} = error "HsAppType"
go HsConLikeOut{} = error "HsConLikeOut"
go ExplicitSum{} = error "ExplicitSum"
#if __GLASGOW_HASKELL__ < 806
go ExplicitPArr{} = error "ExplicitPArr"
go ExprWithTySigOut{} = error "ExprWithTySigOut"
go HsAppTypeOut{} = error "HsAppTypeOut"
go PArrSeq{} = error "PArrSeq"
#endif
mMatch :: MatchEnv -> Key EMap -> (Substitution, EMap a) -> [(Substitution, a)]
mMatch _ _ (_,EMEmpty) = []
mMatch env e (hs,m@EM{}) = hss ++ go (unLoc e) (hs,m)
where
hss = extendResult (emHole m) (HoleExpr $ mePruneA env e) hs
#if __GLASGOW_HASKELL__ < 806
go (ExplicitTuple as b) = mapFor emExplicitTuple >=> mMatch env b >=> mMatch env as
go (HsApp l r) = mapFor emApp >=> mMatch env l >=> mMatch env r
go (HsCase s mg) = mapFor emCase >=> mMatch env s >=> mMatch env mg
go (HsDo sc ss _) = mapFor emDo >=> mMatch env sc >=> mMatch env (unLoc ss)
go (HsIf _ c tr fl) =
mapFor emIf >=> mMatch env c >=> mMatch env tr >=> mMatch env fl
go (HsIPVar (HsIPName ip)) = mapFor emIPVar >=> mMatch env ip
go (HsLam mg) = mapFor emLam >=> mMatch env mg
go (HsLit l) = mapFor emLit >=> mMatch env l
go (HsOverLit ol) = mapFor emOverLit >=> mMatch env (ol_val ol)
go (HsPar e') = mapFor emPar >=> mMatch env e'
go (HsVar v) = mapFor emVar >=> mMatch env (unLoc v)
go (NegApp e' _) = mapFor emNegApp >=> mMatch env e'
go (OpApp l o _ r) =
mapFor emOpApp >=> mMatch env o >=> mMatch env l >=> mMatch env r
go (RecordCon v _ _ fs) =
mapFor emRecordCon >=> mMatch env (unLoc v) >=> mMatch env (fieldsToRdrNames $ rec_flds fs)
go (RecordUpd e' fs _ _ _ _) =
mapFor emRecordUpd >=> mMatch env e' >=> mMatch env (fieldsToRdrNames fs)
go (SectionL lhs o) = mapFor emSecL >=> mMatch env o >=> mMatch env lhs
go (SectionR o rhs) = mapFor emSecR >=> mMatch env o >=> mMatch env rhs
go (HsLet lbs e') =
#else
go (ExplicitTuple _ as b) = mapFor emExplicitTuple >=> mMatch env b >=> mMatch env as
go (HsApp _ l r) = mapFor emApp >=> mMatch env l >=> mMatch env r
go (HsCase _ s mg) = mapFor emCase >=> mMatch env s >=> mMatch env mg
go (HsDo _ sc ss) = mapFor emDo >=> mMatch env sc >=> mMatch env (unLoc ss)
go (HsIf _ _ c tr fl) =
mapFor emIf >=> mMatch env c >=> mMatch env tr >=> mMatch env fl
go (HsIPVar _ (HsIPName ip)) = mapFor emIPVar >=> mMatch env ip
go (HsLam _ mg) = mapFor emLam >=> mMatch env mg
go (HsLit _ l) = mapFor emLit >=> mMatch env l
go (HsOverLit _ ol) = mapFor emOverLit >=> mMatch env (ol_val ol)
go (HsPar _ e') = mapFor emPar >=> mMatch env e'
go (HsVar _ v) = mapFor emVar >=> mMatch env (unLoc v)
go (OpApp _ l o r) =
mapFor emOpApp >=> mMatch env o >=> mMatch env l >=> mMatch env r
go (NegApp _ e' _) = mapFor emNegApp >=> mMatch env e'
go (RecordCon _ v fs) =
mapFor emRecordCon >=> mMatch env (unLoc v) >=> mMatch env (fieldsToRdrNames $ rec_flds fs)
go (RecordUpd _ e' fs) =
mapFor emRecordUpd >=> mMatch env e' >=> mMatch env (fieldsToRdrNames fs)
go (SectionL _ lhs o) = mapFor emSecL >=> mMatch env o >=> mMatch env lhs
go (SectionR _ o rhs) = mapFor emSecR >=> mMatch env o >=> mMatch env rhs
go (HsLet _ lbs e') =
#endif
let
bs = collectLocalBinders (unLoc lbs)
env' = extendMatchEnv env bs
in mapFor emLet >=> mMatch env (unLoc lbs) >=> mMatch env' e'
go (ExplicitList _ _ es) = mapFor emExplicitList >=> mMatch env es
#if __GLASGOW_HASKELL__ < 806
go (ExprWithTySig e' (HsWC _ (HsIB _ ty _))) =
#elif __GLASGOW_HASKELL__ < 808
go (ExprWithTySig (HsWC _ (HsIB _ ty)) e') =
#else
go (ExprWithTySig _ e' (HsWC _ (HsIB _ ty))) =
#endif
mapFor emExprWithTySig >=> mMatch env e' >=> mMatch env ty
go _ = const []
extendResult :: Map RdrName a -> HoleVal -> Substitution -> [(Substitution, a)]
extendResult hm v sub = catMaybes
[ case lookupSubst n sub of
Nothing -> return (extendSubst sub n v, x)
Just v' -> sameHoleValue v v' >> return (sub, x)
| (nm,x) <- mapAssocs hm, let n = rdrFS nm ]
singleton :: [a] -> Maybe a
singleton [x] = Just x
singleton _ = Nothing
sameHoleValue :: HoleVal -> HoleVal -> Maybe ()
sameHoleValue (HoleExpr e1) (HoleExpr e2) =
alphaEquivalent (astA e1) (astA e2) EMEmpty
sameHoleValue (HolePat p1) (HolePat p2) =
alphaEquivalent
#if __GLASGOW_HASKELL__ < 808
(astA p1)
(astA p2)
#else
(composeSrcSpan $ astA p1)
(composeSrcSpan $ astA p2)
#endif
PatEmpty
sameHoleValue (HoleType ty1) (HoleType ty2) =
alphaEquivalent (astA ty1) (astA ty2) TyEmpty
sameHoleValue _ _ = Nothing
alphaEquivalent :: PatternMap m => Key m -> Key m -> m () -> Maybe ()
alphaEquivalent v1 v2 e = snd <$> singleton (findMatch env v2 m)
where
m = insertMatch emptyAlphaEnv emptyQs v1 () e
env = ME emptyAlphaEnv err
err _ = error "hole prune during alpha-equivalence check is impossible!"
data SCMap a
= SCEmpty
| SCM { scmListComp :: MaybeMap a
, scmMonadComp :: MaybeMap a
, scmDoExpr :: MaybeMap a
}
deriving (Functor)
emptySCMapWrapper :: SCMap a
emptySCMapWrapper = SCM mEmpty mEmpty mEmpty
instance PatternMap SCMap where
type Key SCMap = HsStmtContext Name
mEmpty :: SCMap a
mEmpty = SCEmpty
mUnion :: SCMap a -> SCMap a -> SCMap a
mUnion SCEmpty m = m
mUnion m SCEmpty = m
mUnion (SCM a1 b1 c1) (SCM a2 b2 c2) =
SCM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2)
mAlter :: AlphaEnv -> Quantifiers -> Key SCMap -> A a -> SCMap a -> SCMap a
mAlter env vs sc f SCEmpty = mAlter env vs sc f emptySCMapWrapper
mAlter env vs sc f m@SCM{} = go sc
where
go ListComp = m { scmListComp = mAlter env vs () f (scmListComp m) }
go MonadComp = m { scmMonadComp = mAlter env vs () f (scmMonadComp m) }
#if __GLASGOW_HASKELL__ < 806
go PArrComp = error "PArrComp"
#endif
go DoExpr = m { scmDoExpr = mAlter env vs () f (scmDoExpr m) }
go MDoExpr = error "MDoExpr"
go ArrowExpr = error "ArrowExpr"
go GhciStmtCtxt = error "GhciStmtCtxt"
go (PatGuard _) = error "PatGuard"
go (ParStmtCtxt _) = error "ParStmtCtxt"
go (TransStmtCtxt _) = error "TransStmtCtxt"
mMatch :: MatchEnv -> Key SCMap -> (Substitution, SCMap a) -> [(Substitution, a)]
mMatch _ _ (_,SCEmpty) = []
mMatch env sc (hs,m@SCM{}) = go sc (hs,m)
where
go ListComp = mapFor scmListComp >=> mMatch env ()
go MonadComp = mapFor scmMonadComp >=> mMatch env ()
go DoExpr = mapFor scmDoExpr >=> mMatch env ()
go _ = const []
newtype MGMap a = MGMap { unMGMap :: ListMap MMap a }
deriving (Functor)
instance PatternMap MGMap where
type Key MGMap = MatchGroup GhcPs (LHsExpr GhcPs)
mEmpty :: MGMap a
mEmpty = MGMap mEmpty
mUnion :: MGMap a -> MGMap a -> MGMap a
mUnion (MGMap m1) (MGMap m2) = MGMap (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key MGMap -> A a -> MGMap a -> MGMap a
mAlter env vs mg f (MGMap m) = MGMap (mAlter env vs alts f m)
where alts = map unLoc (unLoc $ mg_alts mg)
mMatch :: MatchEnv -> Key MGMap -> (Substitution, MGMap a) -> [(Substitution, a)]
mMatch env mg = mapFor unMGMap >=> mMatch env alts
where alts = map unLoc (unLoc $ mg_alts mg)
newtype MMap a = MMap { unMMap :: ListMap PatMap (GRHSSMap a) }
deriving (Functor)
instance PatternMap MMap where
type Key MMap = Match GhcPs (LHsExpr GhcPs)
mEmpty :: MMap a
mEmpty = MMap mEmpty
mUnion :: MMap a -> MMap a -> MMap a
mUnion (MMap m1) (MMap m2) = MMap (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key MMap -> A a -> MMap a -> MMap a
mAlter env vs match f (MMap m) =
let lpats = m_pats match
pbs = collectPatsBinders lpats
env' = foldr extendAlphaEnvInternal env pbs
vs' = vs `exceptQ` pbs
in MMap (mAlter env vs lpats
(toA (mAlter env' vs' (m_grhss match) f)) m)
mMatch :: MatchEnv -> Key MMap -> (Substitution, MMap a) -> [(Substitution, a)]
mMatch env match = mapFor unMMap >=> mMatch env lpats >=> mMatch env' (m_grhss match)
where
lpats = m_pats match
pbs = collectPatsBinders lpats
env' = extendMatchEnv env pbs
data CDMap a
= CDEmpty
| CDMap { cdPrefixCon :: ListMap PatMap a
, cdInfixCon :: PatMap (PatMap a)
}
deriving (Functor)
emptyCDMapWrapper :: CDMap a
emptyCDMapWrapper = CDMap mEmpty mEmpty
instance PatternMap CDMap where
type Key CDMap = HsConDetails (LPat GhcPs) (HsRecFields GhcPs (LPat GhcPs))
mEmpty :: CDMap a
mEmpty = CDEmpty
mUnion :: CDMap a -> CDMap a -> CDMap a
mUnion CDEmpty m = m
mUnion m CDEmpty = m
mUnion (CDMap a1 b1) (CDMap a2 b2) = CDMap (mUnion a1 a2) (mUnion b1 b2)
mAlter :: AlphaEnv -> Quantifiers -> Key CDMap -> A a -> CDMap a -> CDMap a
mAlter env vs d f CDEmpty = mAlter env vs d f emptyCDMapWrapper
mAlter env vs d f m@CDMap{} = go d
where
go (PrefixCon ps) = m { cdPrefixCon = mAlter env vs ps f (cdPrefixCon m) }
go (RecCon _) = error "RecCon"
go (InfixCon p1 p2) = m { cdInfixCon = mAlter env vs p1
(toA (mAlter env vs p2 f))
(cdInfixCon m) }
mMatch :: MatchEnv -> Key CDMap -> (Substitution, CDMap a) -> [(Substitution, a)]
mMatch _ _ (_ ,CDEmpty) = []
mMatch env d (hs,m@CDMap{}) = go d (hs,m)
where
go (PrefixCon ps) = mapFor cdPrefixCon >=> mMatch env ps
go (InfixCon p1 p2) = mapFor cdInfixCon >=> mMatch env p1 >=> mMatch env p2
go _ = const []
data PatMap a
= PatEmpty
| PatMap { pmHole :: Map RdrName a
, pmWild :: MaybeMap a
, pmVar :: MaybeMap a
, pmParPat :: PatMap a
, pmTuplePat :: BoxityMap (ListMap PatMap a)
, pmConPatIn :: FSEnv (CDMap a)
}
deriving (Functor)
emptyPatMapWrapper :: PatMap a
emptyPatMapWrapper = PatMap mEmpty mEmpty mEmpty mEmpty mEmpty mEmpty
instance PatternMap PatMap where
type Key PatMap = LPat GhcPs
mEmpty :: PatMap a
mEmpty = PatEmpty
mUnion :: PatMap a -> PatMap a -> PatMap a
mUnion PatEmpty m = m
mUnion m PatEmpty = m
mUnion (PatMap a1 b1 c1 d1 e1 f1)
(PatMap a2 b2 c2 d2 e2 f2) =
PatMap (mUnion a1 a2)
(mUnion b1 b2)
(mUnion c1 c2)
(mUnion d1 d2)
(mUnion e1 e2)
(mUnion f1 f2)
mAlter :: AlphaEnv -> Quantifiers -> Key PatMap -> A a -> PatMap a -> PatMap a
mAlter env vs pat f PatEmpty = mAlter env vs pat f emptyPatMapWrapper
mAlter env vs pat f m@PatMap{} = go (unLoc pat)
where
go (WildPat _) = m { pmWild = mAlter env vs () f (pmWild m) }
#if __GLASGOW_HASKELL__ < 806
go (VarPat v)
#else
go (VarPat _ v)
#endif
| unLoc v `isQ` vs = m { pmHole = mAlter env vs (unLoc v) f (pmHole m) }
| otherwise = m { pmVar = mAlter env vs () f (pmVar m) }
go LazyPat{} = error "LazyPat"
go AsPat{} = error "AsPat"
go BangPat{} = error "BangPat"
go ListPat{} = error "ListPat"
go (ConPatIn c d) = m { pmConPatIn = mAlter env vs (rdrFS (unLoc c)) (toA (mAlter env vs d f)) (pmConPatIn m) }
go ConPatOut{} = error "ConPatOut"
go ViewPat{} = error "ViewPat"
go SplicePat{} = error "SplicePat"
go LitPat{} = error "LitPat"
go NPat{} = error "NPat"
go NPlusKPat{} = error "NPlusKPat"
#if __GLASGOW_HASKELL__ < 806
go (PArrPat _ _) = error "PArrPat"
go (ParPat p) = m { pmParPat = mAlter env vs p f (pmParPat m) }
go (SigPatIn _ _) = error "SigPatIn"
go (SigPatOut _ _) = error "SigPatOut"
go (TuplePat ps b _tys) =
m { pmTuplePat = mAlter env vs b (toA (mAlter env vs ps f)) (pmTuplePat m) }
#else
go (ParPat _ p) = m { pmParPat = mAlter env vs p f (pmParPat m) }
go (TuplePat _ ps b) =
m { pmTuplePat = mAlter env vs b (toA (mAlter env vs ps f)) (pmTuplePat m) }
go SigPat{} = error "SigPat"
go XPat{} = error "XPat"
#endif
go CoPat{} = error "CoPat"
go SumPat{} = error "SumPat"
mMatch :: MatchEnv -> Key PatMap -> (Substitution, PatMap a) -> [(Substitution, a)]
mMatch _ _ (_ ,PatEmpty) = []
#if __GLASGOW_HASKELL__ < 808
mMatch env pat (hs,m@PatMap{}) =
#else
mMatch env (dL -> pat) (hs,m@PatMap{}) =
#endif
hss ++ go (unLoc pat) (hs,m)
where
hss = extendResult (pmHole m) (HolePat $ mePruneA env pat) hs
go (WildPat _) = mapFor pmWild >=> mMatch env ()
#if __GLASGOW_HASKELL__ < 806
go (ParPat p) = mapFor pmParPat >=> mMatch env p
go (TuplePat ps b _) = mapFor pmTuplePat >=> mMatch env b >=> mMatch env ps
go (VarPat _) = mapFor pmVar >=> mMatch env ()
#else
go (ParPat _ p) = mapFor pmParPat >=> mMatch env p
go (TuplePat _ ps b) = mapFor pmTuplePat >=> mMatch env b >=> mMatch env ps
go (VarPat _ _) = mapFor pmVar >=> mMatch env ()
#endif
go (ConPatIn c d) = mapFor pmConPatIn >=> mMatch env (rdrFS (unLoc c)) >=> mMatch env d
go _ = const []
newtype GRHSSMap a = GRHSSMap { unGRHSSMap :: LBMap (ListMap GRHSMap a) }
deriving (Functor)
instance PatternMap GRHSSMap where
type Key GRHSSMap = GRHSs GhcPs (LHsExpr GhcPs)
mEmpty :: GRHSSMap a
mEmpty = GRHSSMap mEmpty
mUnion :: GRHSSMap a -> GRHSSMap a -> GRHSSMap a
mUnion (GRHSSMap m1) (GRHSSMap m2) = GRHSSMap (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key GRHSSMap -> A a -> GRHSSMap a -> GRHSSMap a
mAlter env vs grhss f (GRHSSMap m) =
let lbs = unLoc $ grhssLocalBinds grhss
bs = collectLocalBinders lbs
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in GRHSSMap (mAlter env vs lbs
(toA (mAlter env' vs' (map unLoc $ grhssGRHSs grhss) f)) m)
mMatch :: MatchEnv -> Key GRHSSMap -> (Substitution, GRHSSMap a) -> [(Substitution, a)]
mMatch env grhss = mapFor unGRHSSMap >=> mMatch env lbs
>=> mMatch env' (map unLoc $ grhssGRHSs grhss)
where
lbs = unLoc $ grhssLocalBinds grhss
bs = collectLocalBinders lbs
env' = extendMatchEnv env bs
newtype GRHSMap a = GRHSMap { unGRHSMap :: SLMap (EMap a) }
deriving (Functor)
instance PatternMap GRHSMap where
type Key GRHSMap = GRHS GhcPs (LHsExpr GhcPs)
mEmpty :: GRHSMap a
mEmpty = GRHSMap mEmpty
mUnion :: GRHSMap a -> GRHSMap a -> GRHSMap a
mUnion (GRHSMap m1) (GRHSMap m2) = GRHSMap (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key GRHSMap -> A a -> GRHSMap a -> GRHSMap a
#if __GLASGOW_HASKELL__ < 806
mAlter env vs (GRHS gs b) f (GRHSMap m) =
#else
mAlter _ _ XGRHS{} _ _ = error "XGRHS"
mAlter env vs (GRHS _ gs b) f (GRHSMap m) =
#endif
let bs = collectLStmtsBinders gs
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in GRHSMap (mAlter env vs gs (toA (mAlter env' vs' b f)) m)
mMatch :: MatchEnv -> Key GRHSMap -> (Substitution, GRHSMap a) -> [(Substitution, a)]
#if __GLASGOW_HASKELL__ < 806
mMatch env (GRHS gs b) =
#else
mMatch _ XGRHS{} = const []
mMatch env (GRHS _ gs b) =
#endif
mapFor unGRHSMap >=> mMatch env gs >=> mMatch env' b
where
bs = collectLStmtsBinders gs
env' = extendMatchEnv env bs
data SLMap a
= SLEmpty
| SLM { slmNil :: MaybeMap a
, slmCons :: SMap (SLMap a)
}
deriving (Functor)
emptySLMapWrapper :: SLMap a
emptySLMapWrapper = SLM mEmpty mEmpty
instance PatternMap SLMap where
type Key SLMap = [LStmt GhcPs (LHsExpr GhcPs)]
mEmpty :: SLMap a
mEmpty = SLEmpty
mUnion :: SLMap a -> SLMap a -> SLMap a
mUnion SLEmpty m = m
mUnion m SLEmpty = m
mUnion (SLM a1 b1) (SLM a2 b2) = SLM (mUnion a1 a2) (mUnion b1 b2)
mAlter :: AlphaEnv -> Quantifiers -> Key SLMap -> A a -> SLMap a -> SLMap a
mAlter env vs ss f SLEmpty = mAlter env vs ss f emptySLMapWrapper
mAlter env vs ss f m@SLM{} = go ss
where
go [] = m { slmNil = mAlter env vs () f (slmNil m) }
go (s:ss') =
let
bs = collectLStmtBinders s
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in m { slmCons = mAlter env vs s (toA (mAlter env' vs' ss' f)) (slmCons m) }
mMatch :: MatchEnv -> Key SLMap -> (Substitution, SLMap a) -> [(Substitution, a)]
mMatch _ _ (_,SLEmpty) = []
mMatch env ss (hs,m@SLM{}) = go ss (hs,m)
where
go [] = mapFor slmNil >=> mMatch env ()
go (s:ss') =
let
bs = collectLStmtBinders s
env' = extendMatchEnv env bs
in mapFor slmCons >=> mMatch env s >=> mMatch env' ss'
data LBMap a
= LBEmpty
| LB { lbValBinds :: ListMap BMap a
, lbEmpty :: MaybeMap a
}
deriving (Functor)
emptyLBMapWrapper :: LBMap a
emptyLBMapWrapper = LB mEmpty mEmpty
instance PatternMap LBMap where
type Key LBMap = HsLocalBinds GhcPs
mEmpty :: LBMap a
mEmpty = LBEmpty
mUnion :: LBMap a -> LBMap a -> LBMap a
mUnion LBEmpty m = m
mUnion m LBEmpty = m
mUnion (LB a1 b1) (LB a2 b2) =
LB (mUnion a1 a2) (mUnion b1 b2)
mAlter :: AlphaEnv -> Quantifiers -> Key LBMap -> A a -> LBMap a -> LBMap a
mAlter env vs lbs f LBEmpty = mAlter env vs lbs f emptyLBMapWrapper
mAlter env vs lbs f m@LB{} = go lbs
where
#if __GLASGOW_HASKELL__ < 806
go EmptyLocalBinds = m { lbEmpty = mAlter env vs () f (lbEmpty m) }
go (HsValBinds vbs) =
#else
go (EmptyLocalBinds _) = m { lbEmpty = mAlter env vs () f (lbEmpty m) }
go XHsLocalBindsLR{} = error "XHsLocalBindsLR"
go (HsValBinds _ vbs) =
#endif
let
bs = collectHsValBinders vbs
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in m { lbValBinds = mAlter env' vs' (deValBinds vbs) f (lbValBinds m) }
go HsIPBinds{} = error "HsIPBinds"
mMatch :: MatchEnv -> Key LBMap -> (Substitution, LBMap a) -> [(Substitution, a)]
mMatch _ _ (_,LBEmpty) = []
mMatch env lbs (hs,m@LB{}) = go lbs (hs,m)
where
#if __GLASGOW_HASKELL__ < 806
go EmptyLocalBinds = mapFor lbEmpty >=> mMatch env ()
go (HsValBinds vbs) =
#else
go (EmptyLocalBinds _) = mapFor lbEmpty >=> mMatch env ()
go (HsValBinds _ vbs) =
#endif
let
bs = collectHsValBinders vbs
env' = extendMatchEnv env bs
in mapFor lbValBinds >=> mMatch env' (deValBinds vbs)
go _ = const []
deValBinds :: HsValBinds GhcPs -> [HsBind GhcPs]
#if __GLASGOW_HASKELL__ < 806
deValBinds (ValBindsIn lbs _) = map unLoc (bagToList lbs)
#else
deValBinds (ValBinds _ lbs _) = map unLoc (bagToList lbs)
#endif
deValBinds _ = error "deValBinds ValBindsOut"
data BMap a
= BMEmpty
| BM { bmFunBind :: MGMap a
, bmVarBind :: EMap a
, bmPatBind :: PatMap (GRHSSMap a)
}
deriving (Functor)
emptyBMapWrapper :: BMap a
emptyBMapWrapper = BM mEmpty mEmpty mEmpty
instance PatternMap BMap where
type Key BMap = HsBind GhcPs
mEmpty :: BMap a
mEmpty = BMEmpty
mUnion :: BMap a -> BMap a -> BMap a
mUnion BMEmpty m = m
mUnion m BMEmpty = m
mUnion (BM a1 b1 c1) (BM a2 b2 c2)
= BM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2)
mAlter :: AlphaEnv -> Quantifiers -> Key BMap -> A a -> BMap a -> BMap a
mAlter env vs b f BMEmpty = mAlter env vs b f emptyBMapWrapper
mAlter env vs b f m@BM{} = go b
where
#if __GLASGOW_HASKELL__ < 806
go (FunBind _ mg _ _ _) = m { bmFunBind = mAlter env vs mg f (bmFunBind m) }
go (VarBind _ e _) = m { bmVarBind = mAlter env vs e f (bmVarBind m) }
go (PatBind lhs rhs _ _ _) =
#else
go (FunBind _ _ mg _ _) = m { bmFunBind = mAlter env vs mg f (bmFunBind m) }
go (VarBind _ _ e _) = m { bmVarBind = mAlter env vs e f (bmVarBind m) }
go XHsBindsLR{} = error "XHsBindsLR"
go (PatBind _ lhs rhs _) =
#endif
m { bmPatBind = mAlter env vs lhs
(toA $ mAlter env vs rhs f) (bmPatBind m) }
go AbsBinds{} = error "AbsBinds"
go PatSynBind{} = error "PatSynBind"
mMatch :: MatchEnv -> Key BMap -> (Substitution, BMap a) -> [(Substitution, a)]
mMatch _ _ (_,BMEmpty) = []
mMatch env b (hs,m@BM{}) = go b (hs,m)
where
#if __GLASGOW_HASKELL__ < 806
go (FunBind _ mg _ _ _) = mapFor bmFunBind >=> mMatch env mg
go (VarBind _ e _) = mapFor bmVarBind >=> mMatch env e
go (PatBind lhs rhs _ _ _)
#else
go (FunBind _ _ mg _ _) = mapFor bmFunBind >=> mMatch env mg
go (VarBind _ _ e _) = mapFor bmVarBind >=> mMatch env e
go (PatBind _ lhs rhs _)
#endif
= mapFor bmPatBind >=> mMatch env lhs >=> mMatch env rhs
go _ = const []
data SMap a
= SMEmpty
| SM { smLastStmt :: EMap a
, smBindStmt :: PatMap (EMap a)
, smBodyStmt :: EMap a
}
deriving (Functor)
emptySMapWrapper :: SMap a
emptySMapWrapper = SM mEmpty mEmpty mEmpty
instance PatternMap SMap where
type Key SMap = LStmt GhcPs (LHsExpr GhcPs)
mEmpty :: SMap a
mEmpty = SMEmpty
mUnion :: SMap a -> SMap a -> SMap a
mUnion SMEmpty m = m
mUnion m SMEmpty = m
mUnion (SM a1 b1 c1) (SM a2 b2 c2) =
SM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2)
mAlter :: AlphaEnv -> Quantifiers -> Key SMap -> A a -> SMap a -> SMap a
mAlter env vs s f SMEmpty = mAlter env vs s f emptySMapWrapper
mAlter env vs s f m@(SM {}) = go (unLoc s)
where
#if __GLASGOW_HASKELL__ < 806
go (BodyStmt e _ _ _) = m { smBodyStmt = mAlter env vs e f (smBodyStmt m) }
go (LastStmt e _ _) = m { smLastStmt = mAlter env vs e f (smLastStmt m) }
go (BindStmt p e _ _ _) =
#else
go (BodyStmt _ e _ _) = m { smBodyStmt = mAlter env vs e f (smBodyStmt m) }
go (LastStmt _ e _ _) = m { smLastStmt = mAlter env vs e f (smLastStmt m) }
go XStmtLR{} = error "XStmtLR"
go (BindStmt _ p e _ _) =
#endif
let bs = collectPatBinders p
env' = foldr extendAlphaEnvInternal env bs
vs' = vs `exceptQ` bs
in m { smBindStmt = mAlter env vs p
(toA (mAlter env' vs' e f)) (smBindStmt m) }
go LetStmt{} = error "LetStmt"
go ParStmt{} = error "ParStmt"
go TransStmt{} = error "TransStmt"
go RecStmt{} = error "RecStmt"
go ApplicativeStmt{} = error "ApplicativeStmt"
mMatch :: MatchEnv -> Key SMap -> (Substitution, SMap a) -> [(Substitution, a)]
mMatch _ _ (_,SMEmpty) = []
mMatch env s (hs,m) = go (unLoc s) (hs,m)
where
#if __GLASGOW_HASKELL__ < 806
go (BodyStmt e _ _ _) = mapFor smBodyStmt >=> mMatch env e
go (LastStmt e _ _) = mapFor smLastStmt >=> mMatch env e
go (BindStmt p e _ _ _) =
#else
go (BodyStmt _ e _ _) = mapFor smBodyStmt >=> mMatch env e
go (LastStmt _ e _ _) = mapFor smLastStmt >=> mMatch env e
go (BindStmt _ p e _ _) =
#endif
let bs = collectPatBinders p
env' = extendMatchEnv env bs
in mapFor smBindStmt >=> mMatch env p >=> mMatch env' e
go _ = const []
data TyMap a
= TyEmpty
| TM { tyHole :: Map RdrName a
, tyHsTyVar :: VMap a
, tyHsFunTy :: TyMap (TyMap a)
, tyHsAppTy :: TyMap (TyMap a)
#if __GLASGOW_HASKELL__ < 806
, tyHsAppsTy :: ListMap AppTyMap a
#endif
, tyHsParTy :: TyMap a
-- TODO: the rest
}
deriving (Functor)
emptyTyMapWrapper :: TyMap a
emptyTyMapWrapper =
TM mEmpty mEmpty mEmpty mEmpty mEmpty
#if __GLASGOW_HASKELL__ < 806
mEmpty
#endif
instance PatternMap TyMap where
type Key TyMap = LHsType GhcPs
mEmpty :: TyMap a
mEmpty = TyEmpty
mUnion :: TyMap a -> TyMap a -> TyMap a
mUnion TyEmpty m = m
mUnion m TyEmpty = m
#if __GLASGOW_HASKELL__ < 806
mUnion (TM a1 b1 c1 d1 e1 f1) (TM a2 b2 c2 d2 e2 f2) =
TM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2) (mUnion d1 d2)
(mUnion e1 e2) (mUnion f1 f2)
#else
mUnion (TM a1 b1 c1 d1 e1) (TM a2 b2 c2 d2 e2) =
TM (mUnion a1 a2) (mUnion b1 b2) (mUnion c1 c2) (mUnion d1 d2)
(mUnion e1 e2)
#endif
mAlter :: AlphaEnv -> Quantifiers -> Key TyMap -> A a -> TyMap a -> TyMap a
mAlter env vs ty f TyEmpty = mAlter env vs ty f emptyTyMapWrapper
#if __GLASGOW_HASKELL__ < 806
mAlter env vs (tyLookThrough -> ty) f m@(TM {}) =
#else
mAlter env vs ty f m@(TM {}) =
#endif
go (unLoc ty)
where
#if __GLASGOW_HASKELL__ < 806
go (HsTyVar _ (L _ v))
#else
go (HsTyVar _ _ (L _ v))
#endif
| v `isQ` vs = m { tyHole = mAlter env vs v f (tyHole m) }
| otherwise = m { tyHsTyVar = mAlter env vs v f (tyHsTyVar m) }
go HsForAllTy{} = error "HsForAllTy"
go HsQualTy{} = error "HsQualTy"
go HsListTy{} = error "HsListTy"
go HsTupleTy{} = error "HsTupleTy"
go HsOpTy{} = error "HsOpTy"
go HsIParamTy{} = error "HsIParamTy"
go HsKindSig{} = error "HsKindSig"
go HsSpliceTy{} = error "HsSpliceTy"
go HsDocTy{} = error "HsDocTy"
go HsBangTy{} = error "HsBangTy"
go HsRecTy{} = error "HsRecTy"
#if __GLASGOW_HASKELL__ < 806
go (HsAppsTy atys) = m { tyHsAppsTy = mAlter env vs atys f (tyHsAppsTy m) }
go (HsAppTy ty1 ty2) = m { tyHsAppTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsAppTy m) }
go (HsFunTy ty1 ty2) = m { tyHsFunTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsFunTy m) }
go (HsCoreTy _) = error "HsCoreTy"
go (HsEqTy _ _) = error "HsEqTy"
go (HsParTy ty') = m { tyHsParTy = mAlter env vs ty' f (tyHsParTy m) }
go (HsPArrTy _) = error "HsPArrTy"
#else
go (HsAppTy _ ty1 ty2) = m { tyHsAppTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsAppTy m) }
go (HsFunTy _ ty1 ty2) = m { tyHsFunTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsFunTy m) }
go (HsParTy _ ty') = m { tyHsParTy = mAlter env vs ty' f (tyHsParTy m) }
go HsStarTy{} = error "HsStarTy"
go XHsType{} = error "XHsType"
#endif
go HsExplicitListTy{} = error "HsExplicitListTy"
go HsExplicitTupleTy{} = error "HsExplicitTupleTy"
go HsTyLit{} = error "HsTyLit"
go HsWildCardTy{} = error "HsWildCardTy"
go HsSumTy{} = error "HsSumTy"
#if __GLASGOW_HASKELL__ < 808
#else
go HsAppKindTy{} = error "HsAppKindTy"
#endif
mMatch :: MatchEnv -> Key TyMap -> (Substitution, TyMap a) -> [(Substitution, a)]
mMatch _ _ (_,TyEmpty) = []
#if __GLASGOW_HASKELL__ < 806
mMatch env (tyLookThrough -> ty) (hs,m@TM{}) =
#else
mMatch env ty (hs,m@TM{}) =
#endif
hss ++ go (unLoc ty) (hs,m)
where
hss = extendResult (tyHole m) (HoleType $ mePruneA env ty) hs
#if __GLASGOW_HASKELL__ < 806
go (HsAppTy ty1 ty2) = mapFor tyHsAppTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsAppsTy atys) = mapFor tyHsAppsTy >=> mMatch env atys
go (HsFunTy ty1 ty2) = mapFor tyHsFunTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsParTy ty') = mapFor tyHsParTy >=> mMatch env ty'
go (HsTyVar _ v) = mapFor tyHsTyVar >=> mMatch env (unLoc v)
#else
go (HsAppTy _ ty1 ty2) = mapFor tyHsAppTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsFunTy _ ty1 ty2) = mapFor tyHsFunTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsParTy _ ty') = mapFor tyHsParTy >=> mMatch env ty'
go (HsTyVar _ _ v) = mapFor tyHsTyVar >=> mMatch env (unLoc v)
#endif
go _ = const []
#if __GLASGOW_HASKELL__ < 806
tyLookThrough :: Key TyMap -> Key TyMap
tyLookThrough (L _ (HsAppsTy [L _ (HsAppPrefix ty)])) = ty
tyLookThrough ty = ty
data AppTyMap a
= AppTyEmpty
| ATM { atmAppInfix :: VMap a
, atmAppPrefix :: TyMap a
}
deriving (Functor)
emptyAppTyMapWrapper :: AppTyMap a
emptyAppTyMapWrapper = ATM mEmpty mEmpty
instance PatternMap AppTyMap where
type Key AppTyMap = LHsAppType GhcPs
mEmpty :: AppTyMap a
mEmpty = AppTyEmpty
mUnion :: AppTyMap a -> AppTyMap a -> AppTyMap a
mUnion AppTyEmpty m = m
mUnion m AppTyEmpty = m
mUnion (ATM a1 b1) (ATM a2 b2) =
ATM (mUnion a1 a2) (mUnion b1 b2)
mAlter :: AlphaEnv -> Quantifiers -> Key AppTyMap -> A a -> AppTyMap a -> AppTyMap a
mAlter env vs aty f AppTyEmpty = mAlter env vs aty f emptyAppTyMapWrapper
mAlter env vs aty f m@(ATM {}) = go (unLoc aty)
where
go (HsAppInfix r) = m { atmAppInfix = mAlter env vs (unLoc r) f (atmAppInfix m) }
go (HsAppPrefix ty) = m { atmAppPrefix = mAlter env vs ty f (atmAppPrefix m) }
mMatch :: MatchEnv -> Key AppTyMap -> (Substitution, AppTyMap a) -> [(Substitution, a)]
mMatch _ _ (_,AppTyEmpty) = []
mMatch env aty (hs,m@ATM{}) = go (unLoc aty) (hs,m)
where
go (HsAppInfix r) = mapFor atmAppInfix >=> mMatch env (unLoc r)
go (HsAppPrefix ty) = mapFor atmAppPrefix >=> mMatch env ty
#endif
newtype RFMap a = RFM { rfmField :: VMap (EMap a) }
deriving (Functor)
instance PatternMap RFMap where
type Key RFMap = LHsRecField' RdrName (LHsExpr GhcPs)
mEmpty :: RFMap a
mEmpty = RFM mEmpty
mUnion :: RFMap a -> RFMap a -> RFMap a
mUnion (RFM m1) (RFM m2) = RFM (mUnion m1 m2)
mAlter :: AlphaEnv -> Quantifiers -> Key RFMap -> A a -> RFMap a -> RFMap a
mAlter env vs lf f m = go (unLoc lf)
where
go (HsRecField lbl arg _pun) =
m { rfmField = mAlter env vs (unLoc lbl) (toA (mAlter env vs arg f)) (rfmField m) }
mMatch :: MatchEnv -> Key RFMap -> (Substitution, RFMap a) -> [(Substitution, a)]
mMatch env lf (hs,m) = go (unLoc lf) (hs,m)
where
go (HsRecField lbl arg _pun) =
mapFor rfmField >=> mMatch env (unLoc lbl) >=> mMatch env arg
class RecordFieldToRdrName f where
recordFieldToRdrName :: f -> RdrName
#if __GLASGOW_HASKELL__ < 806
instance RecordFieldToRdrName (AmbiguousFieldOcc p) where
#else
instance RecordFieldToRdrName (AmbiguousFieldOcc GhcPs) where
#endif
recordFieldToRdrName = rdrNameAmbiguousFieldOcc
instance RecordFieldToRdrName (FieldOcc p) where
recordFieldToRdrName = unLoc . rdrNameFieldOcc
fieldsToRdrNames
:: RecordFieldToRdrName f
=> [LHsRecField' f arg]
-> [LHsRecField' RdrName arg]
fieldsToRdrNames = map go
where
go (L l (HsRecField (L l2 f) arg pun)) =
L l (HsRecField (L l2 (recordFieldToRdrName f)) arg pun)