ghc-lib-parser-9.14.1.20251220: The GHC API, decoupled from GHC versions

Safe Haskell | Ignore
Language | GHC2021

GHC.Unit.Home.Graph

Contents

- Operations
  - Lookups
  - Reachability
- Very important queries
- Utilities
  - Printing
- Auxiliary internal structure

Description

A `HomeUnitGraph` (HUG) collects information about all the home units. Crucially, each node in a `HomeUnitGraph` includes a `HomePackageTable`.

Often, we don't want to query just a single `HomePackageTable`, but rather all `HomePackageTable`s of all home units.

This module is responsible for maintaining this bridge between querying all home units vs querying the home package table directly. Think `lookupHug` vs `lookupHpt`, `hugAllInstances` vs `hptAllInstances`, where the `hug` version replies with information from all home units, and the `hpt` version with information pertaining to a single home unit.

Meant to be imported qualified as `HUG`. Example usage:

    import GHC.Unit.Home.Graph (HomeUnitGraph, HomeUnitEnv)
    import qualified GHC.Unit.Home.Graph as HUG
    usage = ... HUG.insertHug hug uid modname modinfo ...

Synopsis

- type HomeUnitGraph = UnitEnvGraph HomeUnitEnv
- data HomeUnitEnv = HomeUnitEnv {
  - homeUnitEnv_units :: !UnitState
  - homeUnitEnv_unit_dbs :: !(Maybe [UnitDatabase UnitId])
  - homeUnitEnv_dflags :: DynFlags
  - homeUnitEnv_hpt :: HomePackageTable
  - homeUnitEnv_home_unit :: !(Maybe HomeUnit)
  }
- mkHomeUnitEnv :: UnitState -> Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
- addHomeModInfoToHug :: HomeModInfo -> HomeUnitGraph -> IO ()
- restrictHug :: [(UnitId, [HomeModInfo])] -> HomeUnitGraph -> IO ()
- renameUnitId :: UnitId -> UnitId -> HomeUnitGraph -> Maybe HomeUnitGraph
- allUnits :: HomeUnitGraph -> Set UnitId
- updateUnitFlags :: UnitId -> (DynFlags -> DynFlags) -> HomeUnitGraph -> HomeUnitGraph
- lookupHug :: HomeUnitGraph -> UnitId -> ModuleName -> IO (Maybe HomeModInfo)
- lookupHugByModule :: Module -> HomeUnitGraph -> IO (Maybe HomeModInfo)
- lookupHugUnit :: Unit -> HomeUnitGraph -> Maybe HomeUnitEnv
- lookupHugUnitId :: UnitId -> HomeUnitGraph -> Maybe HomeUnitEnv
- lookupAllHug :: HomeUnitGraph -> ModuleName -> IO [HomeModInfo]
- memberHugUnit :: Unit -> HomeUnitGraph -> Bool
- memberHugUnitId :: UnitId -> HomeUnitGraph -> Bool
- transitiveHomeDeps :: UnitId -> HomeUnitGraph -> Maybe [UnitId]
- allInstances :: HomeUnitGraph -> IO (InstEnv, [FamInst])
- allFamInstances :: HomeUnitGraph -> IO (ModuleEnv FamInstEnv)
- allAnns :: HomeUnitGraph -> IO AnnEnv
- allCompleteSigs :: HomeUnitGraph -> IO CompleteMatches
- hugSCCs :: HomeUnitGraph -> [SCC UnitId]
- hugFromList :: [(UnitId, HomeUnitEnv)] -> HomeUnitGraph
- pprHomeUnitGraph :: HomeUnitGraph -> IO SDoc
- pprHomeUnitEnv :: UnitId -> HomeUnitEnv -> IO SDoc
- newtype UnitEnvGraph v = UnitEnvGraph {
  - unitEnv_graph :: Map UnitEnvGraphKey v
  }
- unitEnv_lookup_maybe :: UnitEnvGraphKey -> UnitEnvGraph v -> Maybe v
- unitEnv_foldWithKey :: (b -> UnitEnvGraphKey -> a -> b) -> b -> UnitEnvGraph a -> b
- unitEnv_singleton :: UnitEnvGraphKey -> v -> UnitEnvGraph v
- unitEnv_adjust :: (v -> v) -> UnitEnvGraphKey -> UnitEnvGraph v -> UnitEnvGraph v
- unitEnv_keys :: UnitEnvGraph v -> Set UnitEnvGraphKey
- unitEnv_insert :: UnitEnvGraphKey -> v -> UnitEnvGraph v -> UnitEnvGraph v
- unitEnv_new :: Map UnitEnvGraphKey v -> UnitEnvGraph v
- unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v
- unitEnv_traverseWithKey :: Applicative f => (UnitEnvGraphKey -> a -> f b) -> UnitEnvGraph a -> f (UnitEnvGraph b)
- unitEnv_assocs :: UnitEnvGraph a -> [(UnitEnvGraphKey, a)]

