{-# 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 m1 m2 = TupArgMap
{ tamPresent = unionOn tamPresent m1 m2
, tamMissing = unionOn tamMissing 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{} = missingSyntax "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 m1 m2 = BoxityMap
{ boxBoxed = unionOn boxBoxed m1 m2
, boxUnboxed = unionOn boxUnboxed m1 m2
}
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 m1 m2 = VM
{ bvmap = unionOn bvmap m1 m2
, fvmap = unionOn fvmap m1 m2
}
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 m1 m2 = LM
{ lmChar = unionOn lmChar m1 m2
, lmCharPrim = unionOn lmCharPrim m1 m2
, lmString = unionOn lmString m1 m2
, lmStringPrim = unionOn lmStringPrim m1 m2
, lmInt = unionOn lmInt m1 m2
, lmIntPrim = unionOn lmIntPrim m1 m2
, lmWordPrim = unionOn lmWordPrim m1 m2
, lmInt64Prim = unionOn lmInt64Prim m1 m2
, lmWord64Prim = unionOn lmWord64Prim m1 m2
}
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 _ _ _) = missingSyntax "HsInteger"
go HsRat{} = missingSyntax "HsRat"
go HsFloatPrim{} = missingSyntax "HsFloatPrim"
go HsDoublePrim{} = missingSyntax "HsDoublePrim"
#if __GLASGOW_HASKELL__ < 806
#else
go XLit{} = missingSyntax "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 m1 m2 = OLM
{ olmIntegral = unionOn olmIntegral m1 m2
, olmFractional = unionOn olmFractional m1 m2
, olmIsString = unionOn olmIsString m1 m2
}
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 m1 m2 = EM
{ emHole = unionOn emHole m1 m2
, emVar = unionOn emVar m1 m2
, emIPVar = unionOn emIPVar m1 m2
, emOverLit = unionOn emOverLit m1 m2
, emLit = unionOn emLit m1 m2
, emLam = unionOn emLam m1 m2
, emApp = unionOn emApp m1 m2
, emOpApp = unionOn emOpApp m1 m2
, emNegApp = unionOn emNegApp m1 m2
, emPar = unionOn emPar m1 m2
, emExplicitTuple = unionOn emExplicitTuple m1 m2
, emCase = unionOn emCase m1 m2
, emSecL = unionOn emSecL m1 m2
, emSecR = unionOn emSecR m1 m2
, emIf = unionOn emIf m1 m2
, emLet = unionOn emLet m1 m2
, emDo = unionOn emDo m1 m2
, emExplicitList = unionOn emExplicitList m1 m2
, emRecordCon = unionOn emRecordCon m1 m2
, emRecordUpd = unionOn emRecordUpd m1 m2
, emExprWithTySig = unionOn emExprWithTySig m1 m2
}
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 noExtField l (noLoc (HsPar noExtField 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{} = missingSyntax "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{} = missingSyntax "HsLamCase"
go HsMultiIf{} = missingSyntax "HsMultiIf"
go (ExplicitList _ _ es) = m { emExplicitList = mAlter env vs es f (emExplicitList m) }
go ArithSeq{} = missingSyntax "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{} = missingSyntax "ExprWithTySig"
#endif
go HsSCC{} = missingSyntax "HsSCC"
go HsCoreAnn{} = missingSyntax "HsCoreAnn"
go HsBracket{} = missingSyntax "HsBracket"
go HsRnBracketOut{} = missingSyntax "HsRnBracketOut"
go HsTcBracketOut{} = missingSyntax "HsTcBracketOut"
go HsSpliceE{} = missingSyntax "HsSpliceE"
go HsProc{} = missingSyntax "HsProc"
go HsStatic{} = missingSyntax "HsStatic"
#if __GLASGOW_HASKELL__ < 810
go HsArrApp{} = missingSyntax "HsArrApp"
go HsArrForm{} = missingSyntax "HsArrForm"
go EWildPat{} = missingSyntax "EWildPat"
go EAsPat{} = missingSyntax "EAsPat"
go EViewPat{} = missingSyntax "EViewPat"
go ELazyPat{} = missingSyntax "ELazyPat"
#endif
go HsTick{} = missingSyntax "HsTick"
go HsBinTick{} = missingSyntax "HsBinTick"
go HsTickPragma{} = missingSyntax "HsTickPragma"
go HsWrap{} = missingSyntax "HsWrap"
go HsUnboundVar{} = missingSyntax "HsUnboundVar"
go HsRecFld{} = missingSyntax "HsRecFld"
go HsOverLabel{} = missingSyntax "HsOverLabel"
go HsAppType{} = missingSyntax "HsAppType"
go HsConLikeOut{} = missingSyntax "HsConLikeOut"
go ExplicitSum{} = missingSyntax "ExplicitSum"
#if __GLASGOW_HASKELL__ < 806
go ExplicitPArr{} = missingSyntax "ExplicitPArr"
go ExprWithTySigOut{} = missingSyntax "ExprWithTySigOut"
go HsAppTypeOut{} = missingSyntax "HsAppTypeOut"
go PArrSeq{} = missingSyntax "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 m1 m2 = SCM
{ scmListComp = unionOn scmListComp m1 m2
, scmMonadComp = unionOn scmMonadComp m1 m2
, scmDoExpr = unionOn scmDoExpr m1 m2
}
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 = missingSyntax "PArrComp"
#endif
go DoExpr = m { scmDoExpr = mAlter env vs () f (scmDoExpr m) }
go MDoExpr = missingSyntax "MDoExpr"
go ArrowExpr = missingSyntax "ArrowExpr"
go GhciStmtCtxt = missingSyntax "GhciStmtCtxt"
go (PatGuard _) = missingSyntax "PatGuard"
go (ParStmtCtxt _) = missingSyntax "ParStmtCtxt"
go (TransStmtCtxt _) = missingSyntax "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
#if __GLASGOW_HASKELL__ < 810
type Key CDMap = HsConDetails (LPat GhcPs) (HsRecFields GhcPs (LPat GhcPs))
#else
type Key CDMap = HsConDetails (Located (Pat GhcPs)) (HsRecFields GhcPs (Located (Pat GhcPs)))
#endif
mEmpty :: CDMap a
mEmpty = CDEmpty
mUnion :: CDMap a -> CDMap a -> CDMap a
mUnion CDEmpty m = m
mUnion m CDEmpty = m
mUnion m1 m2 = CDMap
{ cdPrefixCon = unionOn cdPrefixCon m1 m2
, cdInfixCon = unionOn cdInfixCon m1 m2
}
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 _) = missingSyntax "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
#if __GLASGOW_HASKELL__ < 810
type Key PatMap = LPat GhcPs
#else
type Key PatMap = Located (Pat GhcPs)
#endif
mEmpty :: PatMap a
mEmpty = PatEmpty
mUnion :: PatMap a -> PatMap a -> PatMap a
mUnion PatEmpty m = m
mUnion m PatEmpty = m
mUnion m1 m2 = PatMap
{ pmHole = unionOn pmHole m1 m2
, pmWild = unionOn pmWild m1 m2
, pmVar = unionOn pmVar m1 m2
, pmParPat = unionOn pmParPat m1 m2
, pmTuplePat = unionOn pmTuplePat m1 m2
, pmConPatIn = unionOn pmConPatIn m1 m2
}
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{} = missingSyntax "LazyPat"
go AsPat{} = missingSyntax "AsPat"
go BangPat{} = missingSyntax "BangPat"
go ListPat{} = missingSyntax "ListPat"
go (ConPatIn c d) = m { pmConPatIn = mAlter env vs (rdrFS (unLoc c)) (toA (mAlter env vs d f)) (pmConPatIn m) }
go ConPatOut{} = missingSyntax "ConPatOut"
go ViewPat{} = missingSyntax "ViewPat"
go SplicePat{} = missingSyntax "SplicePat"
go LitPat{} = missingSyntax "LitPat"
go NPat{} = missingSyntax "NPat"
go NPlusKPat{} = missingSyntax "NPlusKPat"
#if __GLASGOW_HASKELL__ < 806
go (PArrPat _ _) = missingSyntax "PArrPat"
go (ParPat p) = m { pmParPat = mAlter env vs p f (pmParPat m) }
go (SigPatIn _ _) = missingSyntax "SigPatIn"
go (SigPatOut _ _) = missingSyntax "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{} = missingSyntax "SigPat"
go XPat{} = missingSyntax "XPat"
#endif
go CoPat{} = missingSyntax "CoPat"
go SumPat{} = missingSyntax "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{} _ _ = missingSyntax "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 m1 m2 = SLM
{ slmNil = unionOn slmNil m1 m2
, slmCons = unionOn slmCons m1 m2
}
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 m1 m2 = LB
{ lbValBinds = unionOn lbValBinds m1 m2
, lbEmpty = unionOn lbEmpty m1 m2
}
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{} = missingSyntax "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{} = missingSyntax "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 m1 m2 = BM
{ bmFunBind = unionOn bmFunBind m1 m2
, bmVarBind = unionOn bmVarBind m1 m2
, bmPatBind = unionOn bmPatBind m1 m2
}
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{} = missingSyntax "XHsBindsLR"
go (PatBind _ lhs rhs _) =
#endif
m { bmPatBind = mAlter env vs lhs
(toA $ mAlter env vs rhs f) (bmPatBind m) }
go AbsBinds{} = missingSyntax "AbsBinds"
go PatSynBind{} = missingSyntax "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 m1 m2 = SM
{ smLastStmt = unionOn smLastStmt m1 m2
, smBindStmt = unionOn smBindStmt m1 m2
, smBodyStmt = unionOn smBodyStmt m1 m2
}
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{} = missingSyntax "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{} = missingSyntax "LetStmt"
go ParStmt{} = missingSyntax "ParStmt"
go TransStmt{} = missingSyntax "TransStmt"
go RecStmt{} = missingSyntax "RecStmt"
go ApplicativeStmt{} = missingSyntax "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
, tyHsAppTy :: TyMap (TyMap a)
#if __GLASGOW_HASKELL__ < 806
, tyHsAppsTy :: ListMap AppTyMap a
#endif
#if __GLASGOW_HASKELL__ < 810
, tyHsForAllTy :: ForAllTyMap a
#else
, tyHsForAllTy :: ForallVisMap (ForAllTyMap a)
#endif
, tyHsFunTy :: TyMap (TyMap a)
, tyHsListTy :: TyMap a
, tyHsParTy :: TyMap a
, tyHsQualTy :: TyMap (ListMap TyMap a)
, tyHsSumTy :: ListMap TyMap a
, tyHsTupleTy :: TupleSortMap (ListMap TyMap a)
-- TODO: the rest
}
deriving (Functor)
emptyTyMapWrapper :: TyMap a
emptyTyMapWrapper = TM
mEmpty mEmpty mEmpty
#if __GLASGOW_HASKELL__ < 806
mEmpty
#endif
mEmpty mEmpty mEmpty mEmpty mEmpty mEmpty mEmpty
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
mUnion m1 m2 = TM
{ tyHole = unionOn tyHole m1 m2
, tyHsTyVar = unionOn tyHsTyVar m1 m2
, tyHsAppTy = unionOn tyHsAppTy m1 m2
#if __GLASGOW_HASKELL__ < 806
, tyHsAppsTy = unionOn tyHsAppsTy m1 m2
#endif
, tyHsForAllTy = unionOn tyHsForAllTy m1 m2
, tyHsFunTy = unionOn tyHsFunTy m1 m2
, tyHsListTy = unionOn tyHsListTy m1 m2
, tyHsParTy = unionOn tyHsParTy m1 m2
, tyHsQualTy = unionOn tyHsQualTy m1 m2
, tyHsSumTy = unionOn tyHsSumTy m1 m2
, tyHsTupleTy = unionOn tyHsTupleTy m1 m2
}
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 HsOpTy{} = missingSyntax "HsOpTy"
go HsIParamTy{} = missingSyntax "HsIParamTy"
go HsKindSig{} = missingSyntax "HsKindSig"
go HsSpliceTy{} = missingSyntax "HsSpliceTy"
go HsDocTy{} = missingSyntax "HsDocTy"
go HsBangTy{} = missingSyntax "HsBangTy"
go HsRecTy{} = missingSyntax "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 (HsCoreTy _) = missingSyntax "HsCoreTy"
go (HsEqTy _ _) = missingSyntax "HsEqTy"
go (HsForAllTy bndrs ty') = m { tyHsForAllTy = mAlter env vs (bndrs, ty') f (tyHsForAllTy m) }
go (HsFunTy ty1 ty2) = m { tyHsFunTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsFunTy m) }
go (HsListTy ty') = m { tyHsListTy = mAlter env vs ty' f (tyHsListTy m) }
go (HsParTy ty') = m { tyHsParTy = mAlter env vs ty' f (tyHsParTy m) }
go (HsPArrTy _) = missingSyntax "HsPArrTy"
go (HsQualTy (L _ cons) ty') =
m { tyHsQualTy = mAlter env vs ty' (toA (mAlter env vs cons f)) (tyHsQualTy m) }
go (HsSumTy tys) = m { tyHsSumTy = mAlter env vs tys f (tyHsSumTy m) }
go (HsTupleTy ts tys) =
m { tyHsTupleTy = mAlter env vs ts (toA (mAlter env vs tys f)) (tyHsTupleTy m) }
#else
go (HsAppTy _ ty1 ty2) = m { tyHsAppTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsAppTy m) }
#if __GLASGOW_HASKELL__ < 810
go (HsForAllTy _ bndrs ty') = m { tyHsForAllTy = mAlter env vs (bndrs, ty') f (tyHsForAllTy m) }
#else
go (HsForAllTy _ vis bndrs ty') =
m { tyHsForAllTy = mAlter env vs vis (toA (mAlter env vs (bndrs, ty') f)) (tyHsForAllTy m) }
#endif
go (HsFunTy _ ty1 ty2) = m { tyHsFunTy = mAlter env vs ty1 (toA (mAlter env vs ty2 f)) (tyHsFunTy m) }
go (HsListTy _ ty') = m { tyHsListTy = mAlter env vs ty' f (tyHsListTy m) }
go (HsParTy _ ty') = m { tyHsParTy = mAlter env vs ty' f (tyHsParTy m) }
go (HsQualTy _ (L _ cons) ty') =
m { tyHsQualTy = mAlter env vs ty' (toA (mAlter env vs cons f)) (tyHsQualTy m) }
go HsStarTy{} = missingSyntax "HsStarTy"
go (HsSumTy _ tys) = m { tyHsSumTy = mAlter env vs tys f (tyHsSumTy m) }
go (HsTupleTy _ ts tys) =
m { tyHsTupleTy = mAlter env vs ts (toA (mAlter env vs tys f)) (tyHsTupleTy m) }
go XHsType{} = missingSyntax "XHsType"
#endif
go HsExplicitListTy{} = missingSyntax "HsExplicitListTy"
go HsExplicitTupleTy{} = missingSyntax "HsExplicitTupleTy"
go HsTyLit{} = missingSyntax "HsTyLit"
go HsWildCardTy{} = missingSyntax "HsWildCardTy"
#if __GLASGOW_HASKELL__ < 808
#else
go HsAppKindTy{} = missingSyntax "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 (HsForAllTy bndrs ty') = mapFor tyHsForAllTy >=> mMatch env (bndrs, ty')
go (HsFunTy ty1 ty2) = mapFor tyHsFunTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsListTy ty') = mapFor tyHsListTy >=> mMatch env ty'
go (HsParTy ty') = mapFor tyHsParTy >=> mMatch env ty'
go (HsQualTy (L _ cons) ty') = mapFor tyHsQualTy >=> mMatch env ty' >=> mMatch env cons
go (HsSumTy tys) = mapFor tyHsSumTy >=> mMatch env tys
go (HsTupleTy ts tys) = mapFor tyHsTupleTy >=> mMatch env ts >=> mMatch env tys
go (HsTyVar _ v) = mapFor tyHsTyVar >=> mMatch env (unLoc v)
#else
go (HsAppTy _ ty1 ty2) = mapFor tyHsAppTy >=> mMatch env ty1 >=> mMatch env ty2
#if __GLASGOW_HASKELL__ < 810
go (HsForAllTy _ bndrs ty') = mapFor tyHsForAllTy >=> mMatch env (bndrs, ty')
#else
go (HsForAllTy _ vis bndrs ty') =
mapFor tyHsForAllTy >=> mMatch env vis >=> mMatch env (bndrs, ty')
#endif
go (HsFunTy _ ty1 ty2) = mapFor tyHsFunTy >=> mMatch env ty1 >=> mMatch env ty2
go (HsListTy _ ty') = mapFor tyHsListTy >=> mMatch env ty'
go (HsParTy _ ty') = mapFor tyHsParTy >=> mMatch env ty'
go (HsQualTy _ (L _ cons) ty') = mapFor tyHsQualTy >=> mMatch env ty' >=> mMatch env cons
go (HsSumTy _ tys) = mapFor tyHsSumTy >=> mMatch env tys
go (HsTupleTy _ ts tys) = mapFor tyHsTupleTy >=> mMatch env ts >=> mMatch env tys
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 m1 m2 = ATM
{ atmAppInfix = unionOn atmAppInfix m1 m2
, atmAppPrefix = unionOn atmAppPrefix m1 m2
}
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)
data TupleSortMap a = TupleSortMap
{ tsUnboxed :: MaybeMap a
, tsBoxed :: MaybeMap a
, tsConstraint :: MaybeMap a
, tsBoxedOrConstraint :: MaybeMap a
}
deriving (Functor)
instance PatternMap TupleSortMap where
type Key TupleSortMap = HsTupleSort
mEmpty :: TupleSortMap a
mEmpty = TupleSortMap mEmpty mEmpty mEmpty mEmpty
mUnion :: TupleSortMap a -> TupleSortMap a -> TupleSortMap a
mUnion m1 m2 = TupleSortMap
{ tsUnboxed = unionOn tsUnboxed m1 m2
, tsBoxed = unionOn tsBoxed m1 m2
, tsConstraint = unionOn tsConstraint m1 m2
, tsBoxedOrConstraint = unionOn tsBoxedOrConstraint m1 m2
}
mAlter :: AlphaEnv -> Quantifiers -> Key TupleSortMap -> A a -> TupleSortMap a -> TupleSortMap a
mAlter env vs HsUnboxedTuple f m =
m { tsUnboxed = mAlter env vs () f (tsUnboxed m) }
mAlter env vs HsBoxedTuple f m =
m { tsBoxed = mAlter env vs () f (tsBoxed m) }
mAlter env vs HsConstraintTuple f m =
m { tsConstraint = mAlter env vs () f (tsConstraint m) }
mAlter env vs HsBoxedOrConstraintTuple f m =
m { tsBoxedOrConstraint = mAlter env vs () f (tsBoxedOrConstraint m) }
mMatch :: MatchEnv -> Key TupleSortMap -> (Substitution, TupleSortMap a) -> [(Substitution, a)]
mMatch env HsUnboxedTuple = mapFor tsUnboxed >=> mMatch env ()
mMatch env HsBoxedTuple = mapFor tsBoxed >=> mMatch env ()
mMatch env HsConstraintTuple = mapFor tsConstraint >=> mMatch env ()
mMatch env HsBoxedOrConstraintTuple = mapFor tsBoxedOrConstraint >=> mMatch env ()
data ForAllTyMap a = ForAllTyMap
{ fatNil :: TyMap a
, fatUser :: ForAllTyMap a
, fatKinded :: TyMap (ForAllTyMap a)
}
deriving (Functor)
instance PatternMap ForAllTyMap where
type Key ForAllTyMap = ([LHsTyVarBndr GhcPs], LHsType GhcPs)
mEmpty :: ForAllTyMap a
mEmpty = ForAllTyMap mEmpty mEmpty mEmpty
mUnion :: ForAllTyMap a -> ForAllTyMap a -> ForAllTyMap a
mUnion m1 m2 = ForAllTyMap
{ fatNil = unionOn fatNil m1 m2
, fatUser = unionOn fatUser m1 m2
, fatKinded = unionOn fatKinded m1 m2
}
mAlter :: AlphaEnv -> Quantifiers -> Key ForAllTyMap -> A a -> ForAllTyMap a -> ForAllTyMap a
mAlter env vs ([], ty) f m = m { fatNil = mAlter env vs ty f (fatNil m) }
#if __GLASGOW_HASKELL__ < 806
mAlter env vs (L _ (UserTyVar (L _ v)):rest, ty) f m =
#else
mAlter env vs (L _ (UserTyVar _ (L _ v)):rest, ty) f m =
#endif
let
env' = extendAlphaEnvInternal v env
vs' = vs `exceptQ` [v]
in m { fatUser = mAlter env' vs' (rest, ty) f (fatUser m) }
#if __GLASGOW_HASKELL__ < 806
mAlter env vs (L _ (KindedTyVar (L _ v) k):rest, ty) f m =
#else
mAlter _ _ (L _ (XTyVarBndr _):_,_) _ _ = missingSyntax "XTyVarBndr"
mAlter env vs (L _ (KindedTyVar _ (L _ v) k):rest, ty) f m =
#endif
let
env' = extendAlphaEnvInternal v env
vs' = vs `exceptQ` [v]
in m { fatKinded = mAlter env vs k (toA (mAlter env' vs' (rest, ty) f)) (fatKinded m) }
mMatch :: MatchEnv -> Key ForAllTyMap -> (Substitution, ForAllTyMap a) -> [(Substitution, a)]
mMatch env ([],ty) = mapFor fatNil >=> mMatch env ty
#if __GLASGOW_HASKELL__ < 806
mMatch env (L _ (UserTyVar (L _ v)):rest, ty) =
#else
mMatch env (L _ (UserTyVar _ (L _ v)):rest, ty) =
#endif
let env' = extendMatchEnv env [v]
in mapFor fatUser >=> mMatch env' (rest, ty)
#if __GLASGOW_HASKELL__ < 806
mMatch env (L _ (KindedTyVar (L _ v) k):rest, ty) =
#else
mMatch _ (L _ (XTyVarBndr _):_,_) = const []
mMatch env (L _ (KindedTyVar _ (L _ v) k):rest, ty) =
#endif
let env' = extendMatchEnv env [v]
in mapFor fatKinded >=> mMatch env k >=> mMatch env' (rest, ty)
#if __GLASGOW_HASKELL__ < 810
#else
data ForallVisMap a = ForallVisMap
{ favVis :: MaybeMap a
, favInvis :: MaybeMap a
}
deriving (Functor)
instance PatternMap ForallVisMap where
type Key ForallVisMap = ForallVisFlag
mEmpty :: ForallVisMap a
mEmpty = ForallVisMap mEmpty mEmpty
mUnion :: ForallVisMap a -> ForallVisMap a -> ForallVisMap a
mUnion m1 m2 = ForallVisMap
{ favVis = unionOn favVis m1 m2
, favInvis = unionOn favInvis m1 m2
}
mAlter :: AlphaEnv -> Quantifiers -> Key ForallVisMap -> A a -> ForallVisMap a -> ForallVisMap a
mAlter env vs ForallVis f m =
m { favVis = mAlter env vs () f (favVis m) }
mAlter env vs ForallInvis f m =
m { favInvis = mAlter env vs () f (favInvis m) }
mMatch :: MatchEnv -> Key ForallVisMap -> (Substitution, ForallVisMap a) -> [(Substitution, a)]
mMatch env ForallVis = mapFor favVis >=> mMatch env ()
mMatch env ForallInvis = mapFor favInvis >=> mMatch env ()
#endif