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