- -> RnMG (Maybe (ExportEnv, RnEnv, NameSet))
- -- Nothing <=> no need to recompile
- -- The NameSet is the set of names that are
- -- either locally defined,
- -- or explicitly imported
-
-getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
- = fixRn (\ ~(rec_exp_fn, _) ->
-
- -- PROCESS LOCAL DECLS
- -- Do these *first* so that the correct provenance gets
- -- into the global name cache.
- importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_avails) ->
-
- -- PROCESS IMPORT DECLS
- mapAndUnzip3Rn importsFromImportDecl all_imports
- `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
-
- -- CHECK FOR EARLY EXIT
- checkEarlyExit this_mod `thenRn` \ early_exit ->
- if early_exit then
- returnRn (junk_exp_fn, Nothing)
- else
-
- -- COMBINE RESULTS
- -- We put the local env first, so that a local provenance
- -- "wins", even if a module imports itself.
- foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
- plusRnEnv local_rn_env imp_rn_env `thenRn` \ rn_env ->
- let
- all_avails :: ModuleAvails
- all_avails = foldr plusModuleAvails local_mod_avails imp_avails_s
-
- explicit_names :: NameSet -- locally defined or explicitly imported
- explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
- add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
- in
-
- -- PROCESS EXPORT LISTS
- exportsFromAvail this_mod exports all_avails rn_env
- `thenRn` \ (export_fn, export_env) ->
-
- -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
- mapRn (recordSlurp Nothing Compulsory) local_avails `thenRn_`
-
- returnRn (export_fn, Just (export_env, rn_env, explicit_names))
- ) `thenRn` \ (_, result) ->
- returnRn result
- where
- junk_exp_fn = error "RnNames:export_fn"
+ -> RnMG (Maybe (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
+ ))
+ -- Nothing => no need to recompile
+
+getGlobalNames (HsModule this_mod _ exports imports decls _ mod_loc)
+ = -- These two fix-loops are to get the right
+ -- provenance information into a Name
+ fixRn ( \ ~(Just (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
+ let
+ (source, ordinary) = partition is_source_import all_imports
+ is_source_import (ImportDecl _ ImportByUserSource _ _ _ _) = True
+ is_source_import other = False
+ in
+ mapAndUnzipRn (importsFromImportDecl rec_unqual_fn) ordinary
+ `thenRn` \ (imp_gbl_envs1, imp_avails_s1) ->
+ mapAndUnzipRn (importsFromImportDecl rec_unqual_fn) 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