{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}

module Imp where

import qualified Control.Monad as Monad
import qualified Control.Monad.Catch as Exception
import qualified Control.Monad.Trans.State as StateT
import qualified Data.Data as Data
import qualified Data.Map as Map
import qualified Data.Maybe as Maybe
import qualified Data.Set as Set
import qualified GHC.Hs as Hs
import qualified GHC.Plugins as Plugin
import qualified GHC.Types.PkgQual as PkgQual
import qualified Imp.Exception.ShowHelp as ShowHelp
import qualified Imp.Exception.ShowVersion as ShowVersion
import qualified Imp.Extra.Exception as Exception
import qualified Imp.Extra.HsModule as HsModule
import qualified Imp.Extra.HsParsedModule as HsParsedModule
import qualified Imp.Extra.ImportDecl as ImportDecl
import qualified Imp.Extra.Located as Located
import qualified Imp.Extra.ParsedResult as ParsedResult
import qualified Imp.Extra.SrcSpanAnnN as SrcSpanAnnN
import qualified Imp.Ghc as Ghc
import qualified Imp.Type.Config as Config
import qualified Imp.Type.Context as Context
import qualified Imp.Type.Flag as Flag
import qualified Imp.Type.PackageName as PackageName
import qualified Imp.Type.Source as Source
import qualified Imp.Type.Target as Target
import qualified System.Exit as Exit
import qualified System.IO as IO

plugin :: Plugin.Plugin
plugin :: Plugin
plugin =
  Plugin
Plugin.defaultPlugin
    { Plugin.parsedResultAction = parsedResultAction,
      Plugin.pluginRecompile = Plugin.purePlugin
    }

parsedResultAction ::
  [Plugin.CommandLineOption] ->
  Plugin.ModSummary ->
  Plugin.ParsedResult ->
  Plugin.Hsc Plugin.ParsedResult
parsedResultAction :: [CommandLineOption]
-> ModSummary -> ParsedResult -> Hsc ParsedResult
parsedResultAction [CommandLineOption]
commandLineOptions ModSummary
modSummary =
  IO ParsedResult -> Hsc ParsedResult
forall a. IO a -> Hsc a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
Plugin.liftIO
    (IO ParsedResult -> Hsc ParsedResult)
-> (ParsedResult -> IO ParsedResult)
-> ParsedResult
-> Hsc ParsedResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SomeException -> IO ParsedResult)
-> IO ParsedResult -> IO ParsedResult
forall (m :: * -> *) e a.
(HasCallStack, MonadCatch m, Exception e) =>
(e -> m a) -> m a -> m a
Exception.handle SomeException -> IO ParsedResult
forall a. SomeException -> IO a
handleException
    (IO ParsedResult -> IO ParsedResult)
-> (ParsedResult -> IO ParsedResult)
-> ParsedResult
-> IO ParsedResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HsParsedModule -> IO HsParsedModule)
-> ParsedResult -> IO ParsedResult
forall (f :: * -> *).
Functor f =>
(HsParsedModule -> f HsParsedModule)
-> ParsedResult -> f ParsedResult
ParsedResult.overModule
      ( (Located HsModulePs -> IO (Located HsModulePs))
-> HsParsedModule -> IO HsParsedModule
forall (f :: * -> *).
Functor f =>
(Located HsModulePs -> f (Located HsModulePs))
-> HsParsedModule -> f HsParsedModule
HsParsedModule.overModule
          ((Located HsModulePs -> IO (Located HsModulePs))
 -> HsParsedModule -> IO HsParsedModule)
-> (ModuleName -> Located HsModulePs -> IO (Located HsModulePs))
-> ModuleName
-> HsParsedModule
-> IO HsParsedModule
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CommandLineOption]
-> ModuleName -> Located HsModulePs -> IO (Located HsModulePs)
forall (m :: * -> *).
MonadThrow m =>
[CommandLineOption]
-> ModuleName -> Located HsModulePs -> m (Located HsModulePs)
imp [CommandLineOption]
commandLineOptions
          (ModuleName -> HsParsedModule -> IO HsParsedModule)
-> ModuleName -> HsParsedModule -> IO HsParsedModule
forall a b. (a -> b) -> a -> b
$ ModSummary -> ModuleName
Plugin.ms_mod_name ModSummary
modSummary
      )

handleException :: Exception.SomeException -> IO a
handleException :: forall a. SomeException -> IO a
handleException SomeException
e = do
  Handle -> CommandLineOption -> IO ()
