@@ -12,6 +12,7 @@ module Development.IDE.Core.Rules(
12
12
-- * Types
13
13
IdeState , GetParsedModule (.. ), TransitiveDependencies (.. ),
14
14
GhcSessionIO (.. ), GetClientSettings (.. ),
15
+ useTransDepModuleGraph ,
15
16
-- * Functions
16
17
runAction ,
17
18
toIdeResult ,
@@ -472,7 +473,7 @@ rawDependencyInformation fs = do
472
473
reportImportCyclesRule :: Recorder (WithPriority Log ) -> Rules ()
473
474
reportImportCyclesRule recorder =
474
475
defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \ ReportImportCycles file -> fmap (\ errs -> if null errs then (Just " 1" ,([] , Just () )) else (Nothing , (errs, Nothing ))) $ do
475
- DependencyInformation { .. } <- useNoFile_ GetModuleGraph
476
+ DependencyInformation {depErrorNodes, depPathIdMap } <- useTransDepModuleGraph file
476
477
case pathToId depPathIdMap file of
477
478
-- The header of the file does not parse, so it can't be part of any import cycles.
478
479
Nothing -> pure []
@@ -608,7 +609,7 @@ typeCheckRule recorder = define (cmapWithPrio LogShake recorder) $ \TypeCheck fi
608
609
-- very expensive.
609
610
when (foi == NotFOI ) $
610
611
logWith recorder Logger. Warning $ LogTypecheckedFOI file
611
- typeCheckRuleDefinition hsc pm
612
+ typeCheckRuleDefinition hsc pm file
612
613
613
614
knownFilesRule :: Recorder (WithPriority Log ) -> Rules ()
614
615
knownFilesRule recorder = defineEarlyCutOffNoFile (cmapWithPrio LogShake recorder) $ \ GetKnownTargets -> do
@@ -633,17 +634,20 @@ dependencyInfoForFiles fs = do
633
634
(rawDepInfo, bm) <- rawDependencyInformation fs
634
635
let (all_fs, _all_ids) = unzip $ HM. toList $ pathToIdMap $ rawPathIdMap rawDepInfo
635
636
msrs <- uses GetModSummaryWithoutTimestamps all_fs
636
- let mss = map (fmap msrModSummary) msrs
637
+ let mss = zip _all_ids $ map (fmap msrModSummary) msrs
637
638
let deps = map (\ i -> IM. lookup (getFilePathId i) (rawImports rawDepInfo)) _all_ids
638
- nodeKeys = IM. fromList $ catMaybes $ zipWith (\ fi mms -> (getFilePathId fi,) . NodeKey_Module . msKey <$> mms) _all_ids mss
639
+ nodeKeys = IM. fromList $ catMaybes $ zipWith (\ fi (_, mms) -> (getFilePathId fi,) . NodeKey_Module . msKey <$> mms) _all_ids mss
639
640
mns = catMaybes $ zipWith go mss deps
640
- go (Just ms) (Just (Right (ModuleImports xs))) = Just $ ModuleNode this_dep_keys ms
641
+ go (pid, Just ms) (Just (Right (ModuleImports xs))) = Just $ (pid, ModuleNode this_dep_keys ms)
641
642
where this_dep_ids = mapMaybe snd xs
642
643
this_dep_keys = mapMaybe (\ fi -> IM. lookup (getFilePathId fi) nodeKeys) this_dep_ids
643
- go (Just ms) _ = Just $ ModuleNode [] ms
644
+ go (pid, Just ms) _ = Just $ (pid, ModuleNode [] ms)
644
645
go _ _ = Nothing
645
- mg = mkModuleGraph mns
646
- pure (fingerprintToBS $ Util. fingerprintFingerprints $ map (maybe fingerprint0 msrFingerprint) msrs, processDependencyInformation rawDepInfo bm mg)
646
+ mg = IntMap. fromList $ map (first getFilePathId) mns
647
+ let shallowFingers = IntMap. fromList $! foldr' (\ (i, m) acc -> case m of
648
+ Just x -> (getFilePathId i,msrFingerprint x): acc
649
+ Nothing -> acc) [] $ zip _all_ids msrs
650
+ pure (fingerprintToBS $ Util. fingerprintFingerprints $ map (maybe fingerprint0 msrFingerprint) msrs, processDependencyInformation rawDepInfo bm mg shallowFingers)
647
651
648
652
-- This is factored out so it can be directly called from the GetModIface
649
653
-- rule. Directly calling this rule means that on the initial load we can
@@ -652,14 +656,15 @@ dependencyInfoForFiles fs = do
652
656
typeCheckRuleDefinition
653
657
:: HscEnv
654
658
-> ParsedModule
659
+ -> NormalizedFilePath
655
660
-> Action (IdeResult TcModuleResult )
656
- typeCheckRuleDefinition hsc pm = do
661
+ typeCheckRuleDefinition hsc pm fp = do
657
662
IdeOptions { optDefer = defer } <- getIdeOptions
658
663
659
664
unlift <- askUnliftIO
660
665
let dets = TypecheckHelpers
661
666
{ getLinkables = unliftIO unlift . uses_ GetLinkable
662
- , getModuleGraph = unliftIO unlift $ useNoFile_ GetModuleGraph
667
+ , getModuleGraph = unliftIO unlift $ useTransDepModuleGraph fp
663
668
}
664
669
addUsageDependencies $ liftIO $
665
670
typecheckModule defer hsc dets pm
@@ -731,6 +736,11 @@ instance Default GhcSessionDepsConfig where
731
736
{ fullModuleGraph = True
732
737
}
733
738
739
+ useTransDepModuleGraph :: NormalizedFilePath -> Action DependencyInformation
740
+ useTransDepModuleGraph file = filterDependencyInformationReachable file <$> useWithSeparateFingerprintRule_ GetModuleGraphTransDepsFingerprints GetModuleGraph file
741
+ useImmediateDepsModuleGraph :: NormalizedFilePath -> Action (Maybe DependencyInformation )
742
+ useImmediateDepsModuleGraph file = useWithSeparateFingerprintRule GetModuleGraphTransDepsFingerprints GetModuleGraph file
743
+
734
744
-- | Note [GhcSessionDeps]
735
745
-- ~~~~~~~~~~~~~~~~~~~~~
736
746
-- For a file 'Foo', GhcSessionDeps "Foo.hs" results in an HscEnv which includes
@@ -756,9 +766,10 @@ ghcSessionDepsDefinition fullModSummary GhcSessionDepsConfig{..} env file = do
756
766
depSessions <- map hscEnv <$> uses_ (GhcSessionDeps_ fullModSummary) deps
757
767
ifaces <- uses_ GetModIface deps
758
768
let inLoadOrder = map (\ HiFileResult {.. } -> HomeModInfo hirModIface hirModDetails emptyHomeModInfoLinkable) ifaces
759
- mg <- do
769
+ de <- useTransDepModuleGraph file
770
+ mg <- mkModuleGraph <$> do
760
771
if fullModuleGraph
761
- then depModuleGraph <$> useNoFile_ GetModuleGraph
772
+ then return $ IntMap. elems $ depModuleGraph de
762
773
else do
763
774
let mgs = map hsc_mod_graph depSessions
764
775
-- On GHC 9.4+, the module graph contains not only ModSummary's but each `ModuleNode` in the graph
@@ -770,8 +781,7 @@ ghcSessionDepsDefinition fullModSummary GhcSessionDepsConfig{..} env file = do
770
781
let module_graph_nodes =
771
782
nubOrdOn mkNodeKey (ModuleNode final_deps ms : concatMap mgModSummaries' mgs)
772
783
liftIO $ evaluate $ liftRnf rwhnf module_graph_nodes
773
- return $ mkModuleGraph module_graph_nodes
774
- de <- useNoFile_ GetModuleGraph
784
+ return module_graph_nodes
775
785
session' <- liftIO $ mergeEnvs hsc mg de ms inLoadOrder depSessions
776
786
777
787
-- Here we avoid a call to to `newHscEnvEqWithImportPaths`, which creates a new
@@ -801,7 +811,7 @@ getModIfaceFromDiskRule recorder = defineEarlyCutoff (cmapWithPrio LogShake reco
801
811
, old_value = m_old
802
812
, get_file_version = use GetModificationTime_ {missingFileDiagnostics = False }
803
813
, get_linkable_hashes = \ fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs
804
- , get_module_graph = useNoFile_ GetModuleGraph
814
+ , get_module_graph = useTransDepModuleGraph f
805
815
, regenerate = regenerateHiFile session f ms
806
816
}
807
817
hsc_env' <- setFileCacheHook (hscEnv session)
@@ -977,7 +987,7 @@ regenerateHiFile sess f ms compNeeded = do
977
987
Just pm -> do
978
988
-- Invoke typechecking directly to update it without incurring a dependency
979
989
-- on the parsed module and the typecheck rules
980
- (diags', mtmr) <- typeCheckRuleDefinition hsc pm
990
+ (diags', mtmr) <- typeCheckRuleDefinition hsc pm f
981
991
case mtmr of
982
992
Nothing -> pure (diags', Nothing )
983
993
Just tmr -> do
@@ -1135,7 +1145,7 @@ needsCompilationRule file
1135
1145
| " boot" `isSuffixOf` fromNormalizedFilePath file =
1136
1146
pure (Just $ encodeLinkableType Nothing , Just Nothing )
1137
1147
needsCompilationRule file = do
1138
- graph <- useNoFile GetModuleGraph
1148
+ graph <- useImmediateDepsModuleGraph file
1139
1149
res <- case graph of
1140
1150
-- Treat as False if some reverse dependency header fails to parse
1141
1151
Nothing -> pure Nothing
@@ -1247,6 +1257,19 @@ mainRule recorder RulesConfig{..} = do
1247
1257
persistentDocMapRule
1248
1258
persistentImportMapRule
1249
1259
getLinkableRule recorder
1260
+ defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \ GetModuleGraphTransDepsFingerprints file -> do
1261
+ di <- useNoFile_ GetModuleGraph
1262
+ let finger = lookupFingerprint file di (depTransDepsFingerprints di)
1263
+ return (fingerprintToBS <$> finger, ([] , finger))
1264
+ defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \ GetModuleGraphTransReverseDepsFingerprints file -> do
1265
+ di <- useNoFile_ GetModuleGraph
1266
+ let finger = lookupFingerprint file di (depTransReverseDepsFingerprints di)
1267
+ return (fingerprintToBS <$> finger, ([] , finger))
1268
+ defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \ GetModuleGraphImmediateReverseDepsFingerprints file -> do
1269
+ di <- useNoFile_ GetModuleGraph
1270
+ let finger = lookupFingerprint file di (depImmediateReverseDepsFingerprints di)
1271
+ return (fingerprintToBS <$> finger, ([] , finger))
1272
+
1250
1273
1251
1274
-- | Get HieFile for haskell file on NormalizedFilePath
1252
1275
getHieFile :: NormalizedFilePath -> Action (Maybe HieFile )
0 commit comments