    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Distribution.Simple.GHC.ImplInfo
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- This module contains the data structure describing invocation
    -- details for a GHC or GHC-derived compiler, such as supported flags
    -- and workarounds for bugs.

    module Distribution.Simple.GHC.ImplInfo (
            GhcImplInfo(..), getImplInfo,
            ghcVersionImplInfo, ghcjsVersionImplInfo
            ) where

    import Prelude ()
    import Distribution.Compat.Prelude

    import Distribution.Simple.Compiler
    import Distribution.Version

    {- |
         Information about features and quirks of a GHC-based implementation.

         Compiler flavors based on GHC behave similarly enough that some of
         the support code for them is shared. Every implementation has its
         own peculiarities, that may or may not be a direct result of the
         underlying GHC version. This record keeps track of these differences.

         All shared code (i.e. everything not in the Distribution.Simple.FLAVOR
         module) should use implementation info rather than version numbers
         to test for supported features.
    -}

    data GhcImplInfo = GhcImplInfo
      { GhcImplInfo -> Bool
    supportsHaskell2010  :: Bool -- ^ -XHaskell2010 and -XHaskell98 flags
      , GhcImplInfo -> Bool
    supportsGHC2021      :: Bool -- ^ -XGHC2021 flag
      , GhcImplInfo -> Bool
    reportsNoExt         :: Bool -- ^ --supported-languages gives Ext and NoExt
      , GhcImplInfo -> Bool
    alwaysNondecIndent   :: Bool -- ^ NondecreasingIndentation is always on
      , GhcImplInfo -> Bool
    flagGhciScript       :: Bool -- ^ -ghci-script flag supported
      , GhcImplInfo -> Bool
    flagProfAuto         :: Bool -- ^ new style -fprof-auto* flags
      , GhcImplInfo -> Bool
    flagPackageConf      :: Bool -- ^ use package-conf instead of package-db
      , GhcImplInfo -> Bool
    flagDebugInfo        :: Bool -- ^ -g flag supported
      , GhcImplInfo -> Bool
    supportsDebugLevels  :: Bool -- ^ supports numeric @-g@ levels
      , GhcImplInfo -> Bool
    supportsPkgEnvFiles  :: Bool -- ^ picks up @.ghc.environment@ files
      , GhcImplInfo -> Bool
    flagWarnMissingHomeModules :: Bool -- ^ -Wmissing-home-modules is supported
      }

    getImplInfo :: Compiler -> GhcImplInfo
    getImplInfo :: Compiler -> GhcImplInfo
    getImplInfo Compiler
    comp =
      case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
        CompilerFlavor
    GHC   -> Version -> GhcImplInfo
    ghcVersionImplInfo (Compiler -> Version
    compilerVersion Compiler
    comp)
        CompilerFlavor
    GHCJS -> case CompilerFlavor -> Compiler -> Maybe Version
    compilerCompatVersion CompilerFlavor
    GHC Compiler
    comp of
                  Just Version
    ghcVer -> Version -> Version -> GhcImplInfo
    ghcjsVersionImplInfo (Compiler -> Version
    compilerVersion Compiler
    comp) Version
    ghcVer
                  Maybe Version
    _  -> [Char] -> GhcImplInfo
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Distribution.Simple.GHC.Props.getImplProps: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++
                               [Char]
    "could not find GHC version for GHCJS compiler")
        CompilerFlavor
    x     -> [Char] -> GhcImplInfo
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Distribution.Simple.GHC.Props.getImplProps only works" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++
                        [Char]
    "for GHC-like compilers (GHC, GHCJS)" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++
                        [Char]
    ", but found " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CompilerFlavor -> [Char]
    forall a. Show a => a -> [Char]
    show CompilerFlavor
    x)

    ghcVersionImplInfo :: Version -> GhcImplInfo
    ghcVersionImplInfo :: Version -> GhcImplInfo
    ghcVersionImplInfo Version
    ver = GhcImplInfo
      { supportsHaskell2010 :: Bool
    supportsHaskell2010  = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    7]
      , supportsGHC2021 :: Bool
    supportsGHC2021      = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    9,Int
    1]
      , reportsNoExt :: Bool
    reportsNoExt         = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    7]
      , alwaysNondecIndent :: Bool
    alwaysNondecIndent   = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    <  [Int
    7,Int
    1]
      , flagGhciScript :: Bool
    flagGhciScript       = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    7,Int
    2]
      , flagProfAuto :: Bool
    flagProfAuto         = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    7,Int
    4]
      , flagPackageConf :: Bool
    flagPackageConf      = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    <  [Int
    7,Int
    5]
      , flagDebugInfo :: Bool
    flagDebugInfo        = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    7,Int
    10]
      , supportsDebugLevels :: Bool
    supportsDebugLevels  = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    0]
      , supportsPkgEnvFiles :: Bool
    supportsPkgEnvFiles  = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    0,Int
    1,Int
    20160901] -- broken in 8.0.1, fixed in 8.0.2
      , flagWarnMissingHomeModules :: Bool
    flagWarnMissingHomeModules = [Int]
    v [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    2]
      }
      where
        v :: [Int]
    v = Version -> [Int]
    versionNumbers Version
    ver

    ghcjsVersionImplInfo :: Version  -- ^ The GHCJS version
                         -> Version  -- ^ The GHC version
                         -> GhcImplInfo
    ghcjsVersionImplInfo :: Version -> Version -> GhcImplInfo
    ghcjsVersionImplInfo Version
    _ghcjsver Version
    ghcver = GhcImplInfo
      { supportsHaskell2010 :: Bool
    supportsHaskell2010  = Bool
    True
      , supportsGHC2021 :: Bool
    supportsGHC2021      = Bool
    True
      , reportsNoExt :: Bool
    reportsNoExt         = Bool
    True
      , alwaysNondecIndent :: Bool
    alwaysNondecIndent   = Bool
    False
      , flagGhciScript :: Bool
    flagGhciScript       = Bool
    True
      , flagProfAuto :: Bool
    flagProfAuto         = Bool
    True
      , flagPackageConf :: Bool
    flagPackageConf      = Bool
    False
      , flagDebugInfo :: Bool
    flagDebugInfo        = Bool
    False
      , supportsDebugLevels :: Bool
    supportsDebugLevels  = [Int]
    ghcv [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    0]
      , supportsPkgEnvFiles :: Bool
    supportsPkgEnvFiles  = [Int]
    ghcv [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    0,Int
    2] --TODO: check this works in ghcjs
      , flagWarnMissingHomeModules :: Bool
    flagWarnMissingHomeModules = [Int]
    ghcv [Int] -> [Int] -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int
    8,Int
    2]
      }
      where
        ghcv :: [Int]
    ghcv = Version -> [Int]
    versionNumbers Version
    ghcver