@@ -9,10 +9,14 @@ module Haskell.Ide.Engine.TypeMap where
99import qualified Data.IntervalMap.FingerTree as IM
1010
1111import qualified GHC
12- import GHC ( TypecheckedModule )
12+ import GHC ( TypecheckedModule , GhcMonad )
13+ import Bag
14+ import BasicTypes
15+ import Var
1316
1417import Data.Data as Data
1518import Control.Monad.IO.Class
19+ import Control.Applicative
1620import Data.Maybe
1721import qualified TcHsSyn
1822import qualified CoreUtils
@@ -27,44 +31,57 @@ import Haskell.Ide.Engine.ArtifactMap
2731genTypeMap :: GHC. GhcMonad m => TypecheckedModule -> m TypeMap
2832genTypeMap tm = do
2933 let typecheckedSource = GHC. tm_typechecked_source tm
30- hs_env <- GHC. getSession
31- liftIO $ types hs_env typecheckedSource
34+ everythingInTypecheckedSourceM typecheckedSource
3235
3336
3437everythingInTypecheckedSourceM
35- :: Data x => (forall a . Data a => a -> IO TypeMap ) -> x -> IO TypeMap
36- everythingInTypecheckedSourceM = everythingButTypeM @ GHC. Id
37-
38+ :: GhcMonad m => GHC. TypecheckedSource -> m TypeMap
39+ everythingInTypecheckedSourceM xs = bs
40+ where
41+ bs = foldBag (liftA2 IM. union) processBind (return IM. empty) xs
42+
43+ processBind :: GhcMonad m => GHC. LHsBindLR GHC. GhcTc GHC. GhcTc -> m TypeMap
44+ processBind x@ (GHC. L (GHC. RealSrcSpan spn) b) =
45+ case b of
46+ GHC. FunBind _ fid fmatches _ _ ->
47+ case GHC. mg_origin fmatches of
48+ Generated -> return IM. empty
49+ FromSource -> do
50+ im <- types fmatches
51+ return $ (IM. singleton (rspToInt spn) (varType (GHC. unLoc fid))) `IM.union` im
52+ GHC. AbsBinds _ _ _ _ _ bs _ -> everythingInTypecheckedSourceM bs
53+ _ -> types x
54+ processBind _ = return IM. empty
3855
3956-- | Obtain details map for types.
40- types :: GHC. HscEnv -> GHC. TypecheckedSource -> IO TypeMap
41- types hs_env = everythingInTypecheckedSourceM (ty `combineM` fun `combineM` funBind)
57+ types :: forall m a . ( GhcMonad m , Data a ) => a -> m TypeMap
58+ types = everythingButTypeM @ GHC. Id (ty `combineM` fun `combineM` funBind)
4259 where
43- ty :: forall a . Data a => a -> IO TypeMap
60+ ty :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
4461 ty term = case cast term of
4562 (Just lhsExprGhc@ (GHC. L (GHC. RealSrcSpan spn) _)) ->
46- getType hs_env lhsExprGhc >>= \ case
63+ getType lhsExprGhc >>= \ case
4764 Nothing -> return IM. empty
4865 Just (_, typ) -> return (IM. singleton (rspToInt spn) typ)
4966 _ -> return IM. empty
5067
51- fun :: forall a . Data a => a -> IO TypeMap
68+ fun :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
5269 fun term = case cast term of
5370 (Just (GHC. L (GHC. RealSrcSpan spn) hsPatType)) ->
5471 return (IM. singleton (rspToInt spn) (TcHsSyn. hsPatType hsPatType))
5572 _ -> return IM. empty
5673
57- funBind :: forall a . Data a => a -> IO TypeMap
74+ funBind :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
5875 funBind term = case cast term of
5976 (Just (GHC. L (GHC. RealSrcSpan spn) (FunBindType t))) ->
6077 return (IM. singleton (rspToInt spn) t)
6178 _ -> return IM. empty
6279
6380-- | Combine two queries into one using alternative combinator.
6481combineM
65- :: (forall a . Data a => a -> IO TypeMap )
66- -> (forall a . Data a => a -> IO TypeMap )
67- -> (forall a . Data a => a -> IO TypeMap )
82+ :: (forall a . ( Monad m , Data a ) => a -> m TypeMap )
83+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
84+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
6885combineM f g x = do
6986 a <- f x
7087 b <- g x
@@ -73,10 +90,10 @@ combineM f g x = do
7390-- | Variation of "everything" that does not recurse into children of type t
7491-- requires AllowAmbiguousTypes
7592everythingButTypeM
76- :: forall t
93+ :: forall t m
7794 . (Typeable t )
78- => (forall a . Data a => a -> IO TypeMap )
79- -> (forall a . Data a => a -> IO TypeMap )
95+ => (forall a . ( Monad m , Data a ) => a -> m TypeMap )
96+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
8097everythingButTypeM f = everythingButM $ (,) <$> f <*> isType @ t
8198
8299-- | Returns true if a == t.
@@ -87,8 +104,8 @@ isType _ = isJust $ eqT @a @b
87104-- | Variation of "everything" with an added stop condition
88105-- Just like 'everything', this is stolen from SYB package.
89106everythingButM
90- :: (forall a . Data a => a -> (IO TypeMap , Bool ))
91- -> (forall a . Data a => a -> IO TypeMap )
107+ :: forall m . (forall a . ( Monad m , Data a ) => a -> (m TypeMap , Bool ))
108+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
92109everythingButM f x = do
93110 let (v, stop) = f x
94111 if stop
@@ -111,8 +128,8 @@ everythingButM f x = do
111128--
112129-- See #16233<https://gitlab.haskell.org/ghc/ghc/issues/16233>
113130getType
114- :: GHC. HscEnv - > GHC. LHsExpr GhcTc -> IO (Maybe (GHC. SrcSpan , Type. Type ))
115- getType hs_env e@ (GHC. L spn e') =
131+ :: GhcMonad m = > GHC. LHsExpr GhcTc -> m (Maybe (GHC. SrcSpan , Type. Type ))
132+ getType e@ (GHC. L spn e') =
116133 -- Some expression forms have their type immediately available
117134 let
118135 tyOpt = case e' of
@@ -131,7 +148,8 @@ getType hs_env e@(GHC.L spn e') =
131148 Nothing
132149 | skipDesugaring e' -> pure Nothing
133150 | otherwise -> do
134- (_, mbe) <- Desugar. deSugarExpr hs_env e
151+ hsc_env <- GHC. getSession
152+ (_, mbe) <- liftIO $ Desugar. deSugarExpr hsc_env e
135153 let res = (spn, ) . CoreUtils. exprType <$> mbe
136154 pure res
137155 where
0 commit comments