overloaded-0.3.1: src/Overloaded/Plugin/TcPlugin.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
module Overloaded.Plugin.TcPlugin (
tcPlugin,
) where
import Data.Maybe (mapMaybe)
import qualified GHC.Compat.All as GHC
#if MIN_VERSION_ghc(9,0,0)
import qualified GHC.Tc.Plugin as Plugins
#else
import qualified TcPluginM as Plugins
#endif
import Overloaded.Plugin.TcPlugin.Ctx
import Overloaded.Plugin.HasField
import Overloaded.Plugin.HasConstructor
-- TODO: take argument which options to enable.
tcPlugin :: GHC.TcPlugin
tcPlugin = GHC.TcPlugin
{ GHC.tcPluginInit = tcPluginInit
, GHC.tcPluginSolve = tcPluginSolve
, GHC.tcPluginStop = const (return ())
}
-- HasPolyField "petName" Pet Pet [Char] [Char]
tcPluginSolve :: PluginCtx -> GHC.TcPluginSolver
tcPluginSolve ctx _ _ wanteds = do
-- acquire context
dflags <- Plugins.unsafeTcPluginTcM GHC.getDynFlags
famInstEnvs <- Plugins.getFamInstEnvs
rdrEnv <- Plugins.unsafeTcPluginTcM GHC.getGlobalRdrEnv
solvedHasField <- solveHasField ctx dflags famInstEnvs rdrEnv wanteds
solvedHasConstructor <- solveHasConstructor ctx dflags famInstEnvs rdrEnv wanteds
let solved = solvedHasField ++ solvedHasConstructor
return $ GHC.TcPluginOk (mapMaybe extractA solved) (concat $ mapMaybe extractB solved)
where
extractA (Nothing, _) = Nothing
extractA (Just (a, _), b) = Just (a, b)
extractB (Nothing, _) = Nothing
extractB (Just (_, ct), _) = Just ct