IO.hPutStrLn Handle
IO.stderr (CommandLineOption -> IO ()) -> CommandLineOption -> IO ()
forall a b. (a -> b) -> a -> b
$ SomeException -> CommandLineOption
forall e. Exception e => e -> CommandLineOption
Exception.displayException SomeException
e
  ExitCode -> IO a
forall a. ExitCode -> IO a
Exit.exitWith (ExitCode -> IO a) -> ExitCode -> IO a
forall a b. (a -> b) -> a -> b
$ SomeException -> ExitCode
exceptionToExitCode SomeException
e

exceptionToExitCode :: Exception.SomeException -> Exit.ExitCode
exceptionToExitCode :: SomeException -> ExitCode
exceptionToExitCode SomeException
e
  | forall e. Exception e => SomeException -> Bool
Exception.isType @ShowHelp.ShowHelp SomeException
e = ExitCode
Exit.ExitSuccess
  | forall e. Exception e => SomeException -> Bool
Exception.isType @ShowVersion.ShowVersion SomeException
e = ExitCode
Exit.ExitSuccess
  | Bool
otherwise = Int -> ExitCode
Exit.ExitFailure Int
1

imp ::
  (Exception.MonadThrow m) =>
  [String] ->
  Plugin.ModuleName ->
  Plugin.Located Ghc.HsModulePs ->
  m (Plugin.Located Ghc.HsModulePs)
imp :: forall (m :: * -> *).
MonadThrow m =>
[CommandLineOption]
-> ModuleName -> Located HsModulePs -> m (Located HsModulePs)
imp [CommandLineOption]
arguments ModuleName
this Located HsModulePs
lHsModule = do
  [Flag]
flags <- [CommandLineOption] -> m [Flag]
forall (m :: * -> *).
MonadThrow m =>
[CommandLineOption] -> m [Flag]
Flag.fromArguments [CommandLineOption]
arguments
  Config
config <- [Flag] -> m Config
forall (m :: * -> *). MonadThrow m => [Flag] -> m Config
Config.fromFlags [Flag]
flags
  Context
context <- Config -> m Context
forall (m :: * -> *). MonadThrow m => Config -> m Context
Context.fromConfig Config
config
  let aliases :: Map Target Source
aliases = Context -> Map Target Source
Context.aliases Context
context
      packages :: Map Target PackageName
packages = Context -> Map Target PackageName
Context.packages Context
context
      implicits :: Set ModuleName
implicits =
        (Target -> ModuleName) -> Set Target -> Set ModuleName
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Target -> ModuleName
Target.toModuleName
          (Set Target -> Set ModuleName)
-> (Map Target Source -> Set Target)
-> Map Target Source
-> Set ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Target Source -> Set Target
forall k a. Map k a -> Set k
Map.keysSet
          (Map Target Source -> Set ModuleName)
-> Map Target Source -> Set ModuleName
forall a b. (a -> b) -> a -> b
$ (Source -> Bool) -> Map Target Source -> Map Target Source
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter Source -> Bool
Source.isImplicit Map Target Source
aliases
      imports :: Set ModuleName
imports =
        [ModuleName] -> Set ModuleName
forall a. Ord a => [a] -> Set a
Set.fromList
          ([ModuleName] -> Set ModuleName)
-> (HsModulePs -> [ModuleName]) -> HsModulePs -> Set ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs) -> ModuleName)
-> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
-> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ImportDecl GhcPs -> ModuleName
ImportDecl.toModuleName (ImportDecl GhcPs -> ModuleName)
-> (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
    -> ImportDecl GhcPs)
-> GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
-> ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
-> ImportDecl GhcPs
forall l e. GenLocated l e -> e
Plugin.unLoc)
          ([GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
 -> [ModuleName])
-> (HsModulePs
    -> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)])
