+data HscChecked
+ = HscChecked
+ -- parsed
+ (Located (HsModule RdrName))
+ -- renamed
+ (Maybe (HsGroup Name,[LImportDecl Name],Maybe [LIE Name]))
+ -- typechecked
+ (Maybe (LHsBinds Id, GlobalRdrEnv, ModDetails))
+
+
+-- Status of a compilation to hard-code or nothing.
+data HscStatus
+ = HscNoRecomp
+ | HscRecomp Bool -- Has stub files.
+ -- This is a hack. We can't compile C files here
+ -- since it's done in DriverPipeline. For now we
+ -- just return True if we want the caller to compile
+ -- it for us.
+
+-- Status of a compilation to byte-code.
+data InteractiveStatus
+ = InteractiveNoRecomp
+ | InteractiveRecomp Bool -- Same as HscStatus
+ CompiledByteCode
+
+type NoRecomp result = HscEnv -> ModSummary -> Bool -> ModIface -> Maybe (Int,Int) -> IO result
+type FrontEnd core = HscEnv -> ModSummary -> Maybe (Int,Int) -> IO (Maybe core)
+type BackEnd core prepCore = HscEnv -> ModSummary -> Maybe ModIface -> core -> IO prepCore
+type CodeGen prepCore result = HscEnv -> ModSummary -> prepCore -> IO result
+
+type Compiler result = HscEnv
+ -> ModSummary
+ -> Bool -- True <=> source unchanged
+ -> Bool -- True <=> have an object file (for msgs only)
+ -> Maybe ModIface -- Old interface, if available
+ -> Maybe (Int,Int) -- Just (i,n) <=> module i of n (for msgs)
+ -> IO (Maybe result)
+
+
+-- This functions checks if recompilation is necessary and
+-- then combines the FrontEnd, BackEnd and CodeGen to a
+-- working compiler.
+hscMkCompiler :: NoRecomp result -- What to do when recompilation isn't required.
+ -> FrontEnd core
+ -> BackEnd core prepCore
+ -> CodeGen prepCore result
+ -> Compiler result
+hscMkCompiler norecomp frontend backend codegen
+ hsc_env mod_summary source_unchanged
+ have_object mbOldIface mbModIndex
+ = do (recomp_reqd, mbCheckedIface)
+ <- {-# SCC "checkOldIface" #-}
+ checkOldIface hsc_env mod_summary
+ source_unchanged mbOldIface
+ case mbCheckedIface of
+ Just iface | not recomp_reqd
+ -> do result <- norecomp hsc_env mod_summary have_object iface mbModIndex
+ return (Just result)
+ _otherwise
+ -> do mbCore <- frontend hsc_env mod_summary mbModIndex
+ case mbCore of
+ Nothing
+ -> return Nothing
+ Just core
+ -> do prepCore <- backend hsc_env mod_summary
+ mbCheckedIface core
+ result <- codegen hsc_env mod_summary prepCore
+ return (Just result)
+
+--------------------------------------------------------------
+-- Compilers
+--------------------------------------------------------------
+
+-- Compile Haskell, boot and extCore in OneShot mode.
+hscCompileOneShot :: Compiler HscStatus
+hscCompileOneShot hsc_env mod_summary =
+ compiler hsc_env mod_summary
+ where mkComp = hscMkCompiler (norecompOneShot HscNoRecomp)
+ compiler
+ = case ms_hsc_src mod_summary of
+ ExtCoreFile
+ -> mkComp hscCoreFrontEnd hscNewBackEnd hscCodeGenOneShot
+-- 1 2 3 4 5 6 7 8 9
+ HsSrcFile
+ -> mkComp hscFileFrontEnd hscNewBackEnd hscCodeGenOneShot
+ HsBootFile
+ -> mkComp hscFileFrontEnd hscNewBootBackEnd
+ (hscCodeGenConst (HscRecomp False))
+
+-- Compile Haskell, boot and extCore in --make mode.
+hscCompileMake :: Compiler (HscStatus, ModIface, ModDetails)
+hscCompileMake hsc_env mod_summary
+ = compiler hsc_env mod_summary
+ where mkComp = hscMkCompiler norecompMake
+ backend = case hscTarget (hsc_dflags hsc_env) of
+ HscNothing -> hscCodeGenNothing
+ _other -> hscCodeGenMake
+ compiler
+ = case ms_hsc_src mod_summary of
+ ExtCoreFile
+ -> mkComp hscCoreFrontEnd hscNewBackEnd backend
+ HsSrcFile
+ -> mkComp hscFileFrontEnd hscNewBackEnd backend
+ HsBootFile
+ -> mkComp hscFileFrontEnd hscNewBootBackEnd hscCodeGenIdentity
+
+
+-- Compile Haskell, extCore to bytecode.
+hscCompileInteractive :: Compiler (InteractiveStatus, ModIface, ModDetails)
+hscCompileInteractive hsc_env mod_summary =
+ hscMkCompiler norecompInteractive frontend hscNewBackEnd hscCodeGenInteractive
+ hsc_env mod_summary
+ where frontend = case ms_hsc_src mod_summary of
+ ExtCoreFile -> hscCoreFrontEnd
+ HsSrcFile -> hscFileFrontEnd
+ HsBootFile -> panic bootErrorMsg
+ bootErrorMsg = "Compiling a HsBootFile to bytecode doesn't make sense. " ++
+ "Use 'hscCompileMake' instead."
+
+--------------------------------------------------------------
+-- NoRecomp handlers
+--------------------------------------------------------------
+
+norecompOneShot :: a -> NoRecomp a
+norecompOneShot a hsc_env mod_summary
+ have_object old_iface
+ mb_mod_index
+ = do compilationProgressMsg (hsc_dflags hsc_env) $
+ "compilation IS NOT required"
+ dumpIfaceStats hsc_env
+ return a
+
+norecompMake :: NoRecomp (HscStatus, ModIface, ModDetails)
+norecompMake = norecompWorker HscNoRecomp
+
+norecompInteractive :: NoRecomp (InteractiveStatus, ModIface, ModDetails)
+norecompInteractive = norecompWorker InteractiveNoRecomp
+
+norecompWorker :: a -> NoRecomp (a, ModIface, ModDetails)
+norecompWorker a hsc_env mod_summary have_object
+ old_iface mb_mod_index
+ = do compilationProgressMsg (hsc_dflags hsc_env) $
+ (showModuleIndex mb_mod_index ++
+ "Skipping " ++ showModMsg have_object mod_summary)
+ new_details <- {-# SCC "tcRnIface" #-}
+ initIfaceCheck hsc_env $
+ typecheckIface old_iface
+ dumpIfaceStats hsc_env
+ return (a, old_iface, new_details)
+
+--------------------------------------------------------------
+-- FrontEnds
+--------------------------------------------------------------
+
+hscCoreFrontEnd :: FrontEnd ModGuts
+hscCoreFrontEnd hsc_env mod_summary mb_mod_index = do {
+ -------------------
+ -- PARSE
+ -------------------
+ ; inp <- readFile (expectJust "hscCoreFrontEnd" (ms_hspp_file mod_summary))
+ ; case parseCore inp 1 of
+ FailP s -> do errorMsg (hsc_dflags hsc_env) (text s{-ToDo: wrong-})
+ return Nothing
+ OkP rdr_module -> do {
+
+ -------------------
+ -- RENAME and TYPECHECK
+ -------------------
+ ; (tc_msgs, maybe_tc_result) <- {-# SCC "TypeCheck" #-}
+ tcRnExtCore hsc_env rdr_module
+ ; printErrorsAndWarnings (hsc_dflags hsc_env) tc_msgs
+ ; case maybe_tc_result of
+ Nothing -> return Nothing
+ Just mod_guts -> return (Just mod_guts) -- No desugaring to do!
+ }}
+
+hscFileFrontEnd :: FrontEnd ModGuts
+hscFileFrontEnd hsc_env mod_summary mb_mod_index = do {
+ -------------------
+ -- DISPLAY PROGRESS MESSAGE
+ -------------------
+ ; let dflags = hsc_dflags hsc_env
+ one_shot = isOneShot (ghcMode dflags)
+ toInterp = hscTarget dflags == HscInterpreted
+ ; when (not one_shot) $
+ compilationProgressMsg dflags $
+ (showModuleIndex mb_mod_index ++
+ "Compiling " ++ showModMsg (not toInterp) mod_summary)
+
+ -------------------
+ -- PARSE
+ -------------------
+ ; let hspp_file = expectJust "hscFileFrontEnd" (ms_hspp_file mod_summary)
+ hspp_buf = ms_hspp_buf mod_summary
+
+ ; maybe_parsed <- myParseModule dflags hspp_file hspp_buf
+
+ ; case maybe_parsed of {
+ Left err -> do { printBagOfErrors dflags (unitBag err)
+ ; return Nothing } ;
+ Right rdr_module -> do {
+
+ -------------------
+ -- RENAME and TYPECHECK
+ -------------------
+ (tc_msgs, maybe_tc_result)
+ <- {-# SCC "Typecheck-Rename" #-}
+ tcRnModule hsc_env (ms_hsc_src mod_summary) False rdr_module
+
+ ; printErrorsAndWarnings dflags tc_msgs
+ ; case maybe_tc_result of {
+ Nothing -> return Nothing ;
+ Just tc_result -> do {
+
+ -------------------
+ -- DESUGAR
+ -------------------
+ ; (warns, maybe_ds_result) <- {-# SCC "DeSugar" #-}
+ deSugar hsc_env tc_result
+ ; printBagOfWarnings dflags warns
+ ; return maybe_ds_result
+ }}}}}
+
+--------------------------------------------------------------
+-- BackEnds
+--------------------------------------------------------------
+
+hscNewBootBackEnd :: BackEnd ModGuts (HscStatus, ModIface, ModDetails)
+hscNewBootBackEnd hsc_env mod_summary maybe_old_iface ds_result
+ = do details <- mkBootModDetails hsc_env ds_result
+ (new_iface, no_change)
+ <- {-# SCC "MkFinalIface" #-}
+ mkIface hsc_env maybe_old_iface ds_result details
+ writeIfaceFile hsc_env (ms_location mod_summary) new_iface no_change
+ -- And the answer is ...
+ dumpIfaceStats hsc_env
+ return (HscRecomp False, new_iface, details)
+
+hscNewBackEnd :: BackEnd ModGuts (ModIface, ModDetails, CgGuts)
+hscNewBackEnd hsc_env mod_summary maybe_old_iface ds_result
+ = do { -- OMITTED:
+ -- ; seqList imported_modules (return ())
+
+ let dflags = hsc_dflags hsc_env
+
+ -------------------
+ -- FLATTENING
+ -------------------
+ ; flat_result <- {-# SCC "Flattening" #-}
+ flatten hsc_env ds_result
+
+
+{- TEMP: need to review space-leak fixing here
+ NB: even the code generator can force one of the
+ thunks for constructor arguments, for newtypes in particular
+
+ ; let -- Rule-base accumulated from imported packages
+ pkg_rule_base = eps_rule_base (hsc_EPS hsc_env)
+
+ -- In one-shot mode, ZAP the external package state at
+ -- this point, because we aren't going to need it from
+ -- now on. We keep the name cache, however, because
+ -- tidyCore needs it.
+ pcs_middle
+ | one_shot = pcs_tc{ pcs_EPS = error "pcs_EPS missing" }
+ | otherwise = pcs_tc
+
+ ; pkg_rule_base `seq` pcs_middle `seq` return ()
+-}