# Documentation

type HomeUnitGraph = UnitEnvGraph HomeUnitEnv #

data HomeUnitEnv #

Constructors

HomeUnitEnv |

Fields

- homeUnitEnv_units :: !UnitState

  External units

- homeUnitEnv_unit_dbs :: !(Maybe [UnitDatabase UnitId])

  Stack of unit databases for the target platform.

  This field is populated with the result of `initUnits`.

  `Nothing` means the databases have never been read from disk.

  Usually we don't reload the databases from disk if they are cached, even if the database flags changed!

- homeUnitEnv_dflags :: DynFlags

  The dynamic flag settings

- homeUnitEnv_hpt :: HomePackageTable

  The home package table describes already-compiled home-package modules, excluding the module we are compiling right now. (In one-shot mode the current module is the only home-package module, so homeUnitEnv_hpt is empty. All other modules count as "external-package" modules. However, even in GHCi mode, hi-boot interfaces are demand-loaded into the external-package table.)

  `homeUnitEnv_hpt` is not mutable because we only demand-load external packages; the home package is eagerly loaded, module by module, by the compilation manager.

  The HPT may contain modules compiled earlier by `--make` but not actually below the current module in the dependency graph.

  (This changes a previous invariant: changed Jan 05.)

- homeUnitEnv_home_unit :: !(Maybe HomeUnit)

  Home-unit

mkHomeUnitEnv :: UnitState -> Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv #

# Operations

addHomeModInfoToHug :: HomeModInfo -> HomeUnitGraph -> IO () #

Add an entry to the `HomePackageTable` under the unit of that entry.

restrictHug :: [(UnitId, [HomeModInfo])] -> HomeUnitGraph -> IO () #

Thin each HPT variable to only contain keys from the given dependencies. This is used at the end of upsweep to make sure that only completely successfully loaded modules are visible for subsequent operations.

renameUnitId :: UnitId -> UnitId -> HomeUnitGraph -> Maybe HomeUnitGraph #

Rename a unit id in the `HomeUnitGraph`

``renameUnitId` oldUnit newUnit hug`, if `oldUnit` is not found in `hug`, returns `Nothing`. If it exists, the result maps `newUnit` to the `HomeUnitEnv` of the `oldUnit` (and `oldUnit` is removed from `hug`)

allUnits :: HomeUnitGraph -> Set UnitId #

Retrieve all `UnitId`s of units in the `HomeUnitGraph`.

updateUnitFlags :: UnitId -> (DynFlags -> DynFlags) -> HomeUnitGraph -> HomeUnitGraph #

Set the `DynFlags` of the `HomeUnitEnv` for unit in the `HomeModuleGraph`

## Lookups

lookupHug :: HomeUnitGraph -> UnitId -> ModuleName -> IO (Maybe HomeModInfo) #

Lookup the `HomeModInfo` of a `Module` in the `HomeUnitGraph` given its `UnitId` and `ModuleName` (via the `HomePackageTable` of the corresponding unit)

lookupHugByModule :: Module -> HomeUnitGraph -> IO (Maybe HomeModInfo) #

Lookup the `HomeModInfo` of a `Module` in the `HomeUnitGraph` (via the `HomePackageTable` of the corresponding unit)

lookupHugUnit :: Unit -> HomeUnitGraph -> Maybe HomeUnitEnv #

Lookup up the `HomeUnitEnv` by the `Unit` in the `HomeUnitGraph`. If the `Unit` can be turned into a `UnitId`, we behave identical to `lookupHugUnitId`.

A `HoleUnit` is never part of the `HomeUnitGraph`, only instantiated `Unit`s

lookupHugUnitId :: UnitId -> HomeUnitGraph -> Maybe HomeUnitEnv #

Lookup a `HomeUnitEnv` by `UnitId` in a `HomeUnitGraph`

lookupAllHug :: HomeUnitGraph -> ModuleName -> IO [HomeModInfo] #

Lookup all `HomeModInfo` that have the same `ModuleName` as the given `ModuleName`. `ModuleName`s are not unique in the case of multiple home units, so there can be more than one possible `HomeModInfo`.

You should always prefer `lookupHug` and `lookupHugByModule` when possible.

memberHugUnit :: Unit -> HomeUnitGraph -> Bool #

Check whether the `Unit` is present in the `HomeUnitGraph`

A `HoleUnit` is never part of the `HomeUnitGraph`, only instantiated `Unit`s

memberHugUnitId :: UnitId -> HomeUnitGraph -> Bool #

