Skip to content

Commit c981151

Browse files
committed
local type references
1 parent 7ca3089 commit c981151

File tree

5 files changed

+50
-36
lines changed

5 files changed

+50
-36
lines changed

ghcide/src/Development/IDE/Core/Compile.hs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ import Control.Concurrent.Extra
113113
import Data.Functor
114114
import Data.Unique
115115
import GHC.Fingerprint
116-
import Debug.Trace
117116

118117
-- | Given a string buffer, return the string (after preprocessing) and the 'ParsedModule'.
119118
parseModule
@@ -507,10 +506,10 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
507506
Nothing -> do
508507
u <- LSP.ProgressTextToken . T.pack . show . hashUnique <$> newUnique
509508
lspId <- getLspId se
510-
eventer se $ traceShowId $ LSP.ReqWorkDoneProgressCreate $
509+
eventer se $ LSP.ReqWorkDoneProgressCreate $
511510
LSP.fmServerWorkDoneProgressCreateRequest lspId $
512511
LSP.WorkDoneProgressCreateParams { _token = u }
513-
eventer se $ traceShowId $ LSP.NotWorkDoneProgressBegin $
512+
eventer se $ LSP.NotWorkDoneProgressBegin $
514513
LSP.fmServerWorkDoneProgressBeginNotification
515514
LSP.ProgressParams
516515
{ _token = u
@@ -527,7 +526,7 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
527526
remaining <- HashMap.size <$> readTVar indexPending
528527
pure (done, remaining)
529528
let progress = " (" <> T.pack (show done) <> "/" <> T.pack (show $ done + remaining) <> ")..."
530-
eventer se $ traceShowId $ LSP.NotWorkDoneProgressReport $
529+
eventer se $ LSP.NotWorkDoneProgressReport $
531530
LSP.fmServerWorkDoneProgressReportNotification
532531
LSP.ProgressParams
533532
{ _token = tok
@@ -554,7 +553,7 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
554553
Nothing -> pure ()
555554
Just done ->
556555
modifyVar_ indexProgressToken $ \_ -> do
557-
eventer se $ traceShowId $ LSP.NotWorkDoneProgressEnd $
556+
eventer se $ LSP.NotWorkDoneProgressEnd $
558557
LSP.fmServerWorkDoneProgressEndNotification
559558
LSP.ProgressParams
560559
{ _token = tok

ghcide/src/Development/IDE/Core/RuleTypes.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ data HieAstResult
174174
-- ^ Lazy because its value only depends on the hieAst, which is bundled in this type
175175
-- Lazyness can't cause leaks here because the lifetime of `refMap` will be the same
176176
-- as that of `hieAst`
177+
, typeRefs :: M.Map Name [RealSrcSpan]
178+
-- ^ type references in this file
177179
, hieKind :: !(HieKind a)
178180
-- ^ Is this hie file loaded from the disk, or freshly computed?
179181
}
@@ -187,7 +189,7 @@ instance NFData (HieKind a) where
187189
rnf HieFresh = ()
188190

189191
instance NFData HieAstResult where
190-
rnf (HAR m hf _rm kind) = rnf m `seq` rwhnf hf `seq` rnf kind
192+
rnf (HAR m hf _rm _tr kind) = rnf m `seq` rwhnf hf `seq` rnf kind
191193

192194
instance Show HieAstResult where
193195
show = show . hieModule

ghcide/src/Development/IDE/Core/Rules.hs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,6 @@ import Module
102102
import qualified Data.Rope.UTF16 as Rope
103103
import GHC.IO.Encoding
104104
import Data.ByteString.Encoding as T
105-
import Debug.Trace
106-
import Outputable (showSDocUnsafe)
107-
import HieDebug
108105

109106
import qualified HieDb
110107

@@ -152,12 +149,10 @@ getAtPoint file pos = runMaybeT $ do
152149
ide <- ask
153150
opts <- liftIO $ getIdeOptionsIO ide
154151

155-
(hf@HAR{hieAst = asts}, mapping) <- useE GetHieAst file
152+
(hf, mapping) <- useE GetHieAst file
156153
dkMap <- lift $ maybe (DKMap mempty mempty) fst <$> (runMaybeT $ useE GetDocMap file)
157154

158155
!pos' <- MaybeT (return $ fromCurrentPosition mapping pos)
159-
traceShowM ("Got pos",pos',"in original file")
160-
-- traceM (showSDocUnsafe $ ppHies asts)
161156
MaybeT $ pure $ fmap (first (toCurrentRange mapping =<<)) $ AtPoint.atPoint opts hf dkMap pos'
162157

163158
toCurrentLocations :: PositionMapping -> [Location] -> [Location]
@@ -170,7 +165,7 @@ getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
170165
getDefinition file pos = runMaybeT $ do
171166
ide <- ask
172167
opts <- liftIO $ getIdeOptionsIO ide
173-
(HAR _ hf _ _, mapping) <- useE GetHieAst file
168+
(HAR _ hf _ _ _, mapping) <- useE GetHieAst file
174169
(ImportMap imports, _) <- useE GetImportMap file
175170
!pos' <- MaybeT (return $ fromCurrentPosition mapping pos)
176171
hiedb <- lift $ asks hiedb
@@ -189,7 +184,7 @@ getTypeDefinition file pos = runMaybeT $ do
189184

190185
highlightAtPoint :: NormalizedFilePath -> Position -> IdeAction (Maybe [DocumentHighlight])
191186
highlightAtPoint file pos = runMaybeT $ do
192-
(HAR _ hf rf _,mapping) <- useE GetHieAst file
187+
(HAR _ hf rf _ _,mapping) <- useE GetHieAst file
193188
!pos' <- MaybeT (return $ fromCurrentPosition mapping pos)
194189
let toCurrentHighlight (DocumentHighlight range t) = flip DocumentHighlight t <$> toCurrentRange mapping range
195190
mapMaybe toCurrentHighlight <$>AtPoint.documentHighlight hf rf pos'
@@ -531,7 +526,7 @@ persistentHieFileRule = addPersistentRule GetHieAst $ \file -> runMaybeT $ do
531526
encoding <- liftIO $ getLocaleEncoding
532527
let refmap = generateReferencesMap . getAsts . hie_asts $ res
533528
del = deltaFromDiff (T.decode encoding $ hie_hs_src res) currentSource
534-
pure $ (HAR (hie_module res) (hie_asts res) refmap (HieFromDisk res),del,ver)
529+
pure $ (HAR (hie_module res) (hie_asts res) refmap mempty (HieFromDisk res),del,ver)
535530

536531
getHieAstRuleDefinition :: NormalizedFilePath -> HscEnv -> TcModuleResult -> Action (IdeResult HieAstResult)
537532
getHieAstRuleDefinition f hsc tmr = do
@@ -549,7 +544,8 @@ getHieAstRuleDefinition f hsc tmr = do
549544
_ -> pure []
550545

551546
let refmap = generateReferencesMap . getAsts <$> masts
552-
pure (diags <> diagsWrite, HAR (ms_mod $ tmrModSummary tmr) <$> masts <*> refmap <*> pure HieFresh)
547+
typemap = AtPoint.computeTypeReferences . getAsts <$> masts
548+
pure (diags <> diagsWrite, HAR (ms_mod $ tmrModSummary tmr) <$> masts <*> refmap <*> typemap <*> pure HieFresh)
553549

554550
getImportMapRule :: Rules ()
555551
getImportMapRule = define $ \GetImportMap f -> do
@@ -786,6 +782,7 @@ getModIfaceFromDiskRule = defineEarlyCutoff $ \GetModIfaceFromDisk f -> do
786782
Nothing -> regenerateHieFile
787783
-- can just re-index the file we read from disk
788784
Just hf -> liftIO $ do
785+
L.logInfo (logger se) $ "Re-indexing hie file for" <> T.pack (show (f,hash,fmap (HieDb.modInfoHash . HieDb.hieModInfo) mrow))
789786
indexHieFile se ms f hash hf
790787
return (fp, (diags <> diags_session, Just x))
791788

ghcide/src/Development/IDE/Core/Shake.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ import OpenTelemetry.Eventlog
135135
import GHC.Fingerprint
136136

137137
import HieDb.Types
138-
import Debug.Trace
139138

140139
-- | We need to serialize writes to the database, so we send any function that
141140
-- needs to write to the database over the channel, where it will be picked up by
@@ -1183,8 +1182,7 @@ filterVersionMap =
11831182
HMap.intersectionWith $ \versionsToKeep versionMap -> Map.restrictKeys versionMap versionsToKeep
11841183

11851184
updatePositionMapping :: IdeState -> VersionedTextDocumentIdentifier -> List TextDocumentContentChangeEvent -> IO ()
1186-
updatePositionMapping IdeState{shakeExtras = ShakeExtras{positionMapping}} v@VersionedTextDocumentIdentifier{..} (List changes) = do
1187-
traceShowM ("UpdatePositionMapping",v,changes)
1185+
updatePositionMapping IdeState{shakeExtras = ShakeExtras{positionMapping}} VersionedTextDocumentIdentifier{..} (List changes) = do
11881186
modifyVar_ positionMapping $ \allMappings -> do
11891187
let uri = toNormalizedUri _uri
11901188
let mappingForUri = HMap.lookupDefault Map.empty uri allMappings

ghcide/src/Development/IDE/Spans/AtPoint.hs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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
4647
import Control.Monad.IO.Class
4748
import Data.Maybe
4849
import qualified Data.Text as T
49-
import qualified Data.Map as M
50+
import qualified Data.Map.Strict as M
5051
import qualified Data.HashMap.Strict as HM
5152

5253
import 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
6465
newtype 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
6881
foiReferencesAtPoint
@@ -73,14 +86,16 @@ foiReferencesAtPoint
7386
foiReferencesAtPoint 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+
265283
locationsAtPoint
266284
:: forall m a
267285
. MonadIO m

0 commit comments

Comments
 (0)