<div dir="ltr">Uuuuuh. I&#39;m sorry, I don&#39;t know why that email got sent, I was still writing it. Please ignore it for now, will send the full version later :)</div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, Jun 5, 2013 at 12:14 PM, Edsko de Vries <span dir="ltr">&lt;<a href="mailto:edskodevries@gmail.com" target="_blank">edskodevries@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<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>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><br></div><div><div><font face="courier new, monospace">    sourcePlugins         :: [HscPlugin],</font></div><div><br></div></div><div>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><br></div><div>In my current version HscPlugin looks like</div><div><br></div><div><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>runHscPlugin is the main function; it gets passed the TcGblEnv (which contains the type checked AST as its tcd_binds field).</div><div><br></div></div>
</blockquote></div><br></div>