Check whether the `UnitId` is present in the `HomeUnitGraph`

## Reachability

transitiveHomeDeps :: UnitId -> HomeUnitGraph -> Maybe [UnitId] #

Compute the transitive closure of a unit in the `HomeUnitGraph`. If the argument unit is not present in the graph returns Nothing.

# Very important queries

allInstances :: HomeUnitGraph -> IO (InstEnv, [FamInst]) #

Find all the instance declarations (of classes and families) from the Home Package Table filtered by the provided predicate function. Used in `tcRnImports`, to select the instances that are in the transitive closure of imports from the currently compiled module.

allFamInstances :: HomeUnitGraph -> IO (ModuleEnv FamInstEnv) #

allAnns :: HomeUnitGraph -> IO AnnEnv #

allCompleteSigs :: HomeUnitGraph -> IO CompleteMatches #

Get all `CompleteMatches` (arising from COMPLETE pragmas) present across all home units.

# Utilities

hugSCCs :: HomeUnitGraph -> [SCC UnitId] #

hugFromList :: [(UnitId, HomeUnitEnv)] -> HomeUnitGraph #

## Printing

pprHomeUnitGraph :: HomeUnitGraph -> IO SDoc #

pprHomeUnitEnv :: UnitId -> HomeUnitEnv -> IO SDoc #

# Auxiliary internal structure

newtype UnitEnvGraph v #

Constructors

UnitEnvGraph |

Fields

- unitEnv_graph :: Map UnitEnvGraphKey v

#### Instances

Instances details

Functor UnitEnvGraph # |
Instance details Defined in GHC.Unit.Home.Graph Methods fmap :: (a -> b) -> UnitEnvGraph a -> UnitEnvGraph b # (<$) :: a -> UnitEnvGraph b -> UnitEnvGraph a #
Foldable UnitEnvGraph # |

Instance details

Defined in GHC.Unit.Home.Graph

Methods

fold :: Monoid m => UnitEnvGraph m -> m #

foldMap :: Monoid m => (a -> m) -> UnitEnvGraph a -> m #

foldMap' :: Monoid m => (a -> m) -> UnitEnvGraph a -> m #

foldr :: (a -> b -> b) -> b -> UnitEnvGraph a -> b #

foldr' :: (a -> b -> b) -> b -> UnitEnvGraph a -> b #

foldl :: (b -> a -> b) -> b -> UnitEnvGraph a -> b #

foldl' :: (b -> a -> b) -> b -> UnitEnvGraph a -> b #

foldr1 :: (a -> a -> a) -> UnitEnvGraph a -> a #

foldl1 :: (a -> a -> a) -> UnitEnvGraph a -> a #

toList :: UnitEnvGraph a -> [a] #

null :: UnitEnvGraph a -> Bool #

length :: UnitEnvGraph a -> Int #

elem :: Eq a => a -> UnitEnvGraph a -> Bool #

maximum :: Ord a => UnitEnvGraph a -> a #

minimum :: Ord a => UnitEnvGraph a -> a #

sum :: Num a => UnitEnvGraph a -> a #

product :: Num a => UnitEnvGraph a -> a #

Traversable UnitEnvGraph # |
Instance details Defined in GHC.Unit.Home.Graph Methods traverse :: Applicative f => (a -> f b) -> UnitEnvGraph a -> f (UnitEnvGraph b) # sequenceA :: Applicative f => UnitEnvGraph (f a) -> f (UnitEnvGraph a) # mapM :: Monad m => (a -> m b) -> UnitEnvGraph a -> m (UnitEnvGraph b) # sequence :: Monad m => UnitEnvGraph (m a) -> m (UnitEnvGraph a) #

unitEnv_lookup_maybe :: UnitEnvGraphKey -> UnitEnvGraph v -> Maybe v #

unitEnv_foldWithKey :: (b -> UnitEnvGraphKey -> a -> b) -> b -> UnitEnvGraph a -> b #

unitEnv_singleton :: UnitEnvGraphKey -> v -> UnitEnvGraph v #

unitEnv_adjust :: (v -> v) -> UnitEnvGraphKey -> UnitEnvGraph v -> UnitEnvGraph v #

unitEnv_keys :: UnitEnvGraph v -> Set UnitEnvGraphKey #

unitEnv_insert :: UnitEnvGraphKey -> v -> UnitEnvGraph v -> UnitEnvGraph v #

unitEnv_new :: Map UnitEnvGraphKey v -> UnitEnvGraph v #

unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v #

unitEnv_traverseWithKey :: Applicative f => (UnitEnvGraphKey -> a -> f b) -> UnitEnvGraph a -> f (UnitEnvGraph b) #

unitEnv_assocs :: UnitEnvGraph a -> [(UnitEnvGraphKey, a)] #