+\begin{code}
+getGlobalNames :: Module -> RdrNameHsModule
+ -> RnMG (GlobalRdrEnv, -- Maps all in-scope things
+ GlobalRdrEnv, -- Maps just *local* things
+ Avails, -- The exported stuff
+ AvailEnv) -- Maps a name to its parent AvailInfo
+ -- Just for in-scope things only
+
+getGlobalNames this_mod (HsModule _ _ exports imports decls _ mod_loc)
+ = -- These two fix-loops are to get the right
+ -- provenance information into a Name
+ fixRn ( \ ~(rec_gbl_env, _, rec_export_avails, _) ->
+
+ let
+ rec_unqual_fn :: Name -> Bool -- Is this chap in scope unqualified?
+ rec_unqual_fn = unQualInScope rec_gbl_env
+
+ rec_exp_fn :: Name -> Bool
+ rec_exp_fn = mk_export_fn (availsToNameSet rec_export_avails)
+ in
+
+ -- PROCESS LOCAL DECLS
+ -- Do these *first* so that the correct provenance gets
+ -- into the global name cache.
+ importsFromLocalDecls this_mod rec_exp_fn decls `thenRn` \ (local_gbl_env, local_mod_avails) ->
+
+ -- PROCESS IMPORT DECLS
+ -- Do the non {- SOURCE -} ones first, so that we get a helpful
+ -- warning for {- SOURCE -} ones that are unnecessary
+ doptRn Opt_NoImplicitPrelude `thenRn` \ opt_no_prelude ->
+ let
+ all_imports = mk_prel_imports opt_no_prelude ++ imports
+ (source, ordinary) = partition is_source_import all_imports
+ is_source_import (ImportDecl _ ImportByUserSource _ _ _ _) = True
+ is_source_import other = False
+
+ get_imports = importsFromImportDecl this_mod_name rec_unqual_fn
+ in
+ mapAndUnzipRn get_imports ordinary `thenRn` \ (imp_gbl_envs1, imp_avails_s1) ->
+ mapAndUnzipRn get_imports source `thenRn` \ (imp_gbl_envs2, imp_avails_s2) ->
+
+ -- COMBINE RESULTS
+ -- We put the local env second, so that a local provenance
+ -- "wins", even if a module imports itself.
+ let
+ gbl_env :: GlobalRdrEnv
+ imp_gbl_env = foldr plusGlobalRdrEnv emptyRdrEnv (imp_gbl_envs2 ++ imp_gbl_envs1)
+ gbl_env = imp_gbl_env `plusGlobalRdrEnv` local_gbl_env
+
+ all_avails :: ExportAvails
+ all_avails = foldr plusExportAvails local_mod_avails (imp_avails_s2 ++ imp_avails_s1)
+
+ (_, global_avail_env) = all_avails
+ in
+
+ -- PROCESS EXPORT LIST (but not if we've had errors already)
+ checkErrsRn `thenRn` \ no_errs_so_far ->
+ (if no_errs_so_far then
+ exportsFromAvail this_mod_name exports all_avails gbl_env
+ else
+ returnRn []
+ ) `thenRn` \ export_avails ->
+
+ -- ALL DONE
+ returnRn (gbl_env, local_gbl_env, export_avails, global_avail_env)
+ )
+ where
+ this_mod_name = moduleName this_mod
+
+ -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
+ -- because the former doesn't even look at Prelude.hi for instance declarations,
+ -- whereas the latter does.
+ mk_prel_imports no_prelude
+ | this_mod_name == pRELUDE_Name ||
+ explicit_prelude_import ||
+ no_prelude
+ = []
+
+ | otherwise = [ImportDecl pRELUDE_Name
+ ImportByUser
+ False {- Not qualified -}
+ Nothing {- No "as" -}
+ Nothing {- No import list -}
+ mod_loc]
+
+ explicit_prelude_import
+ = not (null [ () | (ImportDecl mod _ _ _ _ _) <- imports, mod == pRELUDE_Name ])
+\end{code}
+
+\begin{code}
+importsFromImportDecl :: ModuleName
+ -> (Name -> Bool) -- OK to omit qualifier
+ -> RdrNameImportDecl
+ -> RnMG (GlobalRdrEnv,
+ ExportAvails)
+
+importsFromImportDecl this_mod_name is_unqual (ImportDecl imp_mod_name from qual_only as_mod import_spec iloc)
+ = pushSrcLocRn iloc $
+ getInterfaceExports imp_mod_name from `thenRn` \ (imp_mod, avails_by_module) ->
+
+ if null avails_by_module then
+ -- If there's an error in getInterfaceExports, (e.g. interface
+ -- file not found) we get lots of spurious errors from 'filterImports'
+ returnRn (emptyRdrEnv, mkEmptyExportAvails imp_mod_name)
+ else