module GHC.Unit.External.Query (
  -- * Query the 'UnitInfoMap'
  lookupUnit',
  lookupUnitId',
) where

import GHC.Prelude

import GHC.Types.Unique.Map
import GHC.Unit.External.Substitution
import GHC.Unit.Info
import GHC.Unit.Module

-- | A more specialized interface, which doesn't require a 'UnitState' (so it
-- can be used while we're initializing 'DynFlags')
--
-- Parameters:
--    * a boolean specifying whether or not to look for on-the-fly renamed interfaces
--    * a 'UnitInfoMap'
lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo
lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo
lookupUnit' Bool
allowOnTheFlyInst UnitInfoMap
pkg_map Unit
u = case Unit
u of
   Unit
HoleUnit   -> [Char] -> Maybe UnitInfo
forall a. HasCallStack => [Char] -> a
error [Char]
"Hole unit"
   RealUnit Definite UnitId
i -> UnitInfoMap -> UnitId -> Maybe UnitInfo
forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
lookupUniqMap UnitInfoMap
pkg_map (Definite UnitId -> UnitId
forall unit. Definite unit -> unit
unDefinite Definite UnitId
i)
   VirtUnit GenInstantiatedUnit UnitId
i
      | Bool
allowOnTheFlyInst
      -> -- lookup UnitInfo of the indefinite unit to be instantiated and
         -- instantiate it on-the-fly
         (UnitInfo -> UnitInfo) -> Maybe UnitInfo -> Maybe UnitInfo
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnitInfoMap -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
renameUnitInfo UnitInfoMap
pkg_map (GenInstantiatedUnit UnitId -> [(ModuleName, Module)]
forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
instUnitInsts GenInstantiatedUnit UnitId
i))
           (UnitInfoMap -> UnitId -> Maybe UnitInfo
forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
lookupUniqMap UnitInfoMap
pkg_map (GenInstantiatedUnit UnitId -> UnitId
forall unit. GenInstantiatedUnit unit -> unit
instUnitInstanceOf GenInstantiatedUnit UnitId
i))

      | Bool
otherwise
      -> -- lookup UnitInfo by virtual UnitId. This is used to find indefinite
         -- units. Even if they are real, installed units, they can't use the
         -- `RealUnit` constructor (it is reserved for definite units) so we use
         -- the `VirtUnit` constructor.
         UnitInfoMap -> UnitId -> Maybe UnitInfo
forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
lookupUniqMap UnitInfoMap
pkg_map (GenInstantiatedUnit UnitId -> UnitId
virtualUnitId GenInstantiatedUnit UnitId
i)


-- | Find the unit we know about with the given unit id, if any
lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
lookupUnitId' UnitInfoMap
db UnitId
uid = UnitInfoMap -> UnitId -> Maybe UnitInfo
forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
lookupUniqMap UnitInfoMap
db UnitId
uid