{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}

module GHC.Iface.Errors.Types (

    MissingInterfaceError(..)
  , InterfaceLookingFor(..)
  , IfaceMessage(..)
  , ReadInterfaceError(..)
  , CantFindInstalled(..)
  , CantFindInstalledReason(..)
  , FindingModuleOrInterface(..)

  , BuildingCabalPackage(..)

  , IfaceMessageOpts(..)

  ) where

import GHC.Prelude

import GHC.Types.Name (Name)
import GHC.Types.TyThing (TyThing)
import GHC.Unit.Types (Module, InstalledModule, UnitId, Unit)
import GHC.Unit.State (UnitState, ModuleSuggestion, ModuleOrigin, UnusableUnitReason, UnitInfo)
import GHC.Exception.Type (SomeException)
import GHC.Unit.Types ( IsBootInterface )
import Language.Haskell.Syntax.Module.Name ( ModuleName )



import GHC.Generics ( Generic )
import GHC.Unit.Module.Location

data IfaceMessageOpts = IfaceMessageOpts { IfaceMessageOpts -> Bool
ifaceShowTriedFiles :: !Bool -- ^ Whether to show files we tried to look for or not when printing loader errors
                                         , IfaceMessageOpts -> BuildingCabalPackage
ifaceBuildingCabalPackage :: !BuildingCabalPackage
                                         }

data InterfaceLookingFor
  = LookingForName   !Name
  | LookingForHiBoot !Module
  | LookingForModule !ModuleName !IsBootInterface
  | LookingForSig    !InstalledModule

data IfaceMessage
  = Can'tFindInterface
      MissingInterfaceError
      InterfaceLookingFor
  | Can'tFindNameInInterface
      Name
      [TyThing] -- possibly relevant TyThings
  | CircularImport !Module
  deriving (forall x. IfaceMessage -> Rep IfaceMessage x)
-> (forall x. Rep IfaceMessage x -> IfaceMessage)
-> Generic IfaceMessage
forall x. Rep IfaceMessage x -> IfaceMessage
forall x. IfaceMessage -> Rep IfaceMessage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. IfaceMessage -> Rep IfaceMessage x
from :: forall x. IfaceMessage -> Rep IfaceMessage x
$cto :: forall x. Rep IfaceMessage x -> IfaceMessage
to :: forall x. Rep IfaceMessage x -> IfaceMessage
Generic

data MissingInterfaceError
  = BadSourceImport !Module
  | HomeModError !InstalledModule !ModLocation
  | DynamicHashMismatchError !Module !ModLocation

  | CantFindErr !UnitState FindingModuleOrInterface CantFindInstalled

  | BadIfaceFile ReadInterfaceError
  | FailedToLoadDynamicInterface Module ReadInterfaceError
    deriving (forall x. MissingInterfaceError -> Rep MissingInterfaceError x)
-> (forall x. Rep MissingInterfaceError x -> MissingInterfaceError)
-> Generic MissingInterfaceError
forall x. Rep MissingInterfaceError x -> MissingInterfaceError
forall x. MissingInterfaceError -> Rep MissingInterfaceError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MissingInterfaceError -> Rep MissingInterfaceError x
from :: forall x. MissingInterfaceError -> Rep MissingInterfaceError x
$cto :: forall x. Rep MissingInterfaceError x -> MissingInterfaceError
to :: forall x. Rep MissingInterfaceError x -> MissingInterfaceError
Generic

data ReadInterfaceError
  = ExceptionOccurred        FilePath SomeException
  | HiModuleNameMismatchWarn FilePath Module Module
  deriving (forall x. ReadInterfaceError -> Rep ReadInterfaceError x)
-> (forall x. Rep ReadInterfaceError x -> ReadInterfaceError)
-> Generic ReadInterfaceError
forall x. Rep ReadInterfaceError x -> ReadInterfaceError
forall x. ReadInterfaceError -> Rep ReadInterfaceError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ReadInterfaceError -> Rep ReadInterfaceError x
from :: forall x. ReadInterfaceError -> Rep ReadInterfaceError x
$cto :: forall x. Rep ReadInterfaceError x -> ReadInterfaceError
to :: forall x. Rep ReadInterfaceError x -> ReadInterfaceError
Generic

data CantFindInstalledReason
  = NoUnitIdMatching UnitId [UnitInfo]
  | MissingPackageFiles UnitId [FilePath]
  | MissingPackageWayFiles String UnitId [FilePath]
  | ModuleSuggestion [ModuleSuggestion] [FilePath]
  | NotAModule
  | CouldntFindInFiles [FilePath]
  | GenericMissing
      [(Unit, Maybe UnitInfo)] [Unit]
      [(Unit, UnusableUnitReason)] [FilePath]
  | MultiplePackages [(Module, ModuleOrigin)]
  deriving (forall x.
 CantFindInstalledReason -> Rep CantFindInstalledReason x)
-> (forall x.
    Rep CantFindInstalledReason x -> CantFindInstalledReason)
-> Generic CantFindInstalledReason
forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
from :: forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
$cto :: forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
to :: forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
Generic

data CantFindInstalled =
  CantFindInstalled ModuleName CantFindInstalledReason
  deriving (forall x. CantFindInstalled -> Rep CantFindInstalled x)
-> (forall x. Rep CantFindInstalled x -> CantFindInstalled)
-> Generic CantFindInstalled
forall x. Rep CantFindInstalled x -> CantFindInstalled
forall x. CantFindInstalled -> Rep CantFindInstalled x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CantFindInstalled -> Rep CantFindInstalled x
from :: forall x. CantFindInstalled -> Rep CantFindInstalled x
$cto :: forall x. Rep CantFindInstalled x -> CantFindInstalled
to :: forall x. Rep CantFindInstalled x -> CantFindInstalled
Generic
data FindingModuleOrInterface = FindingModule
                              | FindingInterface

-- | Pass to a 'DriverMessage' the information whether or not the
-- '-fbuilding-cabal-package' flag is set.
data BuildingCabalPackage
  = YesBuildingCabalPackage
  | NoBuildingCabalPackage
  deriving BuildingCabalPackage -> BuildingCabalPackage -> Bool
(BuildingCabalPackage -> BuildingCabalPackage -> Bool)
-> (BuildingCabalPackage -> BuildingCabalPackage -> Bool)
-> Eq BuildingCabalPackage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
== :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
$c/= :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
/= :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
Eq