<div dir="ltr">Hi all,<br><br>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&#39;s infrastructure for dependency tracking, recompiling only changed modules, etc.<br>
<br>Hence it would be useful to have &quot;source plugins&quot;, which can be used both externally and when using ghc API (in the latter case I guess &quot;hooks&quot; would be the more appropriate terminology). Currently &quot;core plugins&quot; are recorded as part of DynFlags as<br>
<br><font face="courier new, monospace">    pluginModNames        :: [ModuleName],<br>    pluginModNameOpts     :: [(ModuleName,String)],<br></font><br><div style>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 &quot;HscPlugin&quot; (described shortly) and added</div>
<div style><br></div><div style><div><font face="courier new, monospace">    sourcePlugins         :: [HscPlugin],</font></div><div><br></div></div><div style>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.</div>
<div style><br></div><div style>In my current version HscPlugin looks like</div><div style><br></div><div style><div><font face="courier new, monospace">    data HscPlugin = HscPlugin {</font></div><div><font face="courier new, monospace">        runHscPlugin :: forall m. MonadIO m </font></div>
<div><font face="courier new, monospace">                     =&gt; DynFlags</font></div><div><font face="courier new, monospace">                     -&gt; TcGblEnv</font></div><div><font face="courier new, monospace">                     -&gt; m TcGblEnv</font></div>
<div><font face="courier new, monospace">    </font></div><div><font face="courier new, monospace">      , runHscQQ     :: forall m. MonadIO m </font></div><div><font face="courier new, monospace">                     =&gt; Env TcGblEnv TcLclEnv</font></div>
<div><font face="courier new, monospace">                     -&gt; HsQuasiQuote Name</font></div><div><font face="courier new, monospace">                     -&gt; m (HsQuasiQuote Name)</font></div><div><font face="courier new, monospace">      }</font></div>
<div><br></div></div><div style>runHscPlugin is the main function; it gets passed the TcGblEnv (which contains the type checked AST as its tcd_binds field).</div><div style><br></div></div>