-> HsModulePs
-> [ModuleName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsModulePs -> [LImportDecl GhcPs]
HsModulePs -> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
forall p. HsModule p -> [LImportDecl p]
Hs.hsmodImports
          (HsModulePs -> Set ModuleName) -> HsModulePs -> Set ModuleName
forall a b. (a -> b) -> a -> b
$ Located HsModulePs -> HsModulePs
forall l e. GenLocated l e -> e
Plugin.unLoc Located HsModulePs
lHsModule
      (Located HsModulePs
newLHsModule, Map ModuleName SrcSpanAnnN
moduleNames) =
        State (Map ModuleName SrcSpanAnnN) (Located HsModulePs)
-> Map ModuleName SrcSpanAnnN
-> (Located HsModulePs, Map ModuleName SrcSpanAnnN)
forall s a. State s a -> s -> (a, s)
StateT.runState
          ((HsModulePs
 -> StateT (Map ModuleName SrcSpanAnnN) Identity HsModulePs)
-> Located HsModulePs
-> State (Map ModuleName SrcSpanAnnN) (Located HsModulePs)
forall (f :: * -> *) a b.
Functor f =>
(a -> f b) -> Located a -> f (Located b)
Located.overValue (([LHsDecl GhcPs]
 -> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs])
-> HsModulePs
-> StateT (Map ModuleName SrcSpanAnnN) Identity HsModulePs
forall (f :: * -> *).
Functor f =>
([LHsDecl GhcPs] -> f [LHsDecl GhcPs])
-> HsModulePs -> f HsModulePs
HsModule.overDecls (([LHsDecl GhcPs]
  -> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs])
 -> HsModulePs
 -> StateT (Map ModuleName SrcSpanAnnN) Identity HsModulePs)
-> ([LHsDecl GhcPs]
    -> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs])
-> HsModulePs
-> StateT (Map ModuleName SrcSpanAnnN) Identity HsModulePs
forall a b. (a -> b) -> a -> b
$ (forall b.
 Data b =>
 b -> StateT (Map ModuleName SrcSpanAnnN) Identity b)
-> [LHsDecl GhcPs]
-> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs]
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall b. Data b => b -> m b) -> a -> m a
overData ((forall b.
  Data b =>
  b -> StateT (Map ModuleName SrcSpanAnnN) Identity b)
 -> [LHsDecl GhcPs]
 -> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs])
-> (forall b.
    Data b =>
    b -> StateT (Map ModuleName SrcSpanAnnN) Identity b)
-> [LHsDecl GhcPs]
-> StateT (Map ModuleName SrcSpanAnnN) Identity [LHsDecl GhcPs]
forall a b. (a -> b) -> a -> b
$ ModuleName
-> Set ModuleName
-> Set ModuleName
-> b
-> StateT (Map ModuleName SrcSpanAnnN) Identity b
forall a.
Data a =>
ModuleName
-> Set ModuleName
-> Set ModuleName
-> a
-> State (Map ModuleName SrcSpanAnnN) a
updateQualifiedIdentifiers ModuleName
this Set ModuleName
implicits Set ModuleName
imports) Located HsModulePs
lHsModule)
          Map ModuleName SrcSpanAnnN
forall k a. Map k a
Map.empty
  Located HsModulePs -> m (Located HsModulePs)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Located HsModulePs -> m (Located HsModulePs))
-> Located HsModulePs -> m (Located HsModulePs)
forall a b. (a -> b) -> a -> b
$ (HsModulePs -> HsModulePs)
-> Located HsModulePs -> Located HsModulePs
forall a b.
(a -> b) -> GenLocated SrcSpan a -> GenLocated SrcSpan b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([LImportDecl GhcPs] -> [LImportDecl GhcPs])
-> HsModulePs -> HsModulePs
HsModule.overImports (([LImportDecl GhcPs] -> [LImportDecl GhcPs])
 -> HsModulePs -> HsModulePs)
-> ([LImportDecl GhcPs] -> [LImportDecl GhcPs])
-> HsModulePs
-> HsModulePs
forall a b. (a -> b) -> a -> b
$ ModuleName
-> Map Target Source
-> Map Target PackageName
-> Map ModuleName SrcSpanAnnN
-> [LImportDecl GhcPs]
-> [LImportDecl GhcPs]
updateImports ModuleName
this Map Target Source
aliases Map Target PackageName
packages Map ModuleName SrcSpanAnnN
moduleNames) Located HsModulePs
newLHsModule

updateQualifiedIdentifiers ::
  (Data.Data a) =>
  Plugin.ModuleName ->
  Set.Set Plugin.ModuleName ->
  Set.Set Plugin.ModuleName ->
  a ->
  StateT.State (Map.Map Plugin.ModuleName Hs.SrcSpanAnnN) a
updateQualifiedIdentifiers :: forall a.
Data a =>
ModuleName
-> Set ModuleName
-> Set ModuleName
-> a
-> State (Map ModuleName SrcSpanAnnN) a
updateQualifiedIdentifiers ModuleName
this Set ModuleName
implicits Set ModuleName
imports a
x = case a -> Maybe (GenLocated SrcSpanAnnN RdrName)
forall a b. (Typeable a, Typeable b) => a -> Maybe b
Data.cast a
x of
  Maybe (GenLocated SrcSpanAnnN RdrName)
