summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2011-08-02 08:18:03 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2011-08-02 08:18:03 +0100
commit35d213abfe27502fa34b60975c4b18ed51bfeb05 (patch)
treeaab2a30ab9acbf6ab2bc51366530027eab13b8ad /compiler/main
parent6059755e045ed8c4a8c3d48cc0ec5733bd950c0f (diff)
downloadhaskell-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.hs2
-rw-r--r--compiler/main/HeaderInfo.hs22
-rw-r--r--compiler/main/HscMain.lhs4
-rw-r--r--compiler/main/HscStats.lhs3
-rw-r--r--compiler/main/HscTypes.lhs29
-rw-r--r--compiler/main/InteractiveEval.hs53
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.