diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2011-08-02 08:18:03 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2011-08-02 08:18:03 +0100 |
commit | 35d213abfe27502fa34b60975c4b18ed51bfeb05 (patch) | |
tree | aab2a30ab9acbf6ab2bc51366530027eab13b8ad /compiler/main | |
parent | 6059755e045ed8c4a8c3d48cc0ec5733bd950c0f (diff) | |
download | haskell-35d213abfe27502fa34b60975c4b18ed51bfeb05.tar.gz |
Refactor the imports of InteractiveContext
Instead of two fields
ic_toplev_scope :: [Module]
ic_imports :: [ImportDecl RdrName]
we now just have one
ic_imports :: [InteractiveImport]
with the auxiliary data type
data InteractiveImport
= IIDecl (ImportDecl RdrName) -- Bring the exports of a particular module
-- (filtered by an import decl) into scope
| IIModule Module -- Bring into scope the entire top-level envt of
-- of this module, including the things imported
-- into it.
This makes lots of code less confusing. No change in behaviour.
It's preparatory to fixing Trac #5147.
While I was at I also
* Cleaned up the handling of the "implicit" Prelude import
by adding a ideclImplicit field to ImportDecl. This
significantly reduces plumbing in the handling of
the implicit Prelude import
* Used record notation consistently for ImportDecl
Diffstat (limited to 'compiler/main')
-rw-r--r-- | compiler/main/GHC.hs | 2 | ||||
-rw-r--r-- | compiler/main/HeaderInfo.hs | 22 | ||||
-rw-r--r-- | compiler/main/HscMain.lhs | 4 | ||||
-rw-r--r-- | compiler/main/HscStats.lhs | 3 | ||||
-rw-r--r-- | compiler/main/HscTypes.lhs | 29 | ||||
-rw-r--r-- | compiler/main/InteractiveEval.hs | 53 |
6 files changed, 63 insertions, 50 deletions
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs index 3ebfd52bad..c7b7687023 100644 --- a/compiler/main/GHC.hs +++ b/compiler/main/GHC.hs @@ -38,7 +38,7 @@ module GHC ( -- * Loading\/compiling the program depanal, - load, LoadHowMuch(..), + load, LoadHowMuch(..), InteractiveImport(..), SuccessFlag(..), succeeded, failed, defaultWarnErrLogger, WarnErrLogger, workingDirectoryChanged, diff --git a/compiler/main/HeaderInfo.hs b/compiler/main/HeaderInfo.hs index c7a281cff8..a3f7e79dde 100644 --- a/compiler/main/HeaderInfo.hs +++ b/compiler/main/HeaderInfo.hs @@ -100,19 +100,21 @@ mkPrelImports this_mod loc implicit_prelude import_decls | otherwise = [preludeImportDecl] where explicit_prelude_import - = notNull [ () | L _ (ImportDecl mod Nothing _ _ _ _ _) <- import_decls, - unLoc mod == pRELUDE_NAME ] + = notNull [ () | L _ (ImportDecl { ideclName = mod + , ideclPkgQual = Nothing }) + <- import_decls + , unLoc mod == pRELUDE_NAME ] preludeImportDecl :: LImportDecl RdrName preludeImportDecl - = L loc $ - ImportDecl (L loc pRELUDE_NAME) - Nothing {- No specific package -} - False {- Not a boot interface -} - False {- Not a safe import -} - False {- Not qualified -} - Nothing {- No "as" -} - Nothing {- No import list -} + = L loc $ ImportDecl { ideclName = L loc pRELUDE_NAME, + ideclPkgQual = Nothing, + ideclSource = False, + ideclSafe = False, -- Not a safe import + ideclQualified = False, + ideclImplicit = True, -- Implicit! + ideclAs = Nothing, + ideclHiding = Nothing } parseError :: SrcSpan -> Message -> IO a parseError span err = throwOneError $ mkPlainErrMsg span err diff --git a/compiler/main/HscMain.lhs b/compiler/main/HscMain.lhs index 2603d21bc4..ff52d2de76 100644 --- a/compiler/main/HscMain.lhs +++ b/compiler/main/HscMain.lhs @@ -312,9 +312,7 @@ hscRnImportDecls hsc_env this_mod import_decls = runHsc hsc_env $ ioMsgMaybe $ initTc hsc_env HsSrcFile False this_mod $ fmap tcg_rdr_env $ - tcRnImports hsc_env this_mod loc import_decls - where - loc = mkGeneralSrcSpan (mkFastString "In a call to hscRnImportDecls") + tcRnImports hsc_env this_mod import_decls #endif -- ----------------------------------------------------------------------------- diff --git a/compiler/main/HscStats.lhs b/compiler/main/HscStats.lhs index 76699a5f85..34310e038c 100644 --- a/compiler/main/HscStats.lhs +++ b/compiler/main/HscStats.lhs @@ -123,7 +123,8 @@ ppSourceStats short (L _ (HsModule _ exports imports ldecls _ _)) sig_info (GenericSig _ _) = (0,0,0,0,1) sig_info _ = (0,0,0,0,0) - import_info (L _ (ImportDecl _ _ _ safe qual as spec)) + import_info (L _ (ImportDecl { ideclSafe = safe, ideclQualified = qual + , ideclAs = as, ideclHiding = spec })) = add7 (1, safe_info safe, qual_info qual, as_info as, 0,0,0) (spec_info spec) safe_info = qual_info qual_info False = 0 diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs index d43105b02d..436feb0094 100644 --- a/compiler/main/HscTypes.lhs +++ b/compiler/main/HscTypes.lhs @@ -42,6 +42,7 @@ module HscTypes ( -- * Interactive context InteractiveContext(..), emptyInteractiveContext, + InteractiveImport(..), icPrintUnqual, extendInteractiveContext, substInteractiveContext, mkPrintUnqualified, pprModulePrefix, @@ -883,15 +884,12 @@ emptyModIface mod -- data InteractiveContext = InteractiveContext { - -- These two fields are only stored here so that the client - -- can retrieve them with GHC.getContext. GHC itself doesn't - -- use them, but it does reset them to empty sometimes (such + -- This field is only stored here so that the client + -- can retrieve it with GHC.getContext. GHC itself doesn't + -- use it, but does reset it to empty sometimes (such -- as before a GHC.load). The context is set with GHC.setContext. - ic_toplev_scope :: [Module], - -- ^ The context includes the "top-level" scope of - -- these modules - ic_imports :: [ImportDecl RdrName], - -- ^ The context is extended with these import declarations + ic_imports :: [InteractiveImport], + -- ^ The GHCi context is extended with these imports ic_rn_gbl_env :: GlobalRdrEnv, -- ^ The contexts' cached 'GlobalRdrEnv', built by @@ -914,11 +912,17 @@ data InteractiveContext -- virtual CWD of the program } +data InteractiveImport + = IIDecl (ImportDecl RdrName) -- Bring the exports of a particular module + -- (filtered by an import decl) into scope + | IIModule Module -- Bring into scope the entire top-level envt of + -- of this module, including the things imported + -- into it. + emptyInteractiveContext :: InteractiveContext emptyInteractiveContext - = InteractiveContext { ic_toplev_scope = [], - ic_imports = [], + = InteractiveContext { ic_imports = [], ic_rn_gbl_env = emptyGlobalRdrEnv, ic_tmp_ids = [] #ifdef GHCI @@ -948,6 +952,10 @@ substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst = ictxt { ic_tmp_ids = map subst_ty ids } where subst_ty id = id `setIdType` substTy subst (idType id) + +instance Outputable InteractiveImport where + ppr (IIModule m) = char '*' <> ppr m + ppr (IIDecl d) = ppr d \end{code} %************************************************************************ @@ -1675,6 +1683,7 @@ ms_imps ms = ms_textual_imps ms ++ map mk_additional_import (dynFlagDependencies ideclName = noLoc mod_nm, ideclPkgQual = Nothing, ideclSource = False, + ideclImplicit = True, -- Maybe implicit because not "in the program text" ideclQualified = False, ideclAs = Nothing, ideclHiding = Nothing, diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs index 0386273de8..24f340b33d 100644 --- a/compiler/main/InteractiveEval.hs +++ b/compiler/main/InteractiveEval.hs @@ -778,29 +778,32 @@ fromListBL bound l = BL (length l) bound l [] -- Setting the context doesn't throw away any bindings; the bindings -- we've built up in the InteractiveContext simply move to the new -- module. They always shadow anything in scope in the current context. -setContext :: GhcMonad m => - [Module] -- ^ entire top level scope of these modules - -> [ImportDecl RdrName] -- ^ these import declarations - -> m () -setContext toplev_mods import_decls = do - hsc_env <- getSession - let old_ic = hsc_IC hsc_env - hpt = hsc_HPT hsc_env - imprt_decls = map noLoc import_decls - -- - import_env <- - if null imprt_decls then return emptyGlobalRdrEnv else do - let this_mod | null toplev_mods = pRELUDE - | otherwise = head toplev_mods - liftIO $ hscRnImportDecls hsc_env this_mod imprt_decls - - toplev_envs <- liftIO $ mapM (mkTopLevEnv hpt) toplev_mods - - let all_env = foldr plusGlobalRdrEnv import_env toplev_envs - modifySession $ \_ -> - hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods, - ic_imports = import_decls, - ic_rn_gbl_env = all_env }} +setContext :: GhcMonad m => [InteractiveImport] -> m () +setContext imports + = do { hsc_env <- getSession + ; let old_ic = hsc_IC hsc_env + ; all_env <- liftIO $ findGlobalRdrEnv hsc_env imports + ; modifySession $ \_ -> + hsc_env{ hsc_IC = old_ic { ic_imports = imports + , ic_rn_gbl_env = all_env }}} + +findGlobalRdrEnv :: HscEnv -> [InteractiveImport] -> IO GlobalRdrEnv +-- Compute the GlobalRdrEnv for the interactive context +findGlobalRdrEnv hsc_env imports + = do { idecls_env <- hscRnImportDecls hsc_env this_mod idecls + -- This call also loads any orphan modules + ; imods_env <- mapM (mkTopLevEnv (hsc_HPT hsc_env)) imods + ; return (foldr plusGlobalRdrEnv idecls_env imods_env) } + where + idecls :: [LImportDecl RdrName] + idecls = [noLoc d | IIDecl d <- imports] + + imods :: [Module] + imods = [m | IIModule m <- imports] + + this_mod = case imods of + [] -> pRELUDE + (m:_) -> m availsToGlobalRdrEnv :: ModuleName -> [AvailInfo] -> GlobalRdrEnv availsToGlobalRdrEnv mod_name avails @@ -828,9 +831,9 @@ mkTopLevEnv hpt modl -- | Get the interactive evaluation context, consisting of a pair of the -- set of modules from which we take the full top-level scope, and the set -- of modules from which we take just the exports respectively. -getContext :: GhcMonad m => m ([Module],[ImportDecl RdrName]) +getContext :: GhcMonad m => m [InteractiveImport] getContext = withSession $ \HscEnv{ hsc_IC=ic } -> - return (ic_toplev_scope ic, ic_imports ic) + return (ic_imports ic) -- | Returns @True@ if the specified module is interpreted, and hence has -- its full top-level scope available. |