Nothing -> a -> State (Map ModuleName SrcSpanAnnN) a
forall a. a -> StateT (Map ModuleName SrcSpanAnnN) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
  Just (Plugin.L SrcSpanAnnN
l RdrName
rdrName) -> case RdrName
rdrName of
    Plugin.Qual ModuleName
moduleName OccName
occName ->
      if ModuleName -> Set ModuleName -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember ModuleName
moduleName Set ModuleName
imports Bool -> Bool -> Bool
&& ModuleName -> Set ModuleName -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member ModuleName
moduleName Set ModuleName
implicits
        then
          a -> State (Map ModuleName SrcSpanAnnN) a
forall a. a -> StateT (Map ModuleName SrcSpanAnnN) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            (a -> State (Map ModuleName SrcSpanAnnN) a)
-> (RdrName -> a)
-> RdrName
-> State (Map ModuleName SrcSpanAnnN) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe a -> a
forall a. a -> Maybe a -> a
Maybe.fromMaybe a
x
            (Maybe a -> a) -> (RdrName -> Maybe a) -> RdrName -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated SrcSpanAnnN RdrName -> Maybe a
forall a b. (Typeable a, Typeable b) => a -> Maybe b
Data.cast
            (GenLocated SrcSpanAnnN RdrName -> Maybe a)
-> (RdrName -> GenLocated SrcSpanAnnN RdrName)
-> RdrName
-> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
Plugin.L SrcSpanAnnN
l
            (RdrName -> State (Map ModuleName SrcSpanAnnN) a)
-> RdrName -> State (Map ModuleName SrcSpanAnnN) a
forall a b. (a -> b) -> a -> b
$ ModuleName -> OccName -> RdrName
Plugin.Qual ModuleName
this OccName
occName
        else do
          (Map ModuleName SrcSpanAnnN -> Map ModuleName SrcSpanAnnN)
-> StateT (Map ModuleName SrcSpanAnnN) Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
StateT.modify ((Map ModuleName SrcSpanAnnN -> Map ModuleName SrcSpanAnnN)
 -> StateT (Map ModuleName SrcSpanAnnN) Identity ())
-> (Map ModuleName SrcSpanAnnN -> Map ModuleName SrcSpanAnnN)
-> StateT (Map ModuleName SrcSpanAnnN) Identity ()
forall a b. (a -> b) -> a -> b
$
            (SrcSpanAnnN -> SrcSpanAnnN -> SrcSpanAnnN)
-> ModuleName
-> SrcSpanAnnN
-> Map ModuleName SrcSpanAnnN
-> Map ModuleName SrcSpanAnnN
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith
              SrcSpanAnnN -> SrcSpanAnnN -> SrcSpanAnnN
SrcSpanAnnN.leftmostSmallest
              ModuleName
moduleName
              SrcSpanAnnN
l
          a -> State (Map ModuleName SrcSpanAnnN) a
forall a. a -> StateT (Map ModuleName SrcSpanAnnN) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
    RdrName
_ -> a -> State (Map ModuleName SrcSpanAnnN) a
forall a. a -> StateT (Map ModuleName SrcSpanAnnN) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x

overData :: (Data.Data a, Monad m) => (forall b. (Data.Data b) => b -> m b) -> a -> m a
overData :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall b. Data b => b -> m b) -> a -> m a
overData forall b. Data b => b -> m b
f = (forall b. Data b => b -> m b) -> a -> m a
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> a -> m a
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a
Data.gmapM ((forall b. Data b => b -> m b) -> a -> m a)
-> (forall b. Data b => b -> m b) -> a -> m a
forall a b. (a -> b) -> a -> b
$ (forall b. Data b => b -> m b) -> d -> m d
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall b. Data b => b -> m b) -> a -> m a
overData b -> m b
forall b. Data b => b -> m b
f (d -> m d) -> (d -> m d) -> d -> m d
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
Monad.>=> d -> m d
forall b. Data b => b -> m b
f

updateImports ::
  Plugin.ModuleName ->
  Map.Map Target.Target Source.Source ->
  Map.Map Target.Target PackageName.PackageName ->
  Map.Map Plugin.ModuleName Hs.SrcSpanAnnN ->
  [Hs.LImportDecl Hs.GhcPs] ->
  [Hs.LImportDecl Hs.GhcPs]
