Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit f1f14fa

Browse files
committed
Do not traverse into Generated bindings when creating TypeMap
1 parent 51c94a4 commit f1f14fa

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

hie-plugin-api/Haskell/Ide/Engine/TypeMap.hs

+41-23
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ module Haskell.Ide.Engine.TypeMap where
99
import qualified Data.IntervalMap.FingerTree as IM
1010

1111
import qualified GHC
12-
import GHC ( TypecheckedModule )
12+
import GHC ( TypecheckedModule, GhcMonad )
13+
import Bag
14+
import BasicTypes
15+
import Var
1316

1417
import Data.Data as Data
1518
import Control.Monad.IO.Class
19+
import Control.Applicative
1620
import Data.Maybe
1721
import qualified TcHsSyn
1822
import qualified CoreUtils
@@ -27,44 +31,57 @@ import Haskell.Ide.Engine.ArtifactMap
2731
genTypeMap :: GHC.GhcMonad m => TypecheckedModule -> m TypeMap
2832
genTypeMap 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

3437
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
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.
6481
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)
6885
combineM 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
7592
everythingButTypeM
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)
8097
everythingButTypeM 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.
89106
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)
92109
everythingButM 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>
113130
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') =
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

Comments
 (0)