@@ -12,6 +12,7 @@ module Development.IDE.Spans.AtPoint (
12
12
, documentHighlight
13
13
, pointCommand
14
14
, referencesAtPoint
15
+ , computeTypeReferences
15
16
, FOIReferences (.. )
16
17
, defRowToSymbolInfo
17
18
) where
@@ -46,7 +47,7 @@ import Control.Monad.Trans.Class
46
47
import Control.Monad.IO.Class
47
48
import Data.Maybe
48
49
import qualified Data.Text as T
49
- import qualified Data.Map as M
50
+ import qualified Data.Map.Strict as M
50
51
import qualified Data.HashMap.Strict as HM
51
52
52
53
import qualified Data.Array as A
@@ -63,6 +64,18 @@ type LookupModule m = FilePath -> ModuleName -> UnitId -> Bool -> MaybeT m Uri
63
64
-- | HieFileResult for files of interest, along with the position mappings
64
65
newtype FOIReferences = FOIReferences (HM. HashMap NormalizedFilePath (HieAstResult , PositionMapping ))
65
66
67
+ computeTypeReferences :: Foldable f => f (HieAST Type ) -> M. Map Name [Span ]
68
+ computeTypeReferences = foldr (\ ast m -> M. unionWith (++) (go ast) m) M. empty
69
+ where
70
+ go ast = M. unionsWith (++) (this : map go (nodeChildren ast))
71
+ where
72
+ this = M. fromListWith (++)
73
+ $ map (, [nodeSpan ast])
74
+ $ concatMap namesInType
75
+ $ mapMaybe (\ x -> guard (any (not . isOccurrence) (identInfo x)) *> identType x)
76
+ $ M. elems
77
+ $ nodeIdentifiers $ nodeInfo ast
78
+
66
79
-- | Given a file and position, return the names at a point, the references for
67
80
-- those names in the FOIs, and a list of file paths we already searched through
68
81
foiReferencesAtPoint
@@ -73,14 +86,16 @@ foiReferencesAtPoint
73
86
foiReferencesAtPoint file pos (FOIReferences asts) =
74
87
case HM. lookup file asts of
75
88
Nothing -> ([] ,[] ,[] )
76
- Just (HAR _ hf _ _,mapping) ->
89
+ Just (HAR _ hf _ _ _ ,mapping) ->
77
90
let posFile = fromMaybe pos $ fromCurrentPosition mapping pos
78
91
names = concat $ pointCommand hf posFile (rights . M. keys . nodeIdentifiers . nodeInfo)
79
92
adjustedLocs = HM. foldr go [] asts
80
- go (HAR _ _ rf _, mapping) xs = refs ++ xs
93
+ go (HAR _ _ rf tr _, mapping) xs = refs ++ typerefs ++ xs
81
94
where
82
95
refs = mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation . fst )
83
96
$ concat $ mapMaybe (\ n -> M. lookup (Right n) rf) names
97
+ typerefs = mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation)
98
+ $ concat $ mapMaybe (`M.lookup` tr) names
84
99
toCurrentLocation mapping (Location uri range) = Location uri <$> toCurrentRange mapping range
85
100
in (names, adjustedLocs,map fromNormalizedFilePath $ HM. keys asts)
86
101
@@ -101,14 +116,12 @@ referencesAtPoint hiedb nfp pos refs = do
101
116
Just mod -> do
102
117
-- Look for references (strictly in project files, not dependencies),
103
118
-- excluding the files in the FOIs (since those are in foiRefs)
104
- rows <- liftIO $ search hiedb True (nameOccName name) (Just $ moduleName mod ) (Just $ moduleUnitId mod ) exclude
119
+ rows <- liftIO $ findReferences hiedb True (nameOccName name) (Just $ moduleName mod ) (Just $ moduleUnitId mod ) exclude
105
120
pure $ mapMaybe rowToLoc rows
106
- -- Type references are expensive to compute, so we only look for them in the database, not the FOIs
107
- -- Some inaccuracy for FOIs can be expected.
108
121
typeRefs <- forM names $ \ name ->
109
122
case nameModule_maybe name of
110
123
Just mod | isTcClsNameSpace (occNameSpace $ nameOccName name) -> do
111
- refs <- liftIO $ findTypeRefs hiedb (nameOccName name) (moduleName mod ) (moduleUnitId mod )
124
+ refs <- liftIO $ findTypeRefs hiedb True (nameOccName name) (Just $ moduleName mod ) (Just $ moduleUnitId mod ) exclude
112
125
pure $ mapMaybe typeRowToLoc refs
113
126
_ -> pure []
114
127
pure $ nubOrd $ foiRefs ++ concat nonFOIRefs ++ concat typeRefs
@@ -183,7 +196,7 @@ atPoint
183
196
-> DocAndKindMap
184
197
-> Position
185
198
-> Maybe (Maybe Range , [T. Text ])
186
- atPoint IdeOptions {} (HAR _ hf _ kind) (DKMap dm km) pos = listToMaybe $ pointCommand hf pos hoverInfo
199
+ atPoint IdeOptions {} (HAR _ hf _ _ kind) (DKMap dm km) pos = listToMaybe $ pointCommand hf pos hoverInfo
187
200
where
188
201
-- Hover info for values/data
189
202
hoverInfo ast = (Just range, prettyNames ++ pTypes)
@@ -230,7 +243,7 @@ typeLocationsAtPoint
230
243
-> Position
231
244
-> HieAstResult
232
245
-> m [Location ]
233
- typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ hieKind) =
246
+ typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ _ hieKind) =
234
247
case hieKind of
235
248
HieFromDisk hf ->
236
249
let arr = hie_types hf
@@ -252,16 +265,21 @@ typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ hieKind) =
252
265
let ts = concat $ pointCommand ast pos getts
253
266
getts x = nodeType ni ++ (mapMaybe identType $ M. elems $ nodeIdentifiers ni)
254
267
where ni = nodeInfo x
255
- getTypes ts = flip concatMap ts $ \ case
256
- TyVarTy n -> [Var. varName n]
257
- AppTy a b -> getTypes [a,b]
258
- TyConApp tc ts -> tyConName tc : getTypes ts
259
- ForAllTy _ t -> getTypes [t]
260
- FunTy a b -> getTypes [a,b]
261
- CastTy t _ -> getTypes [t]
262
- _ -> []
263
268
in fmap nubOrd $ concatMapM (fmap (maybe [] id ) . nameToLocation hiedb lookupModule) (getTypes ts)
264
269
270
+ namesInType :: Type -> [Name ]
271
+ namesInType (TyVarTy n) = [Var. varName n]
272
+ namesInType (AppTy a b) = getTypes [a,b]
273
+ namesInType (TyConApp tc ts) = tyConName tc : getTypes ts
274
+ namesInType (ForAllTy b t) = Var. varName (binderVar b) : namesInType t
275
+ namesInType (FunTy a b) = getTypes [a,b]
276
+ namesInType (CastTy t _) = namesInType t
277
+ namesInType (LitTy _) = []
278
+ namesInType _ = []
279
+
280
+ getTypes :: [Type ] -> [Name ]
281
+ getTypes ts = concatMap namesInType ts
282
+
265
283
locationsAtPoint
266
284
:: forall m a
267
285
. MonadIO m
0 commit comments