
Hi all, The plugin mechanism gives access to the program in Core; this suffices for many but not quite all purposes. Tools that need access to the original AST can call typecheckModule directly, but of course this requires using the GHC API directly. Moreover, even when using the GHC API directly anyway (as in my case), it means that tools cannot take advantage of ghc's infrastructure for dependency tracking, recompiling only changed modules, etc. Hence it would be useful to have "source plugins", which can be used both externally and when using ghc API (in the latter case I guess "hooks" would be the more appropriate terminology). Currently "core plugins" are recorded as part of DynFlags as pluginModNames :: [ModuleName], pluginModNameOpts :: [(ModuleName,String)], This makes sense when thinking of plugins only as an external mechanism, but is less convenient when using them as internal hooks, too. In my draft patch I introduce a new type "HscPlugin" (described shortly) and added sourcePlugins :: [HscPlugin], to DynFlags. HscPlugin is a record of a pair of functions; having the actual record here rather than a module name means that these functions can have a non-empty closure, which is obviously convenient when using this as a hook rather than an external plugin. In my current version HscPlugin looks like data HscPlugin = HscPlugin { runHscPlugin :: forall m. MonadIO m => DynFlags -> TcGblEnv -> m TcGblEnv , runHscQQ :: forall m. MonadIO m => Env TcGblEnv TcLclEnv -> HsQuasiQuote Name -> m (HsQuasiQuote Name) } runHscPlugin is the main function; it gets passed the TcGblEnv (which contains the type checked AST as its tcd_binds field).