{-# LANGUAGE NamedFieldPuns #-}

module HieDb.Dump where

import qualified Compat.HieDebug as HieDebug
import qualified Compat.HieTypes as HieTypes
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Outputable

import           Compat.HieTypes (HieFile (..))
import           Control.Monad.IO.Class (MonadIO, liftIO)
import           Data.Text (Text)
import           DynFlags (DynFlags)
import           HieDb.Types (NameCacheMonad)
import           HieDb.Utils (withHieFile)

{-| Pretty print Hie AST stored in given .hie file -}
dump ::
    (NameCacheMonad m, MonadIO m)
    => DynFlags
    -> FilePath -- ^ Path to .hie file
    -> m ()
dump :: DynFlags -> FilePath -> m ()
dump DynFlags
dynFlags FilePath
hieFilePath = do
  FilePath -> (HieFile -> m ()) -> m ()
forall (m :: * -> *) a.
(NameCacheMonad m, MonadIO m) =>
FilePath -> (HieFile -> m a) -> m a
withHieFile FilePath
hieFilePath ((HieFile -> m ()) -> m ()) -> (HieFile -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \HieFile{ HieASTs TypeIndex
hie_asts :: HieFile -> HieASTs TypeIndex
hie_asts :: HieASTs TypeIndex
hie_asts } -> do
    let (FastString
_, HieAST TypeIndex
astRoot) = Map FastString (HieAST TypeIndex) -> (FastString, HieAST TypeIndex)
forall k a. Map k a -> (k, a)
Map.findMin (Map FastString (HieAST TypeIndex)
 -> (FastString, HieAST TypeIndex))
-> Map FastString (HieAST TypeIndex)
-> (FastString, HieAST TypeIndex)
forall a b. (a -> b) -> a -> b
$ HieASTs TypeIndex -> Map FastString (HieAST TypeIndex)
forall a. HieASTs a -> Map FastString (HieAST a)
HieTypes.getAsts HieASTs TypeIndex
hie_asts
    IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ()
putStrLn (FilePath -> IO ()) -> FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> FilePath
Outputable.showSDoc DynFlags
dynFlags (SDoc -> FilePath) -> SDoc -> FilePath
forall a b. (a -> b) -> a -> b
$ HieAST TypeIndex -> SDoc
forall a. Outputable a => HieAST a -> SDoc
HieDebug.ppHie HieAST TypeIndex
astRoot

{-| Get lines of original source code from given .hie file -}
sourceCode :: (NameCacheMonad m, MonadIO m) => FilePath -> m [Text]
sourceCode :: FilePath -> m [Text]
sourceCode FilePath
hieFilePath =
  FilePath -> (HieFile -> m [Text]) -> m [Text]
forall (m :: * -> *) a.
(NameCacheMonad m, MonadIO m) =>
FilePath -> (HieFile -> m a) -> m a
withHieFile FilePath
hieFilePath ((HieFile -> m [Text]) -> m [Text])
-> (HieFile -> m [Text]) -> m [Text]
forall a b. (a -> b) -> a -> b
$ \HieFile {ByteString
hie_hs_src :: HieFile -> ByteString
hie_hs_src :: ByteString
hie_hs_src} ->
    [Text] -> m [Text]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Text] -> m [Text]) -> [Text] -> m [Text]
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
T.decodeUtf8 ByteString
hie_hs_src