- CompOK pcs2 new_details new_iface maybe_new_linkable
- -> do let hst2 = addToUFM hst1 mod_name new_details
- hit2 = addToUFM hit1 mod_name new_iface
- threaded2 = CmThreaded pcs2 hst2 hit2
-
- return (threaded2, if isJust maybe_new_linkable
- then maybe_new_linkable
- else Just old_linkable)
-
- -- Compilation failed. compile may still have updated
- -- the PCS, tho.
- CompErrs pcs2
- -> do let threaded2 = CmThreaded pcs2 hst1 hit1
- return (threaded2, Nothing)
-
--- Filter modules in the top level envs (HST, HIT, UI).
-retainInTopLevelEnvs :: [ModuleName]
- -> (HomeSymbolTable, HomeIfaceTable, UnlinkedImage)
- -> (HomeSymbolTable, HomeIfaceTable, UnlinkedImage)
-retainInTopLevelEnvs keep_these (hst, hit, ui)
- = (retainInUFM hst keep_these,
- retainInUFM hit keep_these,
- filterModuleLinkables (`elem` keep_these) ui
- )
- where
- retainInUFM :: Uniquable key => UniqFM elt -> [key] -> UniqFM elt
- retainInUFM ufm keys_to_keep
- = listToUFM (concatMap (maybeLookupUFM ufm) keys_to_keep)
- maybeLookupUFM ufm u
- = case lookupUFM ufm u of Nothing -> []; Just val -> [(u, val)]
-
--- Needed to clean up HIT and HST so that we don't get duplicates in inst env
-downwards_closure_of_module :: [ModSummary] -> ModuleName -> [ModuleName]
-downwards_closure_of_module summaries root
- = let toEdge :: ModSummary -> (ModuleName,[ModuleName])
- toEdge summ = (name_of_summary summ,
- filter (`elem` all_mods) (ms_allimps summ))
-
- all_mods = map name_of_summary summaries
-
- res = simple_transitive_closure (map toEdge summaries) [root]
- in
--- trace (showSDoc (text "DC of mod" <+> ppr root
--- <+> text "=" <+> ppr res)) $
- res
-
--- Calculate transitive closures from a set of roots given an adjacency list
-simple_transitive_closure :: Eq a => [(a,[a])] -> [a] -> [a]
-simple_transitive_closure graph set
- = let set2 = nub (concatMap dsts set ++ set)
- dsts node = fromMaybe [] (lookup node graph)
- in
- if length set == length set2
- then set
- else simple_transitive_closure graph set2
-
-
--- Calculate SCCs of the module graph, with or without taking into
--- account source imports.
-topological_sort :: Bool -> [ModSummary] -> [SCC ModSummary]
-topological_sort include_source_imports summaries
- = let
- toEdge :: ModSummary -> (ModSummary,ModuleName,[ModuleName])
- toEdge summ
- = (summ, name_of_summary summ,
- (if include_source_imports
- then ms_srcimps summ else []) ++ ms_imps summ)
-
- mash_edge :: (ModSummary,ModuleName,[ModuleName]) -> (ModSummary,Int,[Int])
- mash_edge (summ, m, m_imports)
- = case lookup m key_map of
- Nothing -> panic "reverse_topological_sort"
- Just mk -> (summ, mk,
- -- ignore imports not from the home package
- catMaybes (map (flip lookup key_map) m_imports))
-
- edges = map toEdge summaries
- key_map = zip [nm | (s,nm,imps) <- edges] [1 ..] :: [(ModuleName,Int)]
- scc_input = map mash_edge edges
- sccs = stronglyConnComp scc_input
- in
- sccs
+ CompOK new_details new_iface maybe_new_linkable
+ -> do let
+ new_linkable = maybe_new_linkable `orElse` old_linkable
+ new_info = HomeModInfo { hm_iface = new_iface,
+ hm_details = new_details,
+ hm_linkable = new_linkable }
+ return (Just new_info)
+
+ -- Compilation failed. Compile may still have updated the PCS, tho.
+ CompErrs -> return Nothing
+
+-- Filter modules in the HPT
+retainInTopLevelEnvs :: [Module] -> HomePackageTable -> HomePackageTable
+retainInTopLevelEnvs keep_these hpt
+ = mkModuleEnv [ (mod, fromJust mb_mod_info)
+ | mod <- keep_these
+ , let mb_mod_info = lookupModuleEnv hpt mod
+ , isJust mb_mod_info ]
+
+-----------------------------------------------------------------------------
+cmTopSort :: Bool -- Drop hi-boot nodes? (see below)
+ -> [ModSummary]
+ -> [SCC ModSummary]
+-- Calculate SCCs of the module graph, possibly dropping the hi-boot nodes
+--
+-- Drop hi-boot nodes (first boolean arg)?
+--
+-- False: treat the hi-boot summaries as nodes of the graph,
+-- so the graph must be acyclic
+--
+-- True: eliminate the hi-boot nodes, and instead pretend
+-- the a source-import of Foo is an import of Foo
+-- The resulting graph has no hi-boot nodes, but can by cyclic
+
+cmTopSort drop_hs_boot_nodes summaries
+ = stronglyConnComp nodes
+ where
+ -- Drop hs-boot nodes by using HsSrcFile as the key
+ hs_boot_key | drop_hs_boot_nodes = HsSrcFile
+ | otherwise = HsBootFile