{-# LANGUAGE OverloadedStrings #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  HumblePrelude.Plugin
-- Copyright   :  (c) Fumiaki Kinoshita 2020
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  fumiexcel@gmail.com
-- Stability   :  experimental
-- Portability :  portable
--
-- GHC plugin which adds imports to specified modules
--
-----------------------------------------------------------------------------
module HumblePrelude.Plugin (plugin) where

import HumblePrelude
import GhcPlugins hiding ((<>))
import HsSyn (hsmodImports, simpleImportDecl)

-- | @Usage: -fplugin=HumblePrelude.Plugin@
plugin :: Plugin
plugin :: Plugin
plugin = Plugin
defaultPlugin
  { parsedResultAction :: [CommandLineOption]
-> ModSummary -> HsParsedModule -> Hsc HsParsedModule
parsedResultAction = [CommandLineOption]
-> ModSummary -> HsParsedModule -> Hsc HsParsedModule
parsedPlugin
  , pluginRecompile :: [CommandLineOption] -> IO PluginRecompile
pluginRecompile = [CommandLineOption] -> IO PluginRecompile
flagRecompile }

parsedPlugin :: [CommandLineOption] -> ModSummary -> HsParsedModule -> Hsc HsParsedModule
parsedPlugin :: [CommandLineOption]
-> ModSummary -> HsParsedModule -> Hsc HsParsedModule
parsedPlugin [] ms :: ModSummary
ms hpm :: HsParsedModule
hpm = [CommandLineOption]
-> ModSummary -> HsParsedModule -> Hsc HsParsedModule
parsedPlugin ["HumblePrelude.Extras"] ModSummary
ms HsParsedModule
hpm
parsedPlugin mods :: [CommandLineOption]
mods _ pm :: HsParsedModule
pm = do
  let rep :: [LImportDecl GhcPs]
rep = ImportDecl GhcPs -> LImportDecl GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (ImportDecl GhcPs -> LImportDecl GhcPs)
-> (CommandLineOption -> ImportDecl GhcPs)
-> CommandLineOption
-> LImportDecl GhcPs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModuleName -> ImportDecl GhcPs
forall (p :: Pass). ModuleName -> ImportDecl (GhcPass p)
simpleImportDecl (ModuleName -> ImportDecl GhcPs)
-> (CommandLineOption -> ModuleName)
-> CommandLineOption
-> ImportDecl GhcPs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandLineOption -> ModuleName
mkModuleName (CommandLineOption -> LImportDecl GhcPs)
-> [CommandLineOption] -> [LImportDecl GhcPs]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [CommandLineOption]
mods
  HsParsedModule -> Hsc HsParsedModule
forall (f :: * -> *) a. Applicative f => a -> f a
pure HsParsedModule
pm { hpm_module :: Located (HsModule GhcPs)
hpm_module = (HsModule GhcPs -> HsModule GhcPs)
-> Located (HsModule GhcPs) -> Located (HsModule GhcPs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\m :: HsModule GhcPs
m -> HsModule GhcPs
m { hsmodImports :: [LImportDecl GhcPs]
hsmodImports = [LImportDecl GhcPs]
rep [LImportDecl GhcPs] -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
forall a. Semigroup a => a -> a -> a
<> HsModule GhcPs -> [LImportDecl GhcPs]
forall pass. HsModule pass -> [LImportDecl pass]
hsmodImports HsModule GhcPs
m }) (Located (HsModule GhcPs) -> Located (HsModule GhcPs))
-> Located (HsModule GhcPs) -> Located (HsModule GhcPs)
forall a b. (a -> b) -> a -> b
$ HsParsedModule -> Located (HsModule GhcPs)
hpm_module HsParsedModule
pm }