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