summaryrefslogtreecommitdiff
path: root/compiler/GHC/Unit/External.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Unit/External.hs')
-rw-r--r--compiler/GHC/Unit/External.hs131
1 files changed, 131 insertions, 0 deletions
diff --git a/compiler/GHC/Unit/External.hs b/compiler/GHC/Unit/External.hs
new file mode 100644
index 0000000000..2ee6191ec9
--- /dev/null
+++ b/compiler/GHC/Unit/External.hs
@@ -0,0 +1,131 @@
+module GHC.Unit.External
+ ( ExternalPackageState (..)
+ , EpsStats(..)
+ , addEpsInStats
+ , PackageTypeEnv
+ , PackageIfaceTable
+ , PackageInstEnv
+ , PackageFamInstEnv
+ , PackageRuleBase
+ , PackageCompleteMatches
+ , emptyPackageIfaceTable
+ )
+where
+
+import GHC.Prelude
+
+import GHC.Unit
+import GHC.Unit.Module.ModIface
+
+import GHC.Core ( RuleBase )
+import GHC.Core.FamInstEnv
+import GHC.Core.InstEnv ( InstEnv )
+
+import GHC.Types.Annotations ( AnnEnv )
+import GHC.Types.CompleteMatch
+import GHC.Types.TypeEnv
+import GHC.Types.Unique.DSet
+
+
+type PackageTypeEnv = TypeEnv
+type PackageRuleBase = RuleBase
+type PackageInstEnv = InstEnv
+type PackageFamInstEnv = FamInstEnv
+type PackageAnnEnv = AnnEnv
+type PackageCompleteMatches = CompleteMatches
+
+-- | Helps us find information about modules in the imported packages
+type PackageIfaceTable = ModuleEnv ModIface
+ -- Domain = modules in the imported packages
+
+-- | Constructs an empty PackageIfaceTable
+emptyPackageIfaceTable :: PackageIfaceTable
+emptyPackageIfaceTable = emptyModuleEnv
+
+
+-- | Information about other packages that we have slurped in by reading
+-- their interface files
+data ExternalPackageState
+ = EPS {
+ eps_is_boot :: !(ModuleNameEnv ModuleNameWithIsBoot),
+ -- ^ In OneShot mode (only), home-package modules
+ -- accumulate in the external package state, and are
+ -- sucked in lazily. For these home-pkg modules
+ -- (only) we need to record which are boot modules.
+ -- We set this field after loading all the
+ -- explicitly-imported interfaces, but before doing
+ -- anything else
+ --
+ -- The 'ModuleName' part is not necessary, but it's useful for
+ -- debug prints, and it's convenient because this field comes
+ -- direct from 'GHC.Tc.Utils.imp_dep_mods'
+
+ eps_PIT :: !PackageIfaceTable,
+ -- ^ The 'ModIface's for modules in external packages
+ -- whose interfaces we have opened.
+ -- The declarations in these interface files are held in the
+ -- 'eps_decls', 'eps_inst_env', 'eps_fam_inst_env' and 'eps_rules'
+ -- fields of this record, not in the 'mi_decls' fields of the
+ -- interface we have sucked in.
+ --
+ -- What /is/ in the PIT is:
+ --
+ -- * The Module
+ --
+ -- * Fingerprint info
+ --
+ -- * Its exports
+ --
+ -- * Fixities
+ --
+ -- * Deprecations and warnings
+
+ eps_free_holes :: InstalledModuleEnv (UniqDSet ModuleName),
+ -- ^ Cache for 'mi_free_holes'. Ordinarily, we can rely on
+ -- the 'eps_PIT' for this information, EXCEPT that when
+ -- we do dependency analysis, we need to look at the
+ -- 'Dependencies' of our imports to determine what their
+ -- precise free holes are ('moduleFreeHolesPrecise'). We
+ -- don't want to repeatedly reread in the interface
+ -- for every import, so cache it here. When the PIT
+ -- gets filled in we can drop these entries.
+
+ eps_PTE :: !PackageTypeEnv,
+ -- ^ Result of typechecking all the external package
+ -- interface files we have sucked in. The domain of
+ -- the mapping is external-package modules
+
+ eps_inst_env :: !PackageInstEnv, -- ^ The total 'InstEnv' accumulated
+ -- from all the external-package modules
+ eps_fam_inst_env :: !PackageFamInstEnv,-- ^ The total 'FamInstEnv' accumulated
+ -- from all the external-package modules
+ eps_rule_base :: !PackageRuleBase, -- ^ The total 'RuleEnv' accumulated
+ -- from all the external-package modules
+ eps_ann_env :: !PackageAnnEnv, -- ^ The total 'AnnEnv' accumulated
+ -- from all the external-package modules
+ eps_complete_matches :: !PackageCompleteMatches,
+ -- ^ The total 'CompleteMatches' accumulated
+ -- from all the external-package modules
+
+ eps_mod_fam_inst_env :: !(ModuleEnv FamInstEnv), -- ^ The family instances accumulated from external
+ -- packages, keyed off the module that declared them
+
+ eps_stats :: !EpsStats -- ^ Stastics about what was loaded from external packages
+ }
+
+-- | Accumulated statistics about what we are putting into the 'ExternalPackageState'.
+-- \"In\" means stuff that is just /read/ from interface files,
+-- \"Out\" means actually sucked in and type-checked
+data EpsStats = EpsStats { n_ifaces_in
+ , n_decls_in, n_decls_out
+ , n_rules_in, n_rules_out
+ , n_insts_in, n_insts_out :: !Int }
+
+addEpsInStats :: EpsStats -> Int -> Int -> Int -> EpsStats
+-- ^ Add stats for one newly-read interface
+addEpsInStats stats n_decls n_insts n_rules
+ = stats { n_ifaces_in = n_ifaces_in stats + 1
+ , n_decls_in = n_decls_in stats + n_decls
+ , n_insts_in = n_insts_in stats + n_insts
+ , n_rules_in = n_rules_in stats + n_rules }
+