ghc-hie-0.0.4: src/GHC/Iface/Ext/Binary/GHC914.hs
{-# LANGUAGE BlockArguments #-}
module GHC.Iface.Ext.Binary.GHC914 (
readHieFile908
, readHieFile910
, readHieFile912
, readHieFile914
) where
import Data.Typeable
import Prelude hiding (span, mod)
import GHC.Builtin.Utils
import GHC.Iface.Ext.Binary.Utils
import GHC.Iface.Ext.Types
import GHC.Types.Name
import GHC.Types.Name.Cache
import GHC.Types.Unique
import GHC.Utils.Outputable hiding (char)
import GHC.Utils.Panic
import GHC.Types.Avail (AvailInfo)
import GHC.Unit.Module (Module)
import GHC.Types.SrcLoc
import Data.Array (Array)
import qualified Data.Array as A
import qualified Data.Array.IO as A
import qualified Data.Array.Unsafe as A
import Data.Word ( Word32 )
import Data.ByteString (ByteString)
import Control.Monad
readHieFile908 :: ReadBinHandle -> NameCache -> IO HieFile
readHieFile908 = readHieFile908_910 GHC908
readHieFile910 :: ReadBinHandle -> NameCache -> IO HieFile
readHieFile910 = readHieFile908_910 GHC910
readHieFile908_910 :: GHC -> ReadBinHandle -> NameCache -> IO HieFile
readHieFile908_910 ghc bh0 name_cache = do
dict_p <- get bh0
symtab_p <- get bh0
readHieFile ghc dict_p symtab_p (const mempty) bh0 name_cache
readHieFile912 :: ReadBinHandle -> NameCache -> IO HieFile
readHieFile912 = readHieFile912_914 GHC912
readHieFile914 :: ReadBinHandle -> NameCache -> IO HieFile
readHieFile914 = readHieFile912_914 GHC914
readHieFile912_914 :: GHC -> ReadBinHandle -> NameCache -> IO HieFile
readHieFile912_914 ghc bh0 name_cache = do
dict_p <- makeAbsoluteBin <$> getRelBin bh0
symtab_p <- makeAbsoluteBin <$> getRelBin bh0
readHieFile ghc dict_p symtab_p get bh0 name_cache
initReadNameTable :: GHC -> Module -> NameCache -> IO (ReaderTable Name)
initReadNameTable ghc currentModule cache = do
return $
ReaderTable
{ getTable = \bh -> getSymbolTable ghc currentModule bh cache
, mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl)
}
readHieFile :: GHC -> Bin () -> Bin () -> (ReadBinHandle -> IO NameEntityInfo) -> ReadBinHandle -> NameCache -> IO HieFile
readHieFile ghc dict_p symtab_p getNameEntityInfo bh0 name_cache = do
fsReaderTable <- initFastStringReaderTable
bh_dict <- get_dictionary dict_p fsReaderTable bh0
file <- get @FilePath bh_dict
currentModule <- get @Module bh_dict
nameReaderTable <- initReadNameTable ghc currentModule name_cache
bh_symtab <- get_dictionary symtab_p nameReaderTable bh_dict
-- load the actual data
HieFile file currentModule
<$> get @(Array TypeIndex HieTypeFlat) bh_symtab
<*> get @(HieASTs TypeIndex) bh_symtab
<*> get @([AvailInfo]) bh_symtab
<*> get @ByteString bh_symtab
<*> getNameEntityInfo bh_symtab
where
get_dictionary :: forall a. Typeable a => Bin () -> ReaderTable a -> ReadBinHandle -> IO ReadBinHandle
get_dictionary p tbl bin_handle = withRestore do
seekBinReader bin_handle p
fsTable :: SymbolTable a <- getTable tbl bin_handle
let
fsReader :: BinaryReader a
fsReader = mkReaderFromTable tbl fsTable
bhFs :: ReadBinHandle
bhFs = addReaderToUserData fsReader bin_handle
pure bhFs
withRestore :: IO a -> IO a
withRestore action = do
backup <- tellBinReader bh0
action <* seekBinReader bh0 backup
getSymbolTable :: GHC -> Module -> ReadBinHandle -> NameCache -> IO (SymbolTable Name)
getSymbolTable ghc currentModule bh name_cache = do
sz <- get bh
mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name)
forM_ [0..(sz-1)] $ \i -> do
od_name <- getHieName bh
name <- fromHieName ghc currentModule name_cache od_name
A.writeArray mut_arr i name
A.unsafeFreeze mut_arr
getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name
getSymTabName st bh = do
i :: Word32 <- get bh
return $ st A.! (fromIntegral i)
-- ** Converting to and from `HieName`'s
fromHieName :: GHC -> Module -> NameCache -> HieName -> IO Name
fromHieName ghc currentModule nc hie_name = do
case hie_name of
ExternalName mod occ span -> updateNameCache nc mod occ $ \cache -> do
case lookupOrigNameCache cache mod occ of
Just old_name -> case nameSrcSpan old_name of
UnhelpfulSpan {} -> update
RealSrcSpan {}
| mod == currentModule -> update
| otherwise -> keep
where
new_name = mkExternalName uniq mod occ span
new_cache = extendOrigNameCache cache mod occ new_name
uniq = nameUnique old_name
update = pure (new_cache, new_name)
keep = pure (cache, old_name)
Nothing -> do
uniq <- takeUniqFromNameCache nc
let name = mkExternalName uniq mod occ span
new_cache = extendOrigNameCache cache mod occ name
pure (new_cache, name)
LocalName occ span -> do
uniq <- takeUniqFromNameCache nc
-- don't update the NameCache for local names
pure $ mkInternalName uniq occ span
KnownKeyName u -> case lookupKnownKeyName ghc u of
Nothing -> pprPanic "fromHieName:unknown known-key unique"
(ppr u)
Just n -> pure n
-- ** Reading and writing `HieName`'s
getHieName :: ReadBinHandle -> IO HieName
getHieName bh = do
t <- getByte bh
case t of
0 -> do
(modu, occ, span) <- get bh
return $ ExternalName modu occ $ unBinSrcSpan span
1 -> do
(occ, span) <- get bh
return $ LocalName occ $ unBinSrcSpan span
2 -> do
(c,i) <- get bh
return $ KnownKeyName $ mkUnique c i
_ -> panic "GHC.Iface.Ext.Binary.getHieName: invalid tag"