    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE TypeFamilies #-}

    module Distribution.Types.ComponentLocalBuildInfo (
      ComponentLocalBuildInfo(..),
      componentIsIndefinite,
      maybeComponentInstantiatedWith,
      ) where

    import Prelude ()
    import Distribution.Compat.Prelude
    import Distribution.ModuleName

    import Distribution.Backpack
    import Distribution.Compat.Graph
    import Distribution.Types.ComponentId
    import Distribution.Types.MungedPackageId
    import Distribution.Types.UnitId
    import Distribution.Types.ComponentName
    import Distribution.Types.MungedPackageName
    import Distribution.Types.ModuleRenaming

    import qualified Distribution.InstalledPackageInfo as Installed

    -- | The first five fields are common across all algebraic variants.
    data ComponentLocalBuildInfo
      = LibComponentLocalBuildInfo {
        -- | It would be very convenient to store the literal Library here,
        -- but if we do that, it will get serialized (via the Binary)
        -- instance twice.  So instead we just provide the ComponentName,
        -- which can be used to find the Component in the
        -- PackageDescription.  NB: eventually, this will NOT uniquely
        -- identify the ComponentLocalBuildInfo.
        ComponentLocalBuildInfo -> ComponentName
    componentLocalName :: ComponentName,
        -- | The computed 'ComponentId' of this component.
        ComponentLocalBuildInfo -> ComponentId
    componentComponentId :: ComponentId,
        -- | The computed 'UnitId' which uniquely identifies this
        -- component.  Might be hashed.
        ComponentLocalBuildInfo -> UnitId
    componentUnitId :: UnitId,
        -- | Is this an indefinite component (i.e. has unfilled holes)?
        ComponentLocalBuildInfo -> Bool
    componentIsIndefinite_ :: Bool,
        -- | How the component was instantiated
        ComponentLocalBuildInfo -> [(ModuleName, OpenModule)]
    componentInstantiatedWith :: [(ModuleName, OpenModule)],
        -- | Resolved internal and external package dependencies for this component.
        -- The 'BuildInfo' specifies a set of build dependencies that must be
        -- satisfied in terms of version ranges. This field fixes those dependencies
        -- to the specific versions available on this machine for this compiler.
        ComponentLocalBuildInfo -> [(UnitId, MungedPackageId)]
    componentPackageDeps :: [(UnitId, MungedPackageId)],
        -- | The set of packages that are brought into scope during
        -- compilation, including a 'ModuleRenaming' which may used
        -- to hide or rename modules.  This is what gets translated into
        -- @-package-id@ arguments.  This is a modernized version of
        -- 'componentPackageDeps', which is kept around for BC purposes.
        ComponentLocalBuildInfo -> [(OpenUnitId, ModuleRenaming)]
    componentIncludes :: [(OpenUnitId, ModuleRenaming)],
        ComponentLocalBuildInfo -> [UnitId]
    componentExeDeps :: [UnitId],
        -- | The internal dependencies which induce a graph on the
        -- 'ComponentLocalBuildInfo' of this package.  This does NOT
        -- coincide with 'componentPackageDeps' because it ALSO records
        -- 'build-tool' dependencies on executables.  Maybe one day
        -- @cabal-install@ will also handle these correctly too!
        ComponentLocalBuildInfo -> [UnitId]
    componentInternalDeps :: [UnitId],
        -- | Compatibility "package key" that we pass to older versions of GHC.
        ComponentLocalBuildInfo -> String
    componentCompatPackageKey :: String,
        -- | Compatibility "package name" that we register this component as.
        ComponentLocalBuildInfo -> MungedPackageName
    componentCompatPackageName :: MungedPackageName,
        -- | A list of exposed modules (either defined in this component,
        -- or reexported from another component.)
        ComponentLocalBuildInfo -> [ExposedModule]
    componentExposedModules :: [Installed.ExposedModule],
        -- | Convenience field, specifying whether or not this is the
        -- "public library" that has the same name as the package.
        ComponentLocalBuildInfo -> Bool
    componentIsPublic :: Bool
      }
      -- TODO: refactor all these duplicates
      | FLibComponentLocalBuildInfo {
        componentLocalName :: ComponentName,
        componentComponentId :: ComponentId,
        componentUnitId :: UnitId,
        componentPackageDeps :: [(UnitId, MungedPackageId)],
        componentIncludes :: [(OpenUnitId, ModuleRenaming)],
        componentExeDeps :: [UnitId],
        componentInternalDeps :: [UnitId]
      }
      | ExeComponentLocalBuildInfo {
        componentLocalName :: ComponentName,
        componentComponentId :: ComponentId,
        componentUnitId :: UnitId,
        componentPackageDeps :: [(UnitId, MungedPackageId)],
        componentIncludes :: [(OpenUnitId, ModuleRenaming)],
        componentExeDeps :: [UnitId],
        componentInternalDeps :: [UnitId]
      }
      | TestComponentLocalBuildInfo {
        componentLocalName :: ComponentName,
        componentComponentId :: ComponentId,
        componentUnitId :: UnitId,
        componentPackageDeps :: [(UnitId, MungedPackageId)],
        componentIncludes :: [(OpenUnitId, ModuleRenaming)],
        componentExeDeps :: [UnitId],
        componentInternalDeps :: [UnitId]

      }
      | BenchComponentLocalBuildInfo {
        componentLocalName :: ComponentName,
        componentComponentId :: ComponentId,
        componentUnitId :: UnitId,
        componentPackageDeps :: [(UnitId, MungedPackageId)],
        componentIncludes :: [(OpenUnitId, ModuleRenaming)],
        componentExeDeps :: [UnitId],
        componentInternalDeps :: [UnitId]
      }
      deriving ((forall x.
     ComponentLocalBuildInfo -> Rep ComponentLocalBuildInfo x)
    -> (forall x.
        Rep ComponentLocalBuildInfo x -> ComponentLocalBuildInfo)
    -> Generic ComponentLocalBuildInfo
    forall x. Rep ComponentLocalBuildInfo x -> ComponentLocalBuildInfo
    forall x. ComponentLocalBuildInfo -> Rep ComponentLocalBuildInfo x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ComponentLocalBuildInfo -> Rep ComponentLocalBuildInfo x
    from :: forall x. ComponentLocalBuildInfo -> Rep ComponentLocalBuildInfo x
    $cto :: forall x. Rep ComponentLocalBuildInfo x -> ComponentLocalBuildInfo
    to :: forall x. Rep ComponentLocalBuildInfo x -> ComponentLocalBuildInfo
    Generic, ReadPrec [ComponentLocalBuildInfo]
    ReadPrec ComponentLocalBuildInfo
    Int -> ReadS ComponentLocalBuildInfo
    ReadS [ComponentLocalBuildInfo]
    (Int -> ReadS ComponentLocalBuildInfo)
    -> ReadS [ComponentLocalBuildInfo]
    -> ReadPrec ComponentLocalBuildInfo
    -> ReadPrec [ComponentLocalBuildInfo]
    -> Read ComponentLocalBuildInfo
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS ComponentLocalBuildInfo
    readsPrec :: Int -> ReadS ComponentLocalBuildInfo
    $creadList :: ReadS [ComponentLocalBuildInfo]
    readList :: ReadS [ComponentLocalBuildInfo]
    $creadPrec :: ReadPrec ComponentLocalBuildInfo
    readPrec :: ReadPrec ComponentLocalBuildInfo
    $creadListPrec :: ReadPrec [ComponentLocalBuildInfo]
    readListPrec :: ReadPrec [ComponentLocalBuildInfo]
    Read, Int -> ComponentLocalBuildInfo -> ShowS
    [ComponentLocalBuildInfo] -> ShowS
    ComponentLocalBuildInfo -> String
    (Int -> ComponentLocalBuildInfo -> ShowS)
    -> (ComponentLocalBuildInfo -> String)
    -> ([ComponentLocalBuildInfo] -> ShowS)
    -> Show ComponentLocalBuildInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ComponentLocalBuildInfo -> ShowS
    showsPrec :: Int -> ComponentLocalBuildInfo -> ShowS
    $cshow :: ComponentLocalBuildInfo -> String
    show :: ComponentLocalBuildInfo -> String
    $cshowList :: [ComponentLocalBuildInfo] -> ShowS
    showList :: [ComponentLocalBuildInfo] -> ShowS
    Show, Typeable)

    instance Binary ComponentLocalBuildInfo
    instance Structured ComponentLocalBuildInfo

    instance IsNode ComponentLocalBuildInfo where
        type Key ComponentLocalBuildInfo = UnitId
        nodeKey :: ComponentLocalBuildInfo -> Key ComponentLocalBuildInfo
    nodeKey = ComponentLocalBuildInfo -> Key ComponentLocalBuildInfo
    ComponentLocalBuildInfo -> UnitId
    componentUnitId
        nodeNeighbors :: ComponentLocalBuildInfo -> [Key ComponentLocalBuildInfo]
    nodeNeighbors = ComponentLocalBuildInfo -> [Key ComponentLocalBuildInfo]
    ComponentLocalBuildInfo -> [UnitId]
    componentInternalDeps

    componentIsIndefinite :: ComponentLocalBuildInfo -> Bool
    componentIsIndefinite :: ComponentLocalBuildInfo -> Bool
    componentIsIndefinite LibComponentLocalBuildInfo{ componentIsIndefinite_ :: ComponentLocalBuildInfo -> Bool
    componentIsIndefinite_ = Bool
    b } = Bool
    b
    componentIsIndefinite ComponentLocalBuildInfo
    _ = Bool
    False

    maybeComponentInstantiatedWith :: ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith :: ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith
        LibComponentLocalBuildInfo { componentInstantiatedWith :: ComponentLocalBuildInfo -> [(ModuleName, OpenModule)]
    componentInstantiatedWith = [(ModuleName, OpenModule)]
    insts } = [(ModuleName, OpenModule)] -> Maybe [(ModuleName, OpenModule)]
    forall a. a -> Maybe a
    Just [(ModuleName, OpenModule)]
    insts
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    _ = Maybe [(ModuleName, OpenModule)]
    forall a. Maybe a
    Nothing