summaryrefslogtreecommitdiff
path: root/compiler/main/DynamicLoading.hs
diff options
context:
space:
mode:
authorAdam Gundry <adam@well-typed.com>2014-11-20 13:32:26 +0000
committerAdam Gundry <adam@well-typed.com>2014-11-20 16:54:44 +0000
commit64cb49686457c233d0f58e5cfa324ad28a5453a3 (patch)
tree7037ca2fa8ad2702b1f2e73b7f3598a790afded4 /compiler/main/DynamicLoading.hs
parentcce6318e8fdb086a8501a0c81ae1ee02eed67835 (diff)
downloadhaskell-64cb49686457c233d0f58e5cfa324ad28a5453a3.tar.gz
Implement typechecker plugins
Summary: See https://ghc.haskell.org/trac/ghc/wiki/Plugins/TypeChecker This is based on work by Iavor Diatchki and Eric Seidel. Test Plan: validate Reviewers: simonpj, austin Reviewed By: austin Subscribers: gridaphobe, yav, thomie, carter Differential Revision: https://phabricator.haskell.org/D489 Conflicts: docs/users_guide/7.10.1-notes.xml
Diffstat (limited to 'compiler/main/DynamicLoading.hs')
-rw-r--r--compiler/main/DynamicLoading.hs49
1 files changed, 47 insertions, 2 deletions
diff --git a/compiler/main/DynamicLoading.hs b/compiler/main/DynamicLoading.hs
index 046d13cee5..95321cfb79 100644
--- a/compiler/main/DynamicLoading.hs
+++ b/compiler/main/DynamicLoading.hs
@@ -3,6 +3,9 @@
-- | Dynamically lookup up values from modules and loading them.
module DynamicLoading (
#ifdef GHCI
+ -- * Loading plugins
+ loadPlugins,
+
-- * Force loading information
forceLoadModuleInterfaces,
forceLoadNameModuleInterface,
@@ -25,13 +28,17 @@ import Finder ( findImportedModule, cannotFindModule )
import TcRnMonad ( initTcInteractive, initIfaceTcRn )
import LoadIface ( loadPluginInterface )
import RdrName ( RdrName, Provenance(..), ImportSpec(..), ImpDeclSpec(..)
- , ImpItemSpec(..), mkGlobalRdrEnv, lookupGRE_RdrName, gre_name )
+ , ImpItemSpec(..), mkGlobalRdrEnv, lookupGRE_RdrName
+ , gre_name, mkRdrQual )
+import OccName ( mkVarOcc )
import RnNames ( gresFromAvails )
import DynFlags
+import Plugins ( Plugin, CommandLineOption )
+import PrelNames ( pluginTyConName )
import HscTypes
import BasicTypes ( HValue )
-import TypeRep ( pprTyThingCategory )
+import TypeRep ( mkTyConTy, pprTyThingCategory )
import Type ( Type, eqType )
import TyCon ( TyCon )
import Name ( Name, nameModule_maybe )
@@ -48,6 +55,44 @@ import Data.Maybe ( mapMaybe )
import GHC.Exts ( unsafeCoerce# )
+loadPlugins :: HscEnv -> IO [(ModuleName, Plugin, [CommandLineOption])]
+loadPlugins hsc_env
+ = do { plugins <- mapM (loadPlugin hsc_env) to_load
+ ; return $ map attachOptions $ to_load `zip` plugins }
+ where
+ dflags = hsc_dflags hsc_env
+ to_load = pluginModNames dflags
+
+ attachOptions (mod_nm, plug) = (mod_nm, plug, options)
+ where
+ options = [ option | (opt_mod_nm, option) <- pluginModNameOpts dflags
+ , opt_mod_nm == mod_nm ]
+
+loadPlugin :: HscEnv -> ModuleName -> IO Plugin
+loadPlugin hsc_env mod_name
+ = do { let plugin_rdr_name = mkRdrQual mod_name (mkVarOcc "plugin")
+ dflags = hsc_dflags hsc_env
+ ; mb_name <- lookupRdrNameInModuleForPlugins hsc_env mod_name
+ plugin_rdr_name
+ ; case mb_name of {
+ Nothing ->
+ throwGhcExceptionIO (CmdLineError $ showSDoc dflags $ hsep
+ [ ptext (sLit "The module"), ppr mod_name
+ , ptext (sLit "did not export the plugin name")
+ , ppr plugin_rdr_name ]) ;
+ Just name ->
+
+ do { plugin_tycon <- forceLoadTyCon hsc_env pluginTyConName
+ ; mb_plugin <- getValueSafely hsc_env name (mkTyConTy plugin_tycon)
+ ; case mb_plugin of
+ Nothing ->
+ throwGhcExceptionIO (CmdLineError $ showSDoc dflags $ hsep
+ [ ptext (sLit "The value"), ppr name
+ , ptext (sLit "did not have the type")
+ , ppr pluginTyConName, ptext (sLit "as required")])
+ Just plugin -> return plugin } } }
+
+
-- | Force the interfaces for the given modules to be loaded. The 'SDoc' parameter is used
-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded.
forceLoadModuleInterfaces :: HscEnv -> SDoc -> [Module] -> IO ()