module Hhp.List (listModules, modules) where

import GHC (Ghc)
import qualified GHC as G

import GHC.Unit.State (lookupModuleInAllUnits, listVisibleModuleNames)
import GHC.Unit.Types (moduleName)

import Control.Monad.Catch (SomeException(..), catch)
import Data.List (nub, sort)

import Hhp.Gap
import Hhp.GHCApi
import Hhp.Types

----------------------------------------------------------------

-- | Listing installed modules.
listModules :: Options -> Cradle -> IO String
listModules :: Options -> Cradle -> IO String
listModules Options
opt Cradle
cradle = forall a. Ghc a -> IO a
withGHC' forall a b. (a -> b) -> a -> b
$ do
    Options -> Cradle -> Ghc ()
initializeFlagsWithCradle Options
opt Cradle
cradle
    Options -> Ghc String
modules Options
opt

-- | Listing installed modules.
modules :: Options -> Ghc String
modules :: Options -> Ghc String
modules Options
opt = forall a. ToString a => Options -> a -> String
convert Options
opt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {unit}. [GenModule unit] -> [String]
arrange forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Ghc [GenModule Unit]
getModules forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` forall {m :: * -> *} {a}. Monad m => SomeException -> m [a]
handler)
  where
    arrange :: [GenModule unit] -> [String]
arrange = forall a. Eq a => [a] -> [a]
nub forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
sort forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (ModuleName -> String
G.moduleNameString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall unit. GenModule unit -> ModuleName
moduleName)
    handler :: SomeException -> m [a]
handler (SomeException e
_) = forall (m :: * -> *) a. Monad m => a -> m a
return []

----------------------------------------------------------------

getModules :: Ghc [G.Module]
getModules :: Ghc [GenModule Unit]
getModules = do
    UnitState
us <- Ghc UnitState
getUnitState
    let modNames :: [ModuleName]
modNames = UnitState -> [ModuleName]
listVisibleModuleNames UnitState
us
    forall (m :: * -> *) a. Monad m => a -> m a
return [ GenModule Unit
m | ModuleName
mn <- [ModuleName]
modNames, (GenModule Unit
m, UnitInfo
_) <- UnitState -> ModuleName -> [(GenModule Unit, UnitInfo)]
lookupModuleInAllUnits UnitState
us ModuleName
mn ]