updateImports :: ModuleName
-> Map Target Source
-> Map Target PackageName
-> Map ModuleName SrcSpanAnnN
-> [LImportDecl GhcPs]
-> [LImportDecl GhcPs]
updateImports ModuleName
this Map Target Source
aliases Map Target PackageName
packages Map ModuleName SrcSpanAnnN
want [LImportDecl GhcPs]
imports =
  let have :: Set ModuleName
have = ModuleName -> Set ModuleName -> Set ModuleName
forall a. Ord a => a -> Set a -> Set a
Set.insert ModuleName
this (Set ModuleName -> Set ModuleName)
-> ([ModuleName] -> Set ModuleName)
-> [ModuleName]
-> Set ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ModuleName] -> Set ModuleName
forall a. Ord a => [a] -> Set a
Set.fromList ([ModuleName] -> Set ModuleName) -> [ModuleName] -> Set ModuleName
forall a b. (a -> b) -> a -> b
$ (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs) -> ModuleName)
-> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
-> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ImportDecl GhcPs -> ModuleName
ImportDecl.toModuleName (ImportDecl GhcPs -> ModuleName)
-> (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
    -> ImportDecl GhcPs)
-> GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
-> ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
-> ImportDecl GhcPs
forall l e. GenLocated l e -> e
Plugin.unLoc) [LImportDecl GhcPs]
[GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
imports
      need :: [(ModuleName, SrcSpanAnnN)]
need = Map ModuleName SrcSpanAnnN -> [(ModuleName, SrcSpanAnnN)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map ModuleName SrcSpanAnnN -> [(ModuleName, SrcSpanAnnN)])
-> Map ModuleName SrcSpanAnnN -> [(ModuleName, SrcSpanAnnN)]
forall a b. (a -> b) -> a -> b
$ Map ModuleName SrcSpanAnnN
-> Set ModuleName -> Map ModuleName SrcSpanAnnN
forall k a. Ord k => Map k a -> Set k -> Map k a
Map.withoutKeys Map ModuleName SrcSpanAnnN
want Set ModuleName
have
   in [LImportDecl GhcPs]
[GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
imports [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
-> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
-> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
forall a. Semigroup a => a -> a -> a
<> ((ModuleName, SrcSpanAnnN)
 -> Maybe (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)))
-> [(ModuleName, SrcSpanAnnN)]
-> [GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)]
forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe (\(ModuleName
m, SrcSpanAnnN
l) -> SrcAnn AnnListItem
-> ImportDecl GhcPs
-> GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs)
forall l e. l -> e -> GenLocated l e
Plugin.L (SrcSpanAnnN -> SrcAnn AnnListItem
forall a ann. SrcSpanAnn' a -> SrcAnn ann
Hs.na2la SrcSpanAnnN
l) (ImportDecl GhcPs
 -> GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs))
-> Maybe (ImportDecl GhcPs)
-> Maybe (GenLocated (SrcAnn AnnListItem) (ImportDecl GhcPs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Target Source
-> Map Target PackageName -> ModuleName -> Maybe (ImportDecl GhcPs)
createImport Map Target Source
aliases Map Target PackageName
packages ModuleName
m) [(ModuleName, SrcSpanAnnN)]
need

createImport ::
  Map.Map Target.Target Source.Source ->
  Map.Map Target.Target PackageName.PackageName ->
  Plugin.ModuleName ->
  Maybe (Hs.ImportDecl Hs.GhcPs)
createImport :: Map Target Source
-> Map Target PackageName -> ModuleName -> Maybe (ImportDecl GhcPs)
createImport Map Target Source
aliases Map Target PackageName
packages ModuleName
target = do
  ModuleName
source <-
    case Target -> Map Target Source -> Maybe Source
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (ModuleName -> Target
Target.fromModuleName ModuleName
target) Map Target Source
aliases of
      Maybe Source
Nothing -> ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
target
      Just Source
s -> case Source
s of
        Source
Source.Implicit -> Maybe ModuleName
forall a. Maybe a
Nothing
        Source.Explicit ModuleName
m -> ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
m
  ImportDecl GhcPs -> Maybe (ImportDecl GhcPs)
forall a. a -> Maybe a
Just
    (ModuleName -> ImportDecl GhcPs
Ghc.newImportDecl ModuleName
source)
      { Hs.ideclAs =
          if source == target
            then Nothing
            else Just $ Hs.noLocA target,
        Hs.ideclPkgQual =
          maybe PkgQual.NoRawPkgQual (PkgQual.RawPkgQual . PackageName.toStringLiteral) $
            Map.lookup (Target.fromModuleName target) packages
      }