    module GHC.Types.Target
       ( Target(..)
       , TargetId(..)
       , InputFileBuffer
       , pprTarget
       , pprTargetId
       )
    where

    import GHC.Prelude
    import GHC.Driver.Phases ( Phase )
    import GHC.Unit
    import GHC.Data.StringBuffer ( StringBuffer )
    import GHC.Utils.Outputable

    import Data.Time

    -- | A compilation target.
    --
    -- A target may be supplied with the actual text of the
    -- module.  If so, use this instead of the file contents (this
    -- is for use in an IDE where the file hasn't been saved by
    -- the user yet).
    --
    -- These fields are strict because Targets are long lived.
    data Target
      = Target {
          Target -> TargetId
    targetId           :: !TargetId, -- ^ module or filename
          Target -> Bool
    targetAllowObjCode :: !Bool,     -- ^ object code allowed?
          Target -> UnitId
    targetUnitId       :: !UnitId,   -- ^ id of the unit this target is part of
          Target -> Maybe (InputFileBuffer, UTCTime)
    targetContents     :: !(Maybe (InputFileBuffer, UTCTime))
          -- ^ Optional in-memory buffer containing the source code GHC should
          -- use for this target instead of reading it from disk.
          --
          -- Since GHC version 8.10 modules which require preprocessors such as
          -- Literate Haskell or CPP to run are also supported.
          --
          -- If a corresponding source file does not exist on disk this will
          -- result in a 'SourceError' exception if @targetId = TargetModule _@
          -- is used. However together with @targetId = TargetFile _@ GHC will
          -- not complain about the file missing.
        }

    data TargetId
      = TargetModule !ModuleName
            -- ^ A module name: search for the file
      | TargetFile !FilePath !(Maybe Phase)
            -- ^ A filename: preprocess & parse it to find the module name.
            -- If specified, the Phase indicates how to compile this file
            -- (which phase to start from).  Nothing indicates the starting phase
            -- should be determined from the suffix of the filename.
      deriving TargetId -> TargetId -> Bool
    (TargetId -> TargetId -> Bool)
    -> (TargetId -> TargetId -> Bool) -> Eq TargetId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TargetId -> TargetId -> Bool
    == :: TargetId -> TargetId -> Bool
    $c/= :: TargetId -> TargetId -> Bool
    /= :: TargetId -> TargetId -> Bool
    Eq

    type InputFileBuffer = StringBuffer

    pprTarget :: Target -> SDoc
    pprTarget :: Target -> SDoc
    pprTarget Target { targetUnitId :: Target -> UnitId
    targetUnitId = UnitId
    uid, targetId :: Target -> TargetId
    targetId = TargetId
    id, targetAllowObjCode :: Target -> Bool
    targetAllowObjCode = Bool
    obj } =
        (if Bool
    obj then SDoc
    forall doc. IsOutput doc => doc
    empty else Char -> SDoc
    forall doc. IsLine doc => Char -> doc
    char Char
    '*') SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitId
    uid SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    colon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> TargetId -> SDoc
    pprTargetId TargetId
    id

    instance Outputable Target where
        ppr :: Target -> SDoc
    ppr = Target -> SDoc
    pprTarget

    pprTargetId :: TargetId -> SDoc
    pprTargetId :: TargetId -> SDoc
    pprTargetId (TargetModule ModuleName
    m) = ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    m
    pprTargetId (TargetFile FilePath
    f Maybe Phase
    _) = FilePath -> SDoc
    forall doc. IsLine doc => FilePath -> doc
    text FilePath
    f

    instance Outputable TargetId where
        ppr :: TargetId -> SDoc
    ppr = TargetId -> SDoc
    pprTargetId