@@ -9,16 +9,19 @@ 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
13
15
14
16
import Data.Data as Data
15
17
import Control.Monad.IO.Class
18
+ import Control.Applicative
16
19
import Data.Maybe
17
20
import qualified TcHsSyn
18
21
import qualified CoreUtils
19
22
import qualified Type
20
23
import qualified Desugar
21
- import Haskell.Ide.Engine.Compat
24
+ import qualified Haskell.Ide.Engine.Compat as Compat
22
25
23
26
import Haskell.Ide.Engine.ArtifactMap
24
27
@@ -27,44 +30,57 @@ import Haskell.Ide.Engine.ArtifactMap
27
30
genTypeMap :: GHC. GhcMonad m => TypecheckedModule -> m TypeMap
28
31
genTypeMap tm = do
29
32
let typecheckedSource = GHC. tm_typechecked_source tm
30
- hs_env <- GHC. getSession
31
- liftIO $ types hs_env typecheckedSource
33
+ everythingInTypecheckedSourceM typecheckedSource
32
34
33
35
34
36
everythingInTypecheckedSourceM
35
- :: Data x => (forall a . Data a => a -> IO TypeMap ) -> x -> IO TypeMap
36
- everythingInTypecheckedSourceM = everythingButTypeM @ GHC. Id
37
-
37
+ :: GhcMonad m => GHC. TypecheckedSource -> m TypeMap
38
+ everythingInTypecheckedSourceM xs = bs
39
+ where
40
+ bs = foldBag (liftA2 IM. union) processBind (return IM. empty) xs
41
+
42
+ processBind :: GhcMonad m => GHC. LHsBindLR Compat. GhcTc Compat. GhcTc -> m TypeMap
43
+ processBind x@ (GHC. L (GHC. RealSrcSpan spn) b) =
44
+ case b of
45
+ Compat. FunBindGen t fmatches ->
46
+ case GHC. mg_origin fmatches of
47
+ Generated -> return IM. empty
48
+ FromSource -> do
49
+ im <- types fmatches
50
+ return $ IM. singleton (rspToInt spn) t `IM.union` im
51
+ Compat. AbsBinds bs -> everythingInTypecheckedSourceM bs
52
+ _ -> types x
53
+ processBind _ = return IM. empty
38
54
39
55
-- | Obtain details map for types.
40
- types :: GHC. HscEnv -> GHC. TypecheckedSource -> IO TypeMap
41
- types hs_env = everythingInTypecheckedSourceM (ty `combineM` fun `combineM` funBind)
56
+ types :: forall m a . ( GhcMonad m , Data a ) => a -> m TypeMap
57
+ types = everythingButTypeM @ GHC. Id (ty `combineM` fun `combineM` funBind)
42
58
where
43
- ty :: forall a . Data a => a -> IO TypeMap
59
+ ty :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
44
60
ty term = case cast term of
45
61
(Just lhsExprGhc@ (GHC. L (GHC. RealSrcSpan spn) _)) ->
46
- getType hs_env lhsExprGhc >>= \ case
62
+ getType lhsExprGhc >>= \ case
47
63
Nothing -> return IM. empty
48
64
Just (_, typ) -> return (IM. singleton (rspToInt spn) typ)
49
65
_ -> return IM. empty
50
66
51
- fun :: forall a . Data a => a -> IO TypeMap
67
+ fun :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
52
68
fun term = case cast term of
53
69
(Just (GHC. L (GHC. RealSrcSpan spn) hsPatType)) ->
54
70
return (IM. singleton (rspToInt spn) (TcHsSyn. hsPatType hsPatType))
55
71
_ -> return IM. empty
56
72
57
- funBind :: forall a . Data a => a -> IO TypeMap
73
+ funBind :: forall a' . ( GhcMonad m , Data a' ) => a' -> m TypeMap
58
74
funBind term = case cast term of
59
- (Just (GHC. L (GHC. RealSrcSpan spn) (FunBindType t))) ->
75
+ (Just (GHC. L (GHC. RealSrcSpan spn) (Compat. FunBindType t))) ->
60
76
return (IM. singleton (rspToInt spn) t)
61
77
_ -> return IM. empty
62
78
63
79
-- | Combine two queries into one using alternative combinator.
64
80
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 )
81
+ :: (forall a . ( Monad m , Data a ) => a -> m TypeMap )
82
+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
83
+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
68
84
combineM f g x = do
69
85
a <- f x
70
86
b <- g x
@@ -73,10 +89,10 @@ combineM f g x = do
73
89
-- | Variation of "everything" that does not recurse into children of type t
74
90
-- requires AllowAmbiguousTypes
75
91
everythingButTypeM
76
- :: forall t
92
+ :: forall t m
77
93
. (Typeable t )
78
- => (forall a . Data a => a -> IO TypeMap )
79
- -> (forall a . Data a => a -> IO TypeMap )
94
+ => (forall a . ( Monad m , Data a ) => a -> m TypeMap )
95
+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
80
96
everythingButTypeM f = everythingButM $ (,) <$> f <*> isType @ t
81
97
82
98
-- | Returns true if a == t.
@@ -87,8 +103,8 @@ isType _ = isJust $ eqT @a @b
87
103
-- | Variation of "everything" with an added stop condition
88
104
-- Just like 'everything', this is stolen from SYB package.
89
105
everythingButM
90
- :: (forall a . Data a => a -> (IO TypeMap , Bool ))
91
- -> (forall a . Data a => a -> IO TypeMap )
106
+ :: forall m . (forall a . ( Monad m , Data a ) => a -> (m TypeMap , Bool ))
107
+ -> (forall a . ( Monad m , Data a ) => a -> m TypeMap )
92
108
everythingButM f x = do
93
109
let (v, stop) = f x
94
110
if stop
@@ -111,27 +127,28 @@ everythingButM f x = do
111
127
--
112
128
-- See #16233<https://gitlab.haskell.org/ghc/ghc/issues/16233>
113
129
getType
114
- :: GHC. HscEnv - > GHC. LHsExpr GhcTc -> IO (Maybe (GHC. SrcSpan , Type. Type ))
115
- getType hs_env e@ (GHC. L spn e') =
130
+ :: GhcMonad m = > GHC. LHsExpr Compat. GhcTc -> m (Maybe (GHC. SrcSpan , Type. Type ))
131
+ getType e@ (GHC. L spn e') =
116
132
-- Some expression forms have their type immediately available
117
133
let
118
134
tyOpt = case e' of
119
- HsOverLitType t -> Just t
120
- HsLitType t -> Just t
121
- HsLamType t -> Just t
122
- HsLamCaseType t -> Just t
123
- HsCaseType t -> Just t
124
- ExplicitListType t -> Just t
125
- ExplicitSumType t -> Just t
126
- HsMultiIfType t -> Just t
135
+ Compat. HsOverLitType t -> Just t
136
+ Compat. HsLitType t -> Just t
137
+ Compat. HsLamType t -> Just t
138
+ Compat. HsLamCaseType t -> Just t
139
+ Compat. HsCaseType t -> Just t
140
+ Compat. ExplicitListType t -> Just t
141
+ Compat. ExplicitSumType t -> Just t
142
+ Compat. HsMultiIfType t -> Just t
127
143
128
144
_ -> Nothing
129
145
in case tyOpt of
130
146
Just t -> return $ Just (spn ,t)
131
147
Nothing
132
148
| skipDesugaring e' -> pure Nothing
133
149
| otherwise -> do
134
- (_, mbe) <- Desugar. deSugarExpr hs_env e
150
+ hsc_env <- GHC. getSession
151
+ (_, mbe) <- liftIO $ Desugar. deSugarExpr hsc_env e
135
152
let res = (spn, ) . CoreUtils. exprType <$> mbe
136
153
pure res
137
154
where
0 commit comments