@@ -9,10 +9,14 @@ module Haskell.Ide.Engine.TypeMap where
9
9
import qualified Data.IntervalMap.FingerTree as IM
10
10
11
11
import qualified GHC
12
- import GHC ( TypecheckedModule )
12
+ import GHC ( TypecheckedModule , GhcMonad )
13
+ import Bag
14
+ import BasicTypes
15
+ import Var
13
16
14
17
import Data.Data as Data
15
18
import Control.Monad.IO.Class
19
+ import Control.Applicative
16
20
import Data.Maybe
17
21
import qualified TcHsSyn
18
22
import qualified CoreUtils
@@ -27,44 +31,57 @@ import Haskell.Ide.Engine.ArtifactMap
27
31
genTypeMap :: GHC. GhcMonad m => TypecheckedModule -> m TypeMap
28
32
genTypeMap tm = do
29
33
let typecheckedSource = GHC. tm_typechecked_source tm
30
- hs_env <- GHC. getSession
31
- liftIO $ types hs_env typecheckedSource
34
+ everythingInTypecheckedSourceM typecheckedSource
32
35
33
36
34
37
everythingInTypecheckedSourceM
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
38
55
39
56
-- | 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)
42
59
where
43
- ty :: forall a . Data a => a -> IO TypeMap
60
+ ty :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
44
61
ty term = case cast term of
45
62
(Just lhsExprGhc@ (GHC. L (GHC. RealSrcSpan spn) _)) ->
46
- getType hs_env lhsExprGhc >>= \ case
63
+ getType lhsExprGhc >>= \ case
47
64
Nothing -> return IM. empty
48
65
Just (_, typ) -> return (IM. singleton (rspToInt spn) typ)
49
66
_ -> return IM. empty
50
67
51
- fun :: forall a . Data a => a -> IO TypeMap
68
+ fun :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
52
69
fun term = case cast term of
53
70
(Just (GHC. L (GHC. RealSrcSpan spn) hsPatType)) ->
54
71
return (IM. singleton (rspToInt spn) (TcHsSyn. hsPatType hsPatType))
55
72
_ -> return IM. empty
56
73
57
- funBind :: forall a . Data a => a -> IO TypeMap
74
+ funBind :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
58
75
funBind term = case cast term of
59
76
(Just (GHC. L (GHC. RealSrcSpan spn) (FunBindType t))) ->
60
77
return (IM. singleton (rspToInt spn) t)
61
78
_ -> return IM. empty
62
79
63
80
-- | Combine two queries into one using alternative combinator.
64
81
combineM
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 )
68
85
combineM f g x = do
69
86
a <- f x
70
87
b <- g x
@@ -73,10 +90,10 @@ combineM f g x = do
73
90
-- | Variation of "everything" that does not recurse into children of type t
74
91
-- requires AllowAmbiguousTypes
75
92
everythingButTypeM
76
- :: forall t
93
+ :: forall t m
77
94
. (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 )
80
97
everythingButTypeM f = everythingButM $ (,) <$> f <*> isType @ t
81
98
82
99
-- | Returns true if a == t.
@@ -87,8 +104,8 @@ isType _ = isJust $ eqT @a @b
87
104
-- | Variation of "everything" with an added stop condition
88
105
-- Just like 'everything', this is stolen from SYB package.
89
106
everythingButM
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 )
92
109
everythingButM f x = do
93
110
let (v, stop) = f x
94
111
if stop
@@ -111,8 +128,8 @@ everythingButM f x = do
111
128
--
112
129
-- See #16233<https://gitlab.haskell.org/ghc/ghc/issues/16233>
113
130
getType
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') =
116
133
-- Some expression forms have their type immediately available
117
134
let
118
135
tyOpt = case e' of
@@ -131,7 +148,8 @@ getType hs_env e@(GHC.L spn e') =
131
148
Nothing
132
149
| skipDesugaring e' -> pure Nothing
133
150
| otherwise -> do
134
- (_, mbe) <- Desugar. deSugarExpr hs_env e
151
+ hsc_env <- GHC. getSession
152
+ (_, mbe) <- liftIO $ Desugar. deSugarExpr hsc_env e
135
153
let res = (spn, ) . CoreUtils. exprType <$> mbe
136
154
pure res
137
155
where
0 commit comments