module Distribution.C2Hs.TopSort ( reorderC2Hs ) where
import Data.Functor (($>))
import Distribution.Compat.Graph (Node (..), fromDistinctList,
revTopSort)
import Distribution.ModuleName (ModuleName, toFilePath)
import Distribution.Parsec (simpleParsec)
import Distribution.Simple.Utils (findFileWithExtension, warn)
import Distribution.Verbosity (Verbosity)
import Language.Haskell.CHs.Deps (getFileImports)
reorderC2Hs :: Verbosity
-> [FilePath]
-> [ModuleName]
-> IO [ModuleName]
reorderC2Hs v dirs preMods = do
chsFiles <- traverse findCHS preMods
modDeps <- traverse (extractDeps v) (zip preMods chsFiles)
pure $ fmap (\(N m _ _) -> m) (revTopSort $ fromDistinctList modDeps)
where findCHS = findFileWithExtension [".chs"] dirs . toFilePath
extractDeps :: Verbosity -> (ModuleName, Maybe FilePath) -> IO (Node ModuleName ModuleName)
extractDeps _ (m, Nothing) = pure (N m m [])
extractDeps v (m, Just f) = do
res <- getFileImports f
mods <- case res of
Right ms -> case traverse simpleParsec ms of
Just ms' -> pure ms'
Nothing -> warn v ("Cannot parse module name in .chs file " ++ f) $> []
Left err -> warn v ("Cannot parse c2hs import in " ++ f ++ ": " ++ err) $> []
pure (N m m mods)