[project @ 2001-07-18 16:06:10 by rrt]
[ghc-hetmet.git] / ghc / compiler / compMan / CompManager.lhs
1 %
2 % (c) The University of Glasgow, 2000
3 %
4 \section[CompManager]{The Compilation Manager}
5
6 \begin{code}
7 module CompManager ( 
8     cmInit,       -- :: GhciMode -> IO CmState
9
10     cmLoadModule, -- :: CmState -> FilePath -> IO (CmState, [String])
11
12     cmUnload,     -- :: CmState -> DynFlags -> IO CmState
13
14     cmSetContext, -- :: CmState -> String -> IO CmState
15
16     cmGetContext, -- :: CmState -> IO String
17
18 #ifdef GHCI
19     cmInfoThing,  -- :: CmState -> DynFlags -> String -> IO (Maybe TyThing)
20
21     cmRunStmt,    -- :: CmState -> DynFlags -> String -> IO (CmState, [Name])
22
23     cmTypeOfExpr, -- :: CmState -> DynFlags -> String
24                   -- -> IO (CmState, Maybe String)
25
26     cmTypeOfName, -- :: CmState -> Name -> IO (Maybe String)
27
28     cmCompileExpr,-- :: CmState -> DynFlags -> String 
29                   -- -> IO (CmState, Maybe HValue)#endif
30 #endif
31     CmState, emptyCmState  -- abstract
32   )
33 where
34
35 #include "HsVersions.h"
36
37 import CmLink
38 import CmTypes
39 import DriverPipeline
40 import DriverFlags      ( getDynFlags )
41 import DriverPhases
42 import DriverUtil
43 import Finder
44 import HscMain          ( initPersistentCompilerState, hscThing )
45 import HscTypes
46 import RnEnv            ( unQualInScope )
47 import Id               ( idType, idName )
48 import Name             ( Name, NamedThing(..), nameRdrName )
49 import NameEnv
50 import RdrName          ( lookupRdrEnv, emptyRdrEnv )
51 import Module
52 import GetImports
53 import Type             ( tidyType )
54 import VarEnv           ( emptyTidyEnv )
55 import UniqFM
56 import Unique           ( Uniquable )
57 import Digraph          ( SCC(..), stronglyConnComp, flattenSCC )
58 import ErrUtils         ( showPass )
59 import SysTools         ( cleanTempFilesExcept )
60 import Util
61 import Outputable
62 import Panic
63 import CmdLineOpts      ( DynFlags(..) )
64 import IOExts
65
66 #ifdef GHCI
67 import Interpreter      ( HValue )
68 import HscMain          ( hscStmt )
69 import PrelGHC          ( unsafeCoerce# )
70 #endif
71
72 -- lang
73 import Exception        ( throwDyn )
74
75 -- std
76 import Directory        ( getModificationTime, doesFileExist )
77 import IO
78 import Monad
79 import List             ( nub )
80 import Maybe
81 \end{code}
82
83
84 \begin{code}
85 -- Persistent state for the entire system
86 data CmState
87    = CmState {
88         hst   :: HomeSymbolTable,    -- home symbol table
89         hit   :: HomeIfaceTable,     -- home interface table
90         ui    :: UnlinkedImage,      -- the unlinked images
91         mg    :: ModuleGraph,        -- the module graph
92         gmode :: GhciMode,           -- NEVER CHANGES
93         ic    :: InteractiveContext, -- command-line binding info
94
95         pcs    :: PersistentCompilerState, -- compile's persistent state
96         pls    :: PersistentLinkerState    -- link's persistent state
97      }
98
99 emptyCmState :: GhciMode -> Module -> IO CmState
100 emptyCmState gmode mod
101     = do pcs     <- initPersistentCompilerState
102          pls     <- emptyPLS
103          return (CmState { hst    = emptySymbolTable,
104                            hit    = emptyIfaceTable,
105                            ui     = emptyUI,
106                            mg     = emptyMG, 
107                            gmode  = gmode,
108                            ic     = emptyInteractiveContext mod,
109                            pcs    = pcs,
110                            pls    = pls })
111
112 emptyInteractiveContext mod
113   = InteractiveContext { ic_module = mod, 
114                          ic_rn_env = emptyRdrEnv,
115                          ic_type_env = emptyTypeEnv }
116
117 defaultCurrentModuleName = mkModuleName "Prelude"
118 GLOBAL_VAR(defaultCurrentModule, error "no defaultCurrentModule", Module)
119
120 -- CM internal types
121 type UnlinkedImage = [Linkable] -- the unlinked images (should be a set, really)
122 emptyUI :: UnlinkedImage
123 emptyUI = []
124
125 type ModuleGraph = [ModSummary]  -- the module graph, topologically sorted
126 emptyMG :: ModuleGraph
127 emptyMG = []
128
129 -----------------------------------------------------------------------------
130 -- Produce an initial CmState.
131
132 cmInit :: GhciMode -> IO CmState
133 cmInit mode = do
134    prel <- moduleNameToModule defaultCurrentModuleName
135    writeIORef defaultCurrentModule prel
136    emptyCmState mode prel
137
138 -----------------------------------------------------------------------------
139 -- Setting the context doesn't throw away any bindings; the bindings
140 -- we've built up in the InteractiveContext simply move to the new
141 -- module.  They always shadow anything in scope in the current context.
142
143 cmSetContext :: CmState -> String -> IO CmState
144 cmSetContext cmstate str
145    = do let mn = mkModuleName str
146             modules_loaded = [ (name_of_summary s, ms_mod s)  | s <- mg cmstate ]
147
148         m <- case lookup mn modules_loaded of
149                 Just m  -> return m
150                 Nothing -> do
151                    mod <- moduleNameToModule mn
152                    if isHomeModule mod 
153                         then throwDyn (CmdLineError (showSDoc 
154                                 (quotes (ppr (moduleName mod))
155                                   <+> text "is not currently loaded")))
156                         else return mod
157
158         return cmstate{ ic = (ic cmstate){ic_module=m} }
159                 
160 cmGetContext :: CmState -> IO String
161 cmGetContext cmstate = return (moduleUserString (ic_module (ic cmstate)))
162
163 moduleNameToModule :: ModuleName -> IO Module
164 moduleNameToModule mn
165  = do maybe_stuff <- findModule mn
166       case maybe_stuff of
167         Nothing -> throwDyn (CmdLineError ("can't find module `"
168                                     ++ moduleNameUserString mn ++ "'"))
169         Just (m,_) -> return m
170
171 -----------------------------------------------------------------------------
172 -- cmRunStmt:  Run a statement/expr.
173
174 #ifdef GHCI
175 cmInfoThing :: CmState -> DynFlags -> String -> IO (Maybe TyThing)
176 cmInfoThing CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls, ic=icontext } dflags id
177    = do (pcs, thing) <- hscThing dflags hst hit pcs icontext id
178         return thing
179
180 cmRunStmt :: CmState -> DynFlags -> String
181         -> IO (CmState,                 -- new state
182                [Name])                  -- names bound by this evaluation
183 cmRunStmt cmstate dflags expr
184    = do 
185         let InteractiveContext { 
186                 ic_rn_env = rn_env, 
187                 ic_type_env = type_env,
188                 ic_module   = this_mod } = icontext
189
190         (new_pcs, maybe_stuff) 
191             <- hscStmt dflags hst hit pcs icontext expr False{-stmt-}
192
193         case maybe_stuff of
194            Nothing -> return (cmstate{ pcs=new_pcs }, [])
195            Just (ids, _, bcos) -> do
196
197                 -- update the interactive context
198                 let 
199                     names = map idName ids
200
201                     -- these names have just been shadowed
202                     shadowed = [ n | r <- map nameRdrName names,
203                                      Just n <- [lookupRdrEnv rn_env r] ]
204                     
205                     new_rn_env   = extendLocalRdrEnv rn_env names
206
207                     -- remove any shadowed bindings from the type_env
208                     filtered_type_env = delListFromNameEnv type_env shadowed
209
210                     new_type_env = extendNameEnvList filtered_type_env  
211                                         [ (getName id, AnId id) | id <- ids]
212
213                     new_ic = icontext { ic_rn_env   = new_rn_env, 
214                                         ic_type_env = new_type_env }
215
216                 -- link it
217                 hval <- linkExpr pls bcos
218
219                 -- run it!
220                 let thing_to_run = unsafeCoerce# hval :: IO [HValue]
221                 hvals <- thing_to_run
222
223                 -- Get the newly bound things, and bind them.  Don't forget
224                 -- to delete any shadowed bindings from the closure_env, lest
225                 -- we end up with a space leak.
226                 pls <- delListFromClosureEnv pls shadowed
227                 new_pls <- addListToClosureEnv pls (zip names hvals)
228
229                 return (cmstate{ pcs=new_pcs, pls=new_pls, ic=new_ic }, names)
230    where
231        CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls, ic=icontext } = cmstate
232 #endif
233
234 -----------------------------------------------------------------------------
235 -- cmTypeOfExpr: returns a string representing the type of an expression
236
237 #ifdef GHCI
238 cmTypeOfExpr :: CmState -> DynFlags -> String -> IO (CmState, Maybe String)
239 cmTypeOfExpr cmstate dflags expr
240    = do (new_pcs, maybe_stuff) 
241           <- hscStmt dflags hst hit pcs ic expr True{-just an expr-}
242
243         let new_cmstate = cmstate{pcs = new_pcs}
244
245         case maybe_stuff of
246            Nothing -> return (new_cmstate, Nothing)
247            Just (_, ty, _) ->
248              let pit = pcs_PIT pcs
249                  modname = moduleName (ic_module ic)
250                  tidy_ty = tidyType emptyTidyEnv ty
251                  str = case lookupIfaceByModName hit pit modname of
252                           Nothing    -> showSDoc (ppr tidy_ty)
253                           Just iface -> showSDocForUser unqual (ppr tidy_ty)
254                              where unqual = unQualInScope (mi_globals iface)
255              in return (new_cmstate, Just str)
256    where
257        CmState{ hst=hst, hit=hit, pcs=pcs, ic=ic } = cmstate
258 #endif
259
260 -----------------------------------------------------------------------------
261 -- cmTypeOfName: returns a string representing the type of a name.
262
263 #ifdef GHCI
264 cmTypeOfName :: CmState -> Name -> IO (Maybe String)
265 cmTypeOfName CmState{ hit=hit, pcs=pcs, ic=ic } name
266  = case lookupNameEnv (ic_type_env ic) name of
267         Nothing -> return Nothing
268         Just (AnId id) -> 
269            let pit = pcs_PIT pcs
270                modname = moduleName (ic_module ic)
271                ty = tidyType emptyTidyEnv (idType id)
272                str = case lookupIfaceByModName hit pit modname of
273                         Nothing    -> showSDoc (ppr ty)
274                         Just iface -> showSDocForUser unqual (ppr ty)
275                            where unqual = unQualInScope (mi_globals iface)
276            in return (Just str)
277
278         _ -> panic "cmTypeOfName"
279 #endif
280
281 -----------------------------------------------------------------------------
282 -- cmCompileExpr: compile an expression and deliver an HValue
283
284 #ifdef GHCI
285 cmCompileExpr :: CmState -> DynFlags -> String -> IO (CmState, Maybe HValue)
286 cmCompileExpr cmstate dflags expr
287    = do 
288         let InteractiveContext { 
289                 ic_rn_env = rn_env, 
290                 ic_type_env = type_env,
291                 ic_module   = this_mod } = icontext
292
293         (new_pcs, maybe_stuff) 
294             <- hscStmt dflags hst hit pcs icontext 
295                   ("let __cmCompileExpr = "++expr) False{-stmt-}
296
297         case maybe_stuff of
298            Nothing -> return (cmstate{ pcs=new_pcs }, Nothing)
299            Just (ids, _, bcos) -> do
300
301                 -- link it
302                 hval <- linkExpr pls bcos
303
304                 -- run it!
305                 let thing_to_run = unsafeCoerce# hval :: IO [HValue]
306                 hvals <- thing_to_run
307
308                 case (ids,hvals) of
309                   ([id],[hv]) -> return (cmstate{ pcs=new_pcs }, Just hv)
310                   _ -> panic "cmCompileExpr"
311
312    where
313        CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls, ic=icontext } = cmstate
314 #endif
315
316 -----------------------------------------------------------------------------
317 -- cmInfo: return "info" about an expression.  The info might be:
318 --
319 --      * its type, for an expression,
320 --      * the class definition, for a class
321 --      * the datatype definition, for a tycon (or synonym)
322 --      * the export list, for a module
323 --
324 -- Can be used to find the type of the last expression compiled, by looking
325 -- for "it".
326
327 cmInfo :: CmState -> String -> IO (Maybe String)
328 cmInfo cmstate str 
329  = do error "cmInfo not implemented yet"
330
331 -----------------------------------------------------------------------------
332 -- Unload the compilation manager's state: everything it knows about the
333 -- current collection of modules in the Home package.
334
335 cmUnload :: CmState -> DynFlags -> IO CmState
336 cmUnload state@CmState{ gmode=mode, pls=pls, pcs=pcs } dflags
337  = do -- Throw away the old home dir cache
338       emptyHomeDirCache
339
340       -- Unload everything the linker knows about
341       new_pls <- CmLink.unload mode dflags [] pls 
342
343       -- Start with a fresh CmState, but keep the PersistentCompilerState
344       new_state <- cmInit mode
345       return new_state{ pcs=pcs, pls=new_pls }
346
347 -----------------------------------------------------------------------------
348 -- The real business of the compilation manager: given a system state and
349 -- a module name, try and bring the module up to date, probably changing
350 -- the system state at the same time.
351
352 cmLoadModule :: CmState 
353              -> [FilePath]
354              -> IO (CmState,            -- new state
355                     Bool,               -- was successful
356                     [String])           -- list of modules loaded
357
358 cmLoadModule cmstate1 rootnames
359    = do -- version 1's are the original, before downsweep
360         let pls1      = pls    cmstate1
361         let pcs1      = pcs    cmstate1
362         let hst1      = hst    cmstate1
363         let hit1      = hit    cmstate1
364         -- similarly, ui1 is the (complete) set of linkables from
365         -- the previous pass, if any.
366         let ui1       = ui     cmstate1
367         let mg1       = mg     cmstate1
368         let ic1       = ic     cmstate1
369
370         let ghci_mode = gmode cmstate1 -- this never changes
371
372         -- Do the downsweep to reestablish the module graph
373         dflags <- getDynFlags
374         let verb = verbosity dflags
375
376         showPass dflags "Chasing dependencies"
377         when (verb >= 1 && ghci_mode == Batch) $
378            hPutStrLn stderr (showSDoc (hcat [
379              text progName, text ": chasing modules from: ",
380              hcat (punctuate comma (map text rootnames))]))
381
382         (mg2unsorted, a_root_is_Main) <- downsweep rootnames mg1
383         let mg2unsorted_names = map name_of_summary mg2unsorted
384
385         -- reachable_from follows source as well as normal imports
386         let reachable_from :: ModuleName -> [ModuleName]
387             reachable_from = downwards_closure_of_module mg2unsorted
388  
389         -- should be cycle free; ignores 'import source's
390         let mg2 = topological_sort False mg2unsorted
391         -- ... whereas this takes them into account.  Used for
392         -- backing out partially complete cycles following a failed
393         -- upsweep, and for removing from hst/hit all the modules
394         -- not in strict downwards closure, during calls to compile.
395         let mg2_with_srcimps = topological_sort True mg2unsorted
396
397         -- Sort out which linkables we wish to keep in the unlinked image.
398         -- See getValidLinkables below for details.
399         valid_linkables <- getValidLinkables ui1 mg2unsorted_names 
400                                 mg2_with_srcimps
401         -- when (verb >= 2) $
402         --    putStrLn (showSDoc (text "Valid linkables:" 
403         --                       <+> ppr valid_linkables))
404
405         -- Figure out a stable set of modules which can be retained
406         -- the top level envs, to avoid upsweeping them.  Goes to a
407         -- bit of trouble to avoid upsweeping module cycles.
408         --
409         -- Construct a set S of stable modules like this:
410         -- Travel upwards, over the sccified graph.  For each scc
411         -- of modules ms, add ms to S only if:
412         -- 1.  All home imports of ms are either in ms or S
413         -- 2.  A valid linkable exists for each module in ms
414
415         stable_mods <- preUpsweep valid_linkables hit1 
416                                   mg2unsorted_names [] mg2_with_srcimps
417
418         let stable_summaries
419                = concatMap (findInSummaries mg2unsorted) stable_mods
420
421             stable_linkables
422                = filter (\m -> linkableModName m `elem` stable_mods) 
423                     valid_linkables
424
425         when (verb >= 2) $
426            putStrLn (showSDoc (text "Stable modules:" 
427                                <+> sep (map (text.moduleNameUserString) stable_mods)))
428
429         -- unload any modules which aren't going to be re-linked this
430         -- time around.
431         pls2 <- unload ghci_mode dflags stable_linkables pls1
432
433         -- We could at this point detect cycles which aren't broken by
434         -- a source-import, and complain immediately, but it seems better
435         -- to let upsweep_mods do this, so at least some useful work gets
436         -- done before the upsweep is abandoned.
437         let upsweep_these
438                = filter (\scc -> any (`notElem` stable_mods) 
439                                      (map name_of_summary (flattenSCC scc)))
440                         mg2
441
442         --hPutStrLn stderr "after tsort:\n"
443         --hPutStrLn stderr (showSDoc (vcat (map ppr mg2)))
444
445         -- Because we don't take into account source imports when doing
446         -- the topological sort, there shouldn't be any cycles in mg2.
447         -- If there is, we complain and give up -- the user needs to
448         -- break the cycle using a boot file.
449
450         -- Now do the upsweep, calling compile for each module in
451         -- turn.  Final result is version 3 of everything.
452
453         let threaded2 = CmThreaded pcs1 hst1 hit1
454
455         (upsweep_complete_success, threaded3, modsUpswept, newLis)
456            <- upsweep_mods ghci_mode dflags valid_linkables reachable_from 
457                            threaded2 upsweep_these
458
459         let ui3 = add_to_ui valid_linkables newLis
460         let (CmThreaded pcs3 hst3 hit3) = threaded3
461
462         -- At this point, modsUpswept and newLis should have the same
463         -- length, so there is one new (or old) linkable for each 
464         -- mod which was processed (passed to compile).
465
466         -- Make modsDone be the summaries for each home module now
467         -- available; this should equal the domains of hst3 and hit3.
468         -- (NOT STRICTLY TRUE if an interactive session was started
469         --  with some object on disk ???)
470         -- Get in in a roughly top .. bottom order (hence reverse).
471
472         let modsDone = reverse modsUpswept ++ stable_summaries
473
474         -- Try and do linking in some form, depending on whether the
475         -- upsweep was completely or only partially successful.
476
477         if upsweep_complete_success
478
479          then 
480            -- Easy; just relink it all.
481            do when (verb >= 2) $ 
482                  hPutStrLn stderr "Upsweep completely successful."
483
484               -- clean up after ourselves
485               cleanTempFilesExcept verb (ppFilesFromSummaries modsDone)
486
487               -- link everything together
488               linkresult <- link ghci_mode dflags a_root_is_Main ui3 pls2
489
490               cmLoadFinish True linkresult 
491                         hst3 hit3 ui3 modsDone ghci_mode pcs3
492
493          else 
494            -- Tricky.  We need to back out the effects of compiling any
495            -- half-done cycles, both so as to clean up the top level envs
496            -- and to avoid telling the interactive linker to link them.
497            do when (verb >= 2) $
498                 hPutStrLn stderr "Upsweep partially successful."
499
500               let modsDone_names
501                      = map name_of_summary modsDone
502               let mods_to_zap_names 
503                      = findPartiallyCompletedCycles modsDone_names 
504                           mg2_with_srcimps
505               let mods_to_keep
506                      = filter ((`notElem` mods_to_zap_names).name_of_summary) 
507                           modsDone
508
509               let (hst4, hit4, ui4)
510                      = retainInTopLevelEnvs (map name_of_summary mods_to_keep) 
511                                             (hst3,hit3,ui3)
512
513               -- clean up after ourselves
514               cleanTempFilesExcept verb (ppFilesFromSummaries mods_to_keep)
515
516               -- link everything together
517               linkresult <- link ghci_mode dflags False ui4 pls2
518
519               cmLoadFinish False linkresult 
520                     hst4 hit4 ui4 mods_to_keep ghci_mode pcs3
521
522
523 -- Finish up after a cmLoad.
524 --
525 -- Empty the interactive context and set the module context to the topmost
526 -- newly loaded module, or the Prelude if none were loaded.
527 cmLoadFinish ok linkresult hst hit ui mods ghci_mode pcs
528   = do case linkresult of {
529           LinkErrs _ _ -> panic "cmLoadModule: link failed (2)";
530           LinkOK pls   -> do
531
532        def_mod <- readIORef defaultCurrentModule
533        let current_mod = case mods of 
534                                 []    -> def_mod
535                                 (x:_) -> ms_mod x
536
537            new_ic = emptyInteractiveContext current_mod
538
539            new_cmstate = CmState{ hst=hst, hit=hit, 
540                                   ui=ui, mg=mods,
541                                   gmode=ghci_mode, pcs=pcs, 
542                                   pls=pls,
543                                   ic = new_ic }
544            mods_loaded = map (moduleNameUserString.name_of_summary) mods
545
546        return (new_cmstate, ok, mods_loaded)
547     }
548
549 -- used to fish out the preprocess output files for the purposes
550 -- of cleaning up.
551 ppFilesFromSummaries summaries
552   = [ fn | Just fn <- map toPpFile summaries ]
553   where
554    toPpFile sum
555      | hspp /= ml_hs_file loc = hspp
556      | otherwise              = Nothing
557     where
558       loc  = ms_location sum
559       hspp = ml_hspp_file loc
560
561
562 -----------------------------------------------------------------------------
563 -- getValidLinkables
564
565 -- For each module (or SCC of modules), we take:
566 --
567 --      - an on-disk linkable, if this is the first time around and one
568 --        is available.
569 --
570 --      - the old linkable, otherwise (and if one is available).
571 --
572 -- and we throw away the linkable if it is older than the source
573 -- file.  We ignore the on-disk linkables unless all of the dependents
574 -- of this SCC also have on-disk linkables.
575 --
576 -- If a module has a valid linkable, then it may be STABLE (see below),
577 -- and it is classified as SOURCE UNCHANGED for the purposes of calling
578 -- compile.
579 --
580 -- ToDo: this pass could be merged with the preUpsweep.
581
582 getValidLinkables
583         :: [Linkable]           -- old linkables
584         -> [ModuleName]         -- all home modules
585         -> [SCC ModSummary]     -- all modules in the program, dependency order
586         -> IO [Linkable]        -- still-valid linkables 
587
588 getValidLinkables old_linkables all_home_mods module_graph
589   = foldM (getValidLinkablesSCC old_linkables all_home_mods) [] module_graph
590
591 getValidLinkablesSCC old_linkables all_home_mods new_linkables scc0
592    = let 
593           scc             = flattenSCC scc0
594           scc_names       = map name_of_summary scc
595           home_module m   = m `elem` all_home_mods && m `notElem` scc_names
596           scc_allhomeimps = nub (filter home_module (concatMap ms_imps scc))
597                 -- NOTE: ms_imps, not ms_allimps above.  We don't want to
598                 -- force a module's SOURCE imports to be already compiled for
599                 -- its object linkable to be valid.
600
601           has_object m = case findModuleLinkable_maybe new_linkables m of
602                             Nothing -> False
603                             Just l  -> isObjectLinkable l
604
605           objects_allowed = all has_object scc_allhomeimps
606      in do
607
608      these_linkables 
609         <- foldM (getValidLinkable old_linkables objects_allowed) [] scc
610
611         -- since an scc can contain only all objects or no objects at all,
612         -- we have to check whether we got all objects or not, and re-do
613         -- the linkable check if not.
614      adjusted_linkables 
615         <- if objects_allowed && not (all isObjectLinkable these_linkables)
616               then foldM (getValidLinkable old_linkables False) [] scc
617               else return these_linkables
618
619      return (adjusted_linkables ++ new_linkables)
620
621
622 getValidLinkable :: [Linkable] -> Bool -> [Linkable] -> ModSummary 
623         -> IO [Linkable]
624 getValidLinkable old_linkables objects_allowed new_linkables summary 
625   = do let mod_name = name_of_summary summary
626
627        maybe_disk_linkable
628           <- if (not objects_allowed)
629                 then return Nothing
630                 else case ml_obj_file (ms_location summary) of
631                         Just obj_fn -> maybe_getFileLinkable mod_name obj_fn
632                         Nothing -> return Nothing
633
634        let old_linkable = findModuleLinkable_maybe old_linkables mod_name
635            maybe_old_linkable =
636                 case old_linkable of
637                     Just l | not (isObjectLinkable l) || stillThere l 
638                                 -> old_linkable
639                                 -- ToDo: emit a warning if not (stillThere l)
640                     other -> Nothing
641
642            -- make sure that if we had an old disk linkable around, that it's
643            -- still there on the disk (in case we need to re-link it).
644            stillThere l = 
645                 case maybe_disk_linkable of
646                    Nothing    -> False
647                    Just l_disk -> linkableTime l == linkableTime l_disk
648
649            -- we only look for objects on disk the first time around;
650            -- if the user compiles a module on the side during a GHCi session,
651            -- it won't be picked up until the next ":load".  This is what the
652            -- "null old_linkables" test below is.
653            linkable | null old_linkables = maybeToList maybe_disk_linkable
654                     | otherwise          = maybeToList maybe_old_linkable
655
656            -- only linkables newer than the source code are valid
657            src_date = ms_hs_date summary
658
659            valid_linkable
660               =  filter (\l -> linkableTime l >= src_date) linkable
661                 -- why '>=' rather than '>' above?  If the filesystem stores
662                 -- times to the nearset second, we may occasionally find that
663                 -- the object & source have the same modification time, 
664                 -- especially if the source was automatically generated
665                 -- and compiled.  Using >= is slightly unsafe, but it matches
666                 -- make's behaviour.
667
668        return (valid_linkable ++ new_linkables)
669
670
671 maybe_getFileLinkable :: ModuleName -> FilePath -> IO (Maybe Linkable)
672 maybe_getFileLinkable mod_name obj_fn
673    = do obj_exist <- doesFileExist obj_fn
674         if not obj_exist 
675          then return Nothing 
676          else 
677          do let stub_fn = case splitFilename3 obj_fn of
678                              (dir, base, ext) -> dir ++ "/" ++ base ++ ".stub_o"
679             stub_exist <- doesFileExist stub_fn
680             obj_time <- getModificationTime obj_fn
681             if stub_exist
682              then return (Just (LM obj_time mod_name [DotO obj_fn, DotO stub_fn]))
683              else return (Just (LM obj_time mod_name [DotO obj_fn]))
684
685
686 -----------------------------------------------------------------------------
687 -- Do a pre-upsweep without use of "compile", to establish a 
688 -- (downward-closed) set of stable modules for which we won't call compile.
689
690 -- a stable module:
691 --      * has a valid linkable (see getValidLinkables above)
692 --      * depends only on stable modules
693 --      * has an interface in the HIT (interactive mode only)
694
695 preUpsweep :: [Linkable]        -- new valid linkables
696            -> HomeIfaceTable
697            -> [ModuleName]      -- names of all mods encountered in downsweep
698            -> [ModuleName]      -- accumulating stable modules
699            -> [SCC ModSummary]  -- scc-ified mod graph, including src imps
700            -> IO [ModuleName]   -- stable modules
701
702 preUpsweep valid_lis hit all_home_mods stable []  = return stable
703 preUpsweep valid_lis hit all_home_mods stable (scc0:sccs)
704    = do let scc = flattenSCC scc0
705             scc_allhomeimps :: [ModuleName]
706             scc_allhomeimps 
707                = nub (filter (`elem` all_home_mods) (concatMap ms_allimps scc))
708             all_imports_in_scc_or_stable
709                = all in_stable_or_scc scc_allhomeimps
710             scc_names
711                = map name_of_summary scc
712             in_stable_or_scc m
713                = m `elem` scc_names || m `elem` stable
714
715             -- now we check for valid linkables: each module in the SCC must 
716             -- have a valid linkable (see getValidLinkables above).
717             has_valid_linkable new_summary
718               = isJust (findModuleLinkable_maybe valid_lis modname)
719                where modname = name_of_summary new_summary
720
721             has_interface summary = ms_mod summary `elemUFM` hit
722
723             scc_is_stable = all_imports_in_scc_or_stable
724                           && all has_valid_linkable scc
725                           && all has_interface scc
726
727         if scc_is_stable
728          then preUpsweep valid_lis hit all_home_mods (scc_names++stable) sccs
729          else preUpsweep valid_lis hit all_home_mods stable sccs
730
731
732 -- Helper for preUpsweep.  Assuming that new_summary's imports are all
733 -- stable (in the sense of preUpsweep), determine if new_summary is itself
734 -- stable, and, if so, in batch mode, return its linkable.
735 findInSummaries :: [ModSummary] -> ModuleName -> [ModSummary]
736 findInSummaries old_summaries mod_name
737    = [s | s <- old_summaries, name_of_summary s == mod_name]
738
739 findModInSummaries :: [ModSummary] -> Module -> Maybe ModSummary
740 findModInSummaries old_summaries mod
741    = case [s | s <- old_summaries, ms_mod s == mod] of
742          [] -> Nothing
743          (s:_) -> Just s
744
745 -- Return (names of) all those in modsDone who are part of a cycle
746 -- as defined by theGraph.
747 findPartiallyCompletedCycles :: [ModuleName] -> [SCC ModSummary] -> [ModuleName]
748 findPartiallyCompletedCycles modsDone theGraph
749    = chew theGraph
750      where
751         chew [] = []
752         chew ((AcyclicSCC v):rest) = chew rest    -- acyclic?  not interesting.
753         chew ((CyclicSCC vs):rest)
754            = let names_in_this_cycle = nub (map name_of_summary vs)
755                  mods_in_this_cycle  
756                     = nub ([done | done <- modsDone, 
757                                    done `elem` names_in_this_cycle])
758                  chewed_rest = chew rest
759              in 
760              if   not (null mods_in_this_cycle) 
761                   && length mods_in_this_cycle < length names_in_this_cycle
762              then mods_in_this_cycle ++ chewed_rest
763              else chewed_rest
764
765
766 -- Add the given (LM-form) Linkables to the UI, overwriting previous
767 -- versions if they exist.
768 add_to_ui :: UnlinkedImage -> [Linkable] -> UnlinkedImage
769 add_to_ui ui lis
770    = filter (not_in lis) ui ++ lis
771      where
772         not_in :: [Linkable] -> Linkable -> Bool
773         not_in lis li
774            = all (\l -> linkableModName l /= mod) lis
775            where mod = linkableModName li
776                                   
777
778 data CmThreaded  -- stuff threaded through individual module compilations
779    = CmThreaded PersistentCompilerState HomeSymbolTable HomeIfaceTable
780
781
782 -- Compile multiple modules, stopping as soon as an error appears.
783 -- There better had not be any cyclic groups here -- we check for them.
784 upsweep_mods :: GhciMode
785              -> DynFlags
786              -> UnlinkedImage         -- valid linkables
787              -> (ModuleName -> [ModuleName])  -- to construct downward closures
788              -> CmThreaded            -- PCS & HST & HIT
789              -> [SCC ModSummary]      -- mods to do (the worklist)
790                                       -- ...... RETURNING ......
791              -> IO (Bool{-complete success?-},
792                     CmThreaded,
793                     [ModSummary],     -- mods which succeeded
794                     [Linkable])       -- new linkables
795
796 upsweep_mods ghci_mode dflags oldUI reachable_from threaded 
797      []
798    = return (True, threaded, [], [])
799
800 upsweep_mods ghci_mode dflags oldUI reachable_from threaded 
801      ((CyclicSCC ms):_)
802    = do hPutStrLn stderr ("Module imports form a cycle for modules:\n\t" ++
803                           unwords (map (moduleNameUserString.name_of_summary) ms))
804         return (False, threaded, [], [])
805
806 upsweep_mods ghci_mode dflags oldUI reachable_from threaded 
807      ((AcyclicSCC mod):mods)
808    = do --case threaded of
809         --   CmThreaded pcsz hstz hitz
810         --      -> putStrLn ("UPSWEEP_MOD: hit = " ++ show (map (moduleNameUserString.moduleName.mi_module) (eltsUFM hitz)))
811
812         (threaded1, maybe_linkable) 
813            <- upsweep_mod ghci_mode dflags oldUI threaded mod 
814                           (reachable_from (name_of_summary mod))
815         case maybe_linkable of
816            Just linkable 
817               -> -- No errors; do the rest
818                  do (restOK, threaded2, modOKs, linkables) 
819                        <- upsweep_mods ghci_mode dflags oldUI reachable_from 
820                                        threaded1 mods
821                     return (restOK, threaded2, mod:modOKs, linkable:linkables)
822            Nothing -- we got a compilation error; give up now
823               -> return (False, threaded1, [], [])
824
825
826 -- Compile a single module.  Always produce a Linkable for it if 
827 -- successful.  If no compilation happened, return the old Linkable.
828 upsweep_mod :: GhciMode 
829             -> DynFlags
830             -> UnlinkedImage
831             -> CmThreaded
832             -> ModSummary
833             -> [ModuleName]
834             -> IO (CmThreaded, Maybe Linkable)
835
836 upsweep_mod ghci_mode dflags oldUI threaded1 summary1 reachable_inc_me
837    = do 
838         let mod_name = name_of_summary summary1
839         let verb = verbosity dflags
840
841         let (CmThreaded pcs1 hst1 hit1) = threaded1
842         let old_iface = lookupUFM hit1 mod_name
843
844         let maybe_old_linkable = findModuleLinkable_maybe oldUI mod_name
845
846             source_unchanged = isJust maybe_old_linkable
847
848             reachable_only = filter (/= (name_of_summary summary1)) 
849                                 reachable_inc_me
850
851            -- in interactive mode, all home modules below us *must* have an
852            -- interface in the HIT.  We never demand-load home interfaces in
853            -- interactive mode.
854             (hst1_strictDC, hit1_strictDC, [])
855                = ASSERT(ghci_mode == Batch || 
856                         all (`elemUFM` hit1) reachable_only)
857                  retainInTopLevelEnvs reachable_only (hst1,hit1,[])
858
859             old_linkable 
860                = unJust "upsweep_mod:old_linkable" maybe_old_linkable
861
862             have_object 
863                | Just l <- maybe_old_linkable, isObjectLinkable l = True
864                | otherwise = False
865
866         compresult <- compile ghci_mode summary1 source_unchanged
867                          have_object old_iface hst1_strictDC hit1_strictDC pcs1
868
869         case compresult of
870
871            -- Compilation "succeeded", and may or may not have returned a new
872            -- linkable (depending on whether compilation was actually performed
873            -- or not).
874            CompOK pcs2 new_details new_iface maybe_new_linkable
875               -> do let hst2      = addToUFM hst1 mod_name new_details
876                         hit2      = addToUFM hit1 mod_name new_iface
877                         threaded2 = CmThreaded pcs2 hst2 hit2
878
879                     return (threaded2, if isJust maybe_new_linkable
880                                           then maybe_new_linkable
881                                           else Just old_linkable)
882
883            -- Compilation failed.  compile may still have updated
884            -- the PCS, tho.
885            CompErrs pcs2
886               -> do let threaded2 = CmThreaded pcs2 hst1 hit1
887                     return (threaded2, Nothing)
888
889 -- Filter modules in the top level envs (HST, HIT, UI).
890 retainInTopLevelEnvs :: [ModuleName]
891                         -> (HomeSymbolTable, HomeIfaceTable, UnlinkedImage)
892                         -> (HomeSymbolTable, HomeIfaceTable, UnlinkedImage)
893 retainInTopLevelEnvs keep_these (hst, hit, ui)
894    = (retainInUFM hst keep_these,
895       retainInUFM hit keep_these,
896       filterModuleLinkables (`elem` keep_these) ui
897      )
898      where
899         retainInUFM :: Uniquable key => UniqFM elt -> [key] -> UniqFM elt
900         retainInUFM ufm keys_to_keep
901            = listToUFM (concatMap (maybeLookupUFM ufm) keys_to_keep)
902         maybeLookupUFM ufm u 
903            = case lookupUFM ufm u of Nothing -> []; Just val -> [(u, val)] 
904
905 -- Needed to clean up HIT and HST so that we don't get duplicates in inst env
906 downwards_closure_of_module :: [ModSummary] -> ModuleName -> [ModuleName]
907 downwards_closure_of_module summaries root
908    = let toEdge :: ModSummary -> (ModuleName,[ModuleName])
909          toEdge summ = (name_of_summary summ, 
910                         filter (`elem` all_mods) (ms_allimps summ))
911
912          all_mods = map name_of_summary summaries
913
914          res = simple_transitive_closure (map toEdge summaries) [root]
915      in
916 --         trace (showSDoc (text "DC of mod" <+> ppr root
917 --                          <+> text "=" <+> ppr res)) $
918          res
919
920 -- Calculate transitive closures from a set of roots given an adjacency list
921 simple_transitive_closure :: Eq a => [(a,[a])] -> [a] -> [a]
922 simple_transitive_closure graph set 
923    = let set2      = nub (concatMap dsts set ++ set)
924          dsts node = fromMaybe [] (lookup node graph)
925      in
926          if   length set == length set2
927          then set
928          else simple_transitive_closure graph set2
929
930
931 -- Calculate SCCs of the module graph, with or without taking into
932 -- account source imports.
933 topological_sort :: Bool -> [ModSummary] -> [SCC ModSummary]
934 topological_sort include_source_imports summaries
935    = let 
936          toEdge :: ModSummary -> (ModSummary,ModuleName,[ModuleName])
937          toEdge summ
938              = (summ, name_of_summary summ, 
939                       (if include_source_imports 
940                        then ms_srcimps summ else []) ++ ms_imps summ)
941         
942          mash_edge :: (ModSummary,ModuleName,[ModuleName]) -> (ModSummary,Int,[Int])
943          mash_edge (summ, m, m_imports)
944             = case lookup m key_map of
945                  Nothing -> panic "reverse_topological_sort"
946                  Just mk -> (summ, mk, 
947                                 -- ignore imports not from the home package
948                                 catMaybes (map (flip lookup key_map) m_imports))
949
950          edges     = map toEdge summaries
951          key_map   = zip [nm | (s,nm,imps) <- edges] [1 ..] :: [(ModuleName,Int)]
952          scc_input = map mash_edge edges
953          sccs      = stronglyConnComp scc_input
954      in
955          sccs
956
957
958 -- Chase downwards from the specified root set, returning summaries
959 -- for all home modules encountered.  Only follow source-import
960 -- links.  Also returns a Bool to indicate whether any of the roots
961 -- are module Main.
962 downsweep :: [FilePath] -> [ModSummary] -> IO ([ModSummary], Bool)
963 downsweep rootNm old_summaries
964    = do rootSummaries <- mapM getRootSummary rootNm
965         let a_root_is_Main 
966                = any ((=="Main").moduleNameUserString.name_of_summary) 
967                      rootSummaries
968         all_summaries
969            <- loop (concat (map ms_imps rootSummaries))
970                 (mkModuleEnv [ (mod, s) | s <- rootSummaries, 
971                                           let mod = ms_mod s, isHomeModule mod 
972                              ])
973         return (all_summaries, a_root_is_Main)
974      where
975         getRootSummary :: FilePath -> IO ModSummary
976         getRootSummary file
977            | haskellish_src_file file
978            = do exists <- doesFileExist file
979                 if exists then summariseFile file else do
980                 throwDyn (CmdLineError ("can't find file `" ++ file ++ "'"))    
981            | otherwise
982            = do exists <- doesFileExist hs_file
983                 if exists then summariseFile hs_file else do
984                 exists <- doesFileExist lhs_file
985                 if exists then summariseFile lhs_file else do
986                 let mod_name = mkModuleName file
987                 maybe_summary <- getSummary mod_name
988                 case maybe_summary of
989                    Nothing -> packageModErr mod_name
990                    Just s  -> return s
991            where 
992                  hs_file = file ++ ".hs"
993                  lhs_file = file ++ ".lhs"
994
995         getSummary :: ModuleName -> IO (Maybe ModSummary)
996         getSummary nm
997            = do found <- findModule nm
998                 case found of
999                    Just (mod, location) -> do
1000                         let old_summary = findModInSummaries old_summaries mod
1001                         summarise mod location old_summary
1002
1003                    Nothing -> throwDyn (CmdLineError 
1004                                    ("can't find module `" 
1005                                      ++ showSDoc (ppr nm) ++ "'"))
1006
1007         -- loop invariant: env doesn't contain package modules
1008         loop :: [ModuleName] -> ModuleEnv ModSummary -> IO [ModSummary]
1009         loop [] env = return (moduleEnvElts env)
1010         loop imps env
1011            = do -- imports for modules we don't already have
1012                 let needed_imps = nub (filter (not . (`elemUFM` env)) imps)
1013
1014                 -- summarise them
1015                 needed_summaries <- mapM getSummary needed_imps
1016
1017                 -- get just the "home" modules
1018                 let new_home_summaries = [ s | Just s <- needed_summaries ]
1019
1020                 -- loop, checking the new imports
1021                 let new_imps = concat (map ms_imps new_home_summaries)
1022                 loop new_imps (extendModuleEnvList env 
1023                                 [ (ms_mod s, s) | s <- new_home_summaries ])
1024
1025 -----------------------------------------------------------------------------
1026 -- Summarising modules
1027
1028 -- We have two types of summarisation:
1029 --
1030 --    * Summarise a file.  This is used for the root module passed to
1031 --      cmLoadModule.  The file is read, and used to determine the root
1032 --      module name.  The module name may differ from the filename.
1033 --
1034 --    * Summarise a module.  We are given a module name, and must provide
1035 --      a summary.  The finder is used to locate the file in which the module
1036 --      resides.
1037
1038 summariseFile :: FilePath -> IO ModSummary
1039 summariseFile file
1040    = do hspp_fn <- preprocess file
1041         (srcimps,imps,mod_name) <- getImportsFromFile hspp_fn
1042
1043         let (path, basename, ext) = splitFilename3 file
1044
1045         Just (mod, location)
1046            <- mkHomeModuleLocn mod_name (path ++ '/':basename) (Just file)
1047
1048         src_timestamp
1049            <- case ml_hs_file location of 
1050                  Nothing     -> noHsFileErr mod_name
1051                  Just src_fn -> getModificationTime src_fn
1052
1053         return (ModSummary mod
1054                            location{ml_hspp_file=Just hspp_fn}
1055                            srcimps imps src_timestamp)
1056
1057 -- Summarise a module, and pick up source and timestamp.
1058 summarise :: Module -> ModuleLocation -> Maybe ModSummary
1059          -> IO (Maybe ModSummary)
1060 summarise mod location old_summary
1061    | not (isHomeModule mod) = return Nothing
1062    | otherwise
1063    = do let hs_fn = unJust "summarise" (ml_hs_file location)
1064
1065         case ml_hs_file location of {
1066            Nothing -> do {
1067                 dflags <- getDynFlags;
1068                 when (verbosity dflags >= 1) $
1069                     hPutStrLn stderr ("WARNING: module `" ++ 
1070                         moduleUserString mod ++ "' has no source file.");
1071                 return Nothing;
1072              };
1073
1074            Just src_fn -> do
1075
1076         src_timestamp <- getModificationTime src_fn
1077
1078         -- return the cached summary if the source didn't change
1079         case old_summary of {
1080            Just s | ms_hs_date s == src_timestamp -> return (Just s);
1081            _ -> do
1082
1083         hspp_fn <- preprocess hs_fn
1084         (srcimps,imps,mod_name) <- getImportsFromFile hspp_fn
1085
1086         when (mod_name /= moduleName mod) $
1087                 throwDyn (ProgramError 
1088                    (showSDoc (text hs_fn
1089                               <>  text ": file name does not match module name"
1090                               <+> quotes (ppr (moduleName mod)))))
1091
1092         return (Just (ModSummary mod location{ml_hspp_file=Just hspp_fn} 
1093                                  srcimps imps src_timestamp))
1094         }
1095       }
1096
1097
1098 noHsFileErr mod
1099   = throwDyn (CmdLineError (showSDoc (text "no source file for module" <+> quotes (ppr mod))))
1100
1101 packageModErr mod
1102   = throwDyn (CmdLineError (showSDoc (text "module" <+>
1103                                    quotes (ppr mod) <+>
1104                                    text "is a package module")))
1105 \end{code}