{-# LANGUAGE RankNTypes #-}
module GHC.Types.Name.Cache
( NameCache (..)
, initNameCache
, takeUniqFromNameCache
, updateNameCache'
, updateNameCache
, OrigNameCache
, lookupOrigNameCache
, extendOrigNameCache'
, extendOrigNameCache
)
where
import GHC.Prelude
import GHC.Unit.Module
import GHC.Types.Name
import GHC.Types.Unique.Supply
import GHC.Builtin.Types
import GHC.Builtin.Names
import GHC.Utils.Outputable
import GHC.Utils.Panic
import Control.Concurrent.MVar
import Control.Monad
data NameCache = NameCache
{ NameCache -> Char
nsUniqChar :: {-# UNPACK #-} !Char
, NameCache -> MVar OrigNameCache
nsNames :: {-# UNPACK #-} !(MVar OrigNameCache)
}
type OrigNameCache = ModuleEnv (OccEnv Name)
takeUniqFromNameCache :: NameCache -> IO Unique
takeUniqFromNameCache :: NameCache -> IO Unique
takeUniqFromNameCache (NameCache Char
c MVar OrigNameCache
_) = Char -> IO Unique
uniqFromMask Char
c
lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name
lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name
lookupOrigNameCache OrigNameCache
nc Module
mod OccName
occ
| Module
mod forall a. Eq a => a -> a -> Bool
== Module
gHC_TYPES Bool -> Bool -> Bool
|| Module
mod forall a. Eq a => a -> a -> Bool
== Module
gHC_PRIM Bool -> Bool -> Bool
|| Module
mod forall a. Eq a => a -> a -> Bool
== Module
gHC_TUPLE_PRIM
, Just Name
name <- OccName -> Maybe Name
isBuiltInOcc_maybe OccName
occ
=
forall a. a -> Maybe a
Just Name
name
| Bool
otherwise
= case forall a. ModuleEnv a -> Module -> Maybe a
lookupModuleEnv OrigNameCache
nc Module
mod of
Maybe (OccEnv Name)
Nothing -> forall a. Maybe a
Nothing
Just OccEnv Name
occ_env -> forall a. OccEnv a -> OccName -> Maybe a
lookupOccEnv OccEnv Name
occ_env OccName
occ
extendOrigNameCache' :: OrigNameCache -> Name -> OrigNameCache
extendOrigNameCache' :: OrigNameCache -> Name -> OrigNameCache
extendOrigNameCache' OrigNameCache
nc Name
name
= forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (Name -> Bool
isExternalName Name
name) (forall a. Outputable a => a -> SDoc
ppr Name
name) forall a b. (a -> b) -> a -> b
$
OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
extendOrigNameCache OrigNameCache
nc (HasDebugCallStack => Name -> Module
nameModule Name
name) (Name -> OccName
nameOccName Name
name) Name
name
extendOrigNameCache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
extendOrigNameCache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
extendOrigNameCache OrigNameCache
nc Module
mod OccName
occ Name
name
= forall a.
(a -> a -> a) -> ModuleEnv a -> Module -> a -> ModuleEnv a
extendModuleEnvWith OccEnv Name -> OccEnv Name -> OccEnv Name
combine OrigNameCache
nc Module
mod (forall a. OccName -> a -> OccEnv a
unitOccEnv OccName
occ Name
name)
where
combine :: OccEnv Name -> OccEnv Name -> OccEnv Name
combine OccEnv Name
_ OccEnv Name
occ_env = forall a. OccEnv a -> OccName -> a -> OccEnv a
extendOccEnv OccEnv Name
occ_env OccName
occ Name
name
initNameCache :: Char -> [Name] -> IO NameCache
initNameCache :: Char -> [Name] -> IO NameCache
initNameCache Char
c [Name]
names = Char -> MVar OrigNameCache -> NameCache
NameCache Char
c forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. a -> IO (MVar a)
newMVar ([Name] -> OrigNameCache
initOrigNames [Name]
names)
initOrigNames :: [Name] -> OrigNameCache
initOrigNames :: [Name] -> OrigNameCache
initOrigNames [Name]
names = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' OrigNameCache -> Name -> OrigNameCache
extendOrigNameCache' forall a. ModuleEnv a
emptyModuleEnv [Name]
names
updateNameCache'
:: NameCache
-> (OrigNameCache -> IO (OrigNameCache, c))
-> IO c
updateNameCache' :: forall c.
NameCache -> (OrigNameCache -> IO (OrigNameCache, c)) -> IO c
updateNameCache' (NameCache Char
_c MVar OrigNameCache
nc) OrigNameCache -> IO (OrigNameCache, c)
upd_fn = forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar' MVar OrigNameCache
nc OrigNameCache -> IO (OrigNameCache, c)
upd_fn
modifyMVar' :: MVar a -> (a -> IO (a,b)) -> IO b
modifyMVar' :: forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar' MVar a
m a -> IO (a, b)
f = forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar a
m forall a b. (a -> b) -> a -> b
$ a -> IO (a, b)
f forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \(a, b)
c -> forall a b. (a, b) -> a
fst (a, b)
c seq :: forall a b. a -> b -> b
`seq` forall (f :: * -> *) a. Applicative f => a -> f a
pure (a, b)
c
updateNameCache
:: NameCache
-> Module
-> OccName
-> (OrigNameCache -> IO (OrigNameCache, c))
-> IO c
updateNameCache :: forall c.
NameCache
-> Module
-> OccName
-> (OrigNameCache -> IO (OrigNameCache, c))
-> IO c
updateNameCache NameCache
name_cache !Module
_mod !OccName
_occ OrigNameCache -> IO (OrigNameCache, c)
upd_fn
= forall c.
NameCache -> (OrigNameCache -> IO (OrigNameCache, c)) -> IO c
updateNameCache' NameCache
name_cache OrigNameCache -> IO (OrigNameCache, c)
upd_fn