@@ -12,6 +12,7 @@ module Development.IDE.Core.Rules(
1212 -- * Types
1313 IdeState , GetParsedModule (.. ), TransitiveDependencies (.. ),
1414 GhcSessionIO (.. ), GetClientSettings (.. ),
15+ useTransDepModuleGraph ,
1516 -- * Functions
1617 runAction ,
1718 toIdeResult ,
@@ -472,7 +473,7 @@ rawDependencyInformation fs = do
472473reportImportCyclesRule :: Recorder (WithPriority Log ) -> Rules ()
473474reportImportCyclesRule recorder =
474475 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
476477 case pathToId depPathIdMap file of
477478 -- The header of the file does not parse, so it can't be part of any import cycles.
478479 Nothing -> pure []
@@ -608,7 +609,7 @@ typeCheckRule recorder = define (cmapWithPrio LogShake recorder) $ \TypeCheck fi
608609 -- very expensive.
609610 when (foi == NotFOI ) $
610611 logWith recorder Logger. Warning $ LogTypecheckedFOI file
611- typeCheckRuleDefinition hsc pm
612+ typeCheckRuleDefinition hsc pm file
612613
613614knownFilesRule :: Recorder (WithPriority Log ) -> Rules ()
614615knownFilesRule recorder = defineEarlyCutOffNoFile (cmapWithPrio LogShake recorder) $ \ GetKnownTargets -> do
@@ -633,17 +634,20 @@ dependencyInfoForFiles fs = do
633634 (rawDepInfo, bm) <- rawDependencyInformation fs
634635 let (all_fs, _all_ids) = unzip $ HM. toList $ pathToIdMap $ rawPathIdMap rawDepInfo
635636 msrs <- uses GetModSummaryWithoutTimestamps all_fs
636- let mss = map (fmap msrModSummary) msrs
637+ let mss = zip _all_ids $ map (fmap msrModSummary) msrs
637638 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
639640 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)
641642 where this_dep_ids = mapMaybe snd xs
642643 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)
644645 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)
647651
648652-- This is factored out so it can be directly called from the GetModIface
649653-- rule. Directly calling this rule means that on the initial load we can
@@ -652,14 +656,15 @@ dependencyInfoForFiles fs = do
652656typeCheckRuleDefinition
653657 :: HscEnv
654658 -> ParsedModule
659+ -> NormalizedFilePath
655660 -> Action (IdeResult TcModuleResult )
656- typeCheckRuleDefinition hsc pm = do
661+ typeCheckRuleDefinition hsc pm fp = do
657662 IdeOptions { optDefer = defer } <- getIdeOptions
658663
659664 unlift <- askUnliftIO
660665 let dets = TypecheckHelpers
661666 { getLinkables = unliftIO unlift . uses_ GetLinkable
662- , getModuleGraph = unliftIO unlift $ useNoFile_ GetModuleGraph
667+ , getModuleGraph = unliftIO unlift $ useTransDepModuleGraph fp
663668 }
664669 addUsageDependencies $ liftIO $
665670 typecheckModule defer hsc dets pm
@@ -731,6 +736,11 @@ instance Default GhcSessionDepsConfig where
731736 { fullModuleGraph = True
732737 }
733738
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+
734744-- | Note [GhcSessionDeps]
735745-- ~~~~~~~~~~~~~~~~~~~~~
736746-- For a file 'Foo', GhcSessionDeps "Foo.hs" results in an HscEnv which includes
@@ -756,9 +766,10 @@ ghcSessionDepsDefinition fullModSummary GhcSessionDepsConfig{..} env file = do
756766 depSessions <- map hscEnv <$> uses_ (GhcSessionDeps_ fullModSummary) deps
757767 ifaces <- uses_ GetModIface deps
758768 let inLoadOrder = map (\ HiFileResult {.. } -> HomeModInfo hirModIface hirModDetails emptyHomeModInfoLinkable) ifaces
759- mg <- do
769+ de <- useTransDepModuleGraph file
770+ mg <- mkModuleGraph <$> do
760771 if fullModuleGraph
761- then depModuleGraph <$> useNoFile_ GetModuleGraph
772+ then return $ IntMap. elems $ depModuleGraph de
762773 else do
763774 let mgs = map hsc_mod_graph depSessions
764775 -- 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
770781 let module_graph_nodes =
771782 nubOrdOn mkNodeKey (ModuleNode final_deps ms : concatMap mgModSummaries' mgs)
772783 liftIO $ evaluate $ liftRnf rwhnf module_graph_nodes
773- return $ mkModuleGraph module_graph_nodes
774- de <- useNoFile_ GetModuleGraph
784+ return module_graph_nodes
775785 session' <- liftIO $ mergeEnvs hsc mg de ms inLoadOrder depSessions
776786
777787 -- Here we avoid a call to to `newHscEnvEqWithImportPaths`, which creates a new
@@ -801,7 +811,7 @@ getModIfaceFromDiskRule recorder = defineEarlyCutoff (cmapWithPrio LogShake reco
801811 , old_value = m_old
802812 , get_file_version = use GetModificationTime_ {missingFileDiagnostics = False }
803813 , get_linkable_hashes = \ fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs
804- , get_module_graph = useNoFile_ GetModuleGraph
814+ , get_module_graph = useTransDepModuleGraph f
805815 , regenerate = regenerateHiFile session f ms
806816 }
807817 hsc_env' <- setFileCacheHook (hscEnv session)
@@ -977,7 +987,7 @@ regenerateHiFile sess f ms compNeeded = do
977987 Just pm -> do
978988 -- Invoke typechecking directly to update it without incurring a dependency
979989 -- on the parsed module and the typecheck rules
980- (diags', mtmr) <- typeCheckRuleDefinition hsc pm
990+ (diags', mtmr) <- typeCheckRuleDefinition hsc pm f
981991 case mtmr of
982992 Nothing -> pure (diags', Nothing )
983993 Just tmr -> do
@@ -1135,7 +1145,7 @@ needsCompilationRule file
11351145 | " boot" `isSuffixOf` fromNormalizedFilePath file =
11361146 pure (Just $ encodeLinkableType Nothing , Just Nothing )
11371147needsCompilationRule file = do
1138- graph <- useNoFile GetModuleGraph
1148+ graph <- useImmediateDepsModuleGraph file
11391149 res <- case graph of
11401150 -- Treat as False if some reverse dependency header fails to parse
11411151 Nothing -> pure Nothing
@@ -1247,6 +1257,19 @@ mainRule recorder RulesConfig{..} = do
12471257 persistentDocMapRule
12481258 persistentImportMapRule
12491259 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+
12501273
12511274-- | Get HieFile for haskell file on NormalizedFilePath
12521275getHieFile :: NormalizedFilePath -> Action (Maybe HieFile )
0 commit comments