@@ -12,6 +12,7 @@ module Development.IDE.Spans.AtPoint (
1212 , documentHighlight
1313 , pointCommand
1414 , referencesAtPoint
15+ , computeTypeReferences
1516 , FOIReferences (.. )
1617 , defRowToSymbolInfo
1718 ) where
@@ -46,7 +47,7 @@ import Control.Monad.Trans.Class
4647import Control.Monad.IO.Class
4748import Data.Maybe
4849import qualified Data.Text as T
49- import qualified Data.Map as M
50+ import qualified Data.Map.Strict as M
5051import qualified Data.HashMap.Strict as HM
5152
5253import qualified Data.Array as A
@@ -63,6 +64,18 @@ type LookupModule m = FilePath -> ModuleName -> UnitId -> Bool -> MaybeT m Uri
6364-- | HieFileResult for files of interest, along with the position mappings
6465newtype FOIReferences = FOIReferences (HM. HashMap NormalizedFilePath (HieAstResult , PositionMapping ))
6566
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+
6679-- | Given a file and position, return the names at a point, the references for
6780-- those names in the FOIs, and a list of file paths we already searched through
6881foiReferencesAtPoint
@@ -73,14 +86,16 @@ foiReferencesAtPoint
7386foiReferencesAtPoint file pos (FOIReferences asts) =
7487 case HM. lookup file asts of
7588 Nothing -> ([] ,[] ,[] )
76- Just (HAR _ hf _ _,mapping) ->
89+ Just (HAR _ hf _ _ _ ,mapping) ->
7790 let posFile = fromMaybe pos $ fromCurrentPosition mapping pos
7891 names = concat $ pointCommand hf posFile (rights . M. keys . nodeIdentifiers . nodeInfo)
7992 adjustedLocs = HM. foldr go [] asts
80- go (HAR _ _ rf _, mapping) xs = refs ++ xs
93+ go (HAR _ _ rf tr _, mapping) xs = refs ++ typerefs ++ xs
8194 where
8295 refs = mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation . fst )
8396 $ concat $ mapMaybe (\ n -> M. lookup (Right n) rf) names
97+ typerefs = mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation)
98+ $ concat $ mapMaybe (`M.lookup` tr) names
8499 toCurrentLocation mapping (Location uri range) = Location uri <$> toCurrentRange mapping range
85100 in (names, adjustedLocs,map fromNormalizedFilePath $ HM. keys asts)
86101
@@ -101,14 +116,12 @@ referencesAtPoint hiedb nfp pos refs = do
101116 Just mod -> do
102117 -- Look for references (strictly in project files, not dependencies),
103118 -- 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
105120 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.
108121 typeRefs <- forM names $ \ name ->
109122 case nameModule_maybe name of
110123 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
112125 pure $ mapMaybe typeRowToLoc refs
113126 _ -> pure []
114127 pure $ nubOrd $ foiRefs ++ concat nonFOIRefs ++ concat typeRefs
@@ -183,7 +196,7 @@ atPoint
183196 -> DocAndKindMap
184197 -> Position
185198 -> 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
187200 where
188201 -- Hover info for values/data
189202 hoverInfo ast = (Just range, prettyNames ++ pTypes)
@@ -230,7 +243,7 @@ typeLocationsAtPoint
230243 -> Position
231244 -> HieAstResult
232245 -> m [Location ]
233- typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ hieKind) =
246+ typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ _ hieKind) =
234247 case hieKind of
235248 HieFromDisk hf ->
236249 let arr = hie_types hf
@@ -252,16 +265,21 @@ typeLocationsAtPoint hiedb lookupModule _ideOptions pos (HAR _ ast _ hieKind) =
252265 let ts = concat $ pointCommand ast pos getts
253266 getts x = nodeType ni ++ (mapMaybe identType $ M. elems $ nodeIdentifiers ni)
254267 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- _ -> []
263268 in fmap nubOrd $ concatMapM (fmap (maybe [] id ) . nameToLocation hiedb lookupModule) (getTypes ts)
264269
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+
265283locationsAtPoint
266284 :: forall m a
267285 . MonadIO m
